Facade Pattern — Design Patterns

Facade menyediakan antarmuka sederhana di atas subsystem yang kompleks. Client cukup panggil satu method, dibalik layar ada banyak step. Problem yang…

Facade menyediakan antarmuka sederhana di atas subsystem yang kompleks. Client cukup panggil satu method, dibalik layar ada banyak step.

Problem yang diselesaikan:

Library besar sering punya banyak class dengan detail low-level. Kalau tiap client harus tahu semua orkestrasi, tiap tempat jadi copy-paste ritual yang sama. Facade sembunyikan kompleksitas di balik API yang ringkas, sesuai 80% use case.

Implementasi minimal — facade untuk setup upload file ke S3 dengan preview + resize:

// Subsystem complex (banyak kelas kecil)
class FileValidator {
  validate(file) {
    if (file.size > 5_000_000) throw new Error("Max 5MB");
    if (!["image/jpeg", "image/png"].includes(file.type)) throw new Error("Only JPEG/PNG");
  }
}

class ImageResizer {
  async resize(file, maxWidth) {
    // ...canvas manipulation, return Blob
  }
}

class S3Uploader {
  constructor(config) { this.config = config; }
  async upload(blob, key) {
    // ...presigned URL, multipart, etc
  }
}

class ThumbnailGenerator {
  async generate(file) {
    // ...
  }
}

// Facade — satu class yang orkestrasi
class MediaUploadService {
  constructor(s3Config) {
    this.validator = new FileValidator();
    this.resizer = new ImageResizer();
    this.uploader = new S3Uploader(s3Config);
    this.thumbnailer = new ThumbnailGenerator();
  }

  async uploadImage(file, userId) {
    this.validator.validate(file);
    const resized = await this.resizer.resize(file, 1600);
    const thumb = await this.thumbnailer.generate(file);
    const key = `users/${userId}/${Date.now()}-${file.name}`;
    const [fullUrl, thumbUrl] = await Promise.all([
      this.uploader.upload(resized, key),
      this.uploader.upload(thumb, key + "-thumb"),
    ]);
    return { fullUrl, thumbUrl };
  }
}

// Client cukup:
const media = new MediaUploadService(s3Config);
const { fullUrl, thumbUrl } = await media.uploadImage(file, user.id);

Kompleksitas validasi, resize, thumbnail, upload paralel — semua tersembunyi di satu call.

Dunia nyata di ekosistem JS/Laravel:

Facade ≠ God class.

Facade yang sehat hanya orkestrasi, tidak berisi logic. Detail tetap di kelas-kelas subsystem. Kalau facade mulai tumbuh besar dan isi business rule, itu sign harus dipecah (lihat anti-pattern "God Object").

Facade vs Adapter:

Kapan pakai:

Kapan JANGAN pakai:

Trade-off:

Facade sangat bermanfaat untuk API ergonomics dan encapsulation subsystem. Risiko: bisa jadi bottleneck (semua jalur lewat sini) atau membengkak jadi god class. Jaga facade tetap tipis dan fokus pada orkestrasi.

Yang akan kamu pelajari