Theme

Accent color

Gray color

Appearance

Radius

Scaling

Panel background

Ikhtisar Clean Architecture

Fondasi pengembangan aplikasi yang scalable, mudah dirawat, dan mudah diintegrasikan dengan berbagai teknologi.

ComponentsUI, Controller, Presenter, AdapterCore (Application)Entity, Use Case, ServiceInfrastructureInfra Adapters, DB, APIClean Architecture Diagram

Prinsip

  • Separation of concerns: Pisahkan logika bisnis, presentasi, dan data.
  • Dependency inversion: Layer atas tidak bergantung pada detail layer bawah.
  • Testability: Setiap bagian mudah di-test secara terpisah.
  • Independence: Framework, UI, dan database bisa diganti tanpa mengubah domain.

Lapisan

  • Core (Application): Core (Application): Berisi business logic murni, entity, value object, dan use case. Tidak bergantung pada framework atau library eksternal.
  • Infrastructure (Infra Adapters): Infrastructure (Infra Adapters): Detail teknis seperti database, framework, third-party service. Implementasi adapter dan komunikasi eksternal.
  • Components: Components: UI Components, controller, presenter, dan adapter untuk interaksi user. Semua komponen UI diletakkan di direktori components agar mudah integrasi dengan library lain seperti shadcn.

Port & Adapter

  • Port: Repository Port
    Adapter: Repository Adapter (misal: Prisma, MongoDB, REST API)
    Dependency: Core → Port → Infra Adapter → Infrastructure
  • Port: Controller Port
    Adapter: Controller Adapter (misal: Next.js API Route, Express)
    Dependency: Components → Adapter → Infrastructure

Contoh Struktur Project

src/
├── core/                  // Entity, Value Object, Use Case, Service
├── infrastructure/        // Infra Adapters, DB, API, External Service
├── components/            // UI Components (Next.js, React, shadcn, dsb)
├── types/                 // Shared Types
└── ...                    // File lain sesuai kebutuhan

Interface & Dependency Injection

Untuk menghubungkan interface dari domain ke infrastructure, gunakan dependency injection (IoC container). Domain hanya mendefinisikan interface (misal UserRepository), sedangkan implementasi detail (misal PrismaUserRepository) ada di infrastructure.

  • Domain: Mendefinisikan interface/abstraction.
  • Infrastructure: Mengimplementasikan interface tersebut.
  • IoC Container: Melakukan binding antara interface dan implementasi saat aplikasi berjalan.

Contoh binding dengan inversify:

// core/user/UserRepository.ts
export interface UserRepository {
  findById(id: string): Promise<User>;
}

// infrastructure/user/PrismaUserRepository.ts
import { injectable } from "inversify";
import { UserRepository } from "../../core/user/UserRepository";
@injectable()
export class PrismaUserRepository implements UserRepository {
  // implementasi detail
}

// infrastructure/ioc/container.ts
import "reflect-metadata";
import { Container } from "inversify";
import { UserRepository } from "../../core/user/UserRepository";
import { PrismaUserRepository } from "../user/PrismaUserRepository";

const TYPES = {
  UserRepository: Symbol.for("UserRepository"),
};

const container = new Container();
container.bind<UserRepository>(TYPES.UserRepository).to(PrismaUserRepository);

export { container, TYPES };

Dengan cara ini, domain tetap terpisah dari detail teknis, dan aplikasi mudah di-maintain serta di-test.