Module 92: Architecture Patterns

Lesson 4 of 5 · 15–25 minutes

Clean architecture

🏠The everyday picture

A wall socket: any appliance with the right plug works, and the electricity company can change how it generates power without you changing your appliances. The socket is a fixed agreement between the two sides.

📘What it really is

// port (inside)
export interface PaymentGateway {
  createOrder(amountPaise: number, bookingId: string): Promise<{ orderId: string }>;
}

// use case (inside) depends only on ports
export class BookSession {
  private bookings: BookingRepository;
  private payments: PaymentGateway;
  constructor(bookings: BookingRepository, payments: PaymentGateway) {
    this.bookings = bookings;
    this.payments = payments;
  }
  async execute(input: BookSessionInput) { /* domain rules, then ports */ }
}

// adapter (outside) implements the port for a real provider
export class RazorpayGateway implements PaymentGateway { /* calls the provider's API */ }

🖱️Try it

Implement the BookSession use case for the booking platform with the clean structure: a Booking domain type with its rules, BookingRepository and PaymentGateway ports, a PostgreSQL adapter, and a fake payment adapter. Write unit tests for the use case using in-memory fakes, including "slot already booked" and "payment order creation fails".

✅Quick check

What's the dependency rule in clean architecture?

Show the answer

Code dependencies point inward: the business core doesn't depend on frameworks, databases or outside services.

What's a port?

Show the answer

An interface the core needs (such as a repository or payment gateway), implemented by an adapter for a specific technology.

← PreviousLayered architecture
ProLearners Assist