<aside> 📚 📁 Category: Structural

</aside>

Overview

Facade pattern menyediakan simplified interface ke complex system dari classes, library, atau framework. Pattern ini membuat subsystem lebih mudah digunakan dengan menyembunyikan kompleksitas di balik interface yang lebih sederhana.

<aside> â„šī¸ Analogi: Seperti customer service representative di toko. Alih-alih menghadapi berbagai departemen (inventory, billing, shipping), Anda hanya perlu berbicara dengan satu orang yang menangani semua koordinasi internal.

</aside>

Problem

Ketika aplikasi Anda perlu bekerja dengan banyak objek dari sophisticated library atau framework, Anda harus menginisialisasi semua objek, melacak dependencies, mengeksekusi methods dalam urutan yang benar, dll. Business logic menjadi tightly coupled dengan implementation details dari third-party classes.

Solution

Buat facade class yang menyediakan simple interface ke complex subsystem. Facade mendelegasikan client requests ke objek-objek yang sesuai dalam subsystem dan menangani kompleksitas workflow.

Implementation (C#)

// Complex Subsystem Classes
public class VideoFile
{
    public string FileName { get; }
    public VideoFile(string fileName) => FileName = fileName;
}

public class AudioMixer
{
    public void Fix(VideoFile file)
    {
        Console.WriteLine($"AudioMixer: fixing audio in {file.FileName}");
    }
}

public class VideoCodec { }
public class MPEG4CompressionCodec : VideoCodec { }
public class OggCompressionCodec : VideoCodec { }

public class CodecFactory
{
    public static VideoCodec Extract(VideoFile file)
    {
        Console.WriteLine("CodecFactory: extracting codec");
        return new MPEG4CompressionCodec();
    }
}

public class BitrateReader
{
    public static string Read(VideoFile file, VideoCodec codec)
    {
        Console.WriteLine("BitrateReader: reading file");
        return "buffer data";
    }

    public static string Convert(string buffer, VideoCodec codec)
    {
        Console.WriteLine("BitrateReader: converting buffer");
        return "converted buffer";
    }
}

// Facade - Simplified Interface
public class VideoConverter
{
    public void Convert(string fileName, string format)
    {
        Console.WriteLine($"VideoConverter: conversion started for {fileName}");
        
        VideoFile file = new VideoFile(fileName);
        VideoCodec sourceCodec = CodecFactory.Extract(file);
        
        VideoCodec destinationCodec = format == "mp4" 
            ? new MPEG4CompressionCodec() 
            : new OggCompressionCodec();
        
        string buffer = BitrateReader.Read(file, sourceCodec);
        string result = BitrateReader.Convert(buffer, destinationCodec);
        
        new AudioMixer().Fix(file);
        
        Console.WriteLine("VideoConverter: conversion completed");
    }
}

// Client Code - Simple Usage
var converter = new VideoConverter();
converter.Convert("funny-cats-video.ogg", "mp4");

Implementation (Python)

# Complex Subsystem Classes
class VideoFile:
    def __init__(self, file_name: str):
        self.file_name = file_name

class AudioMixer:
    def fix(self, file: VideoFile) -> None:
        print(f"AudioMixer: fixing audio in {file.file_name}")

class VideoCodec:
    pass

class MPEG4CompressionCodec(VideoCodec):
    pass

class OggCompressionCodec(VideoCodec):
    pass

class CodecFactory:
    @staticmethod
    def extract(file: VideoFile) -> VideoCodec:
        print("CodecFactory: extracting codec")
        return MPEG4CompressionCodec()

class BitrateReader:
    @staticmethod
    def read(file: VideoFile, codec: VideoCodec) -> str:
        print("BitrateReader: reading file")
        return "buffer data"
    
    @staticmethod
    def convert(buffer: str, codec: VideoCodec) -> str:
        print("BitrateReader: converting buffer")
        return "converted buffer"

# Facade - Simplified Interface
class VideoConverter:
    def convert(self, file_name: str, format: str) -> None:
        print(f"VideoConverter: conversion started for {file_name}")
        
        file = VideoFile(file_name)
        source_codec = CodecFactory.extract(file)
        
        destination_codec = (MPEG4CompressionCodec() if format == "mp4" 
                            else OggCompressionCodec())
        
        buffer = BitrateReader.read(file, source_codec)
        result = BitrateReader.convert(buffer, destination_codec)
        
        AudioMixer().fix(file)
        
        print("VideoConverter: conversion completed")

# Client Code - Simple Usage
converter = VideoConverter()
converter.convert("funny-cats-video.ogg", "mp4")

Real-World Examples

Pros and Cons