Menu
CoddyTech

Factory dan Abstract Factory

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 92 dari 104.

Factory pattern mendelegasikan pembuatan object ke method atau class terpisah, sehingga kamu dapat membuat object tanpa menentukan class spesifiknya. Pola ini berguna saat logika pembuatannya kompleks atau saat kamu ingin memisahkan kode client dari implementasi konkret.

Factory sederhana menggunakan method yang mengembalikan berbagai tipe turunan berdasarkan input:

#include <iostream>
#include <memory>

class Button {
public:
    virtual void render() = 0;
    virtual ~Button() = default;
};

class WindowsButton : public Button {
public:
    void render() override { std::cout << "Windows button\n"; }
};

class MacButton : public Button {
public:
    void render() override { std::cout << "Mac button\n"; }
};

// Fungsi factory
std::unique_ptr<Button> createButton(const std::string& os) {
    if (os == "windows") return std::make_unique<WindowsButton>();
    if (os == "mac") return std::make_unique<MacButton>();
    return nullptr;
}

Abstract Factory melangkah lebih jauh dengan membuat kelompok object yang saling berkaitan. Alih-alih satu method factory, kamu memiliki antarmuka factory dengan beberapa method untuk membuat object:

class Checkbox {
public:
    virtual void check() = 0;
    virtual ~Checkbox() = default;
};

class WindowsCheckbox : public Checkbox {
public:
    void check() override { std::cout << "Windows checkbox\n"; }
};

class MacCheckbox : public Checkbox {
public:
    void check() override { std::cout << "Mac checkbox\n"; }
};

// Abstract Factory
class GUIFactory {
public:
    virtual std::unique_ptr<Button> createButton() = 0;
    virtual std::unique_ptr<Checkbox> createCheckbox() = 0;
    virtual ~GUIFactory() = default;
};

class WindowsFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<WindowsButton>();
    }
    std::unique_ptr<Checkbox> createCheckbox() override {
        return std::make_unique<WindowsCheckbox>();
    }
};

Gunakan Factory saat kamu membutuhkan pembuatan object yang fleksibel, dan Abstract Factory saat kamu perlu memastikan bahwa object yang saling terkait bekerja bersama secara konsisten.

challenge icon

Tantangan

Mudah

Mari kita buat sistem Document Generator menggunakan pola Factory dan Abstract Factory. Kamu akan membuat sistem yang dapat menghasilkan berbagai jenis dokumen (laporan dan faktur) dalam berbagai format output (PDF dan HTML), untuk menunjukkan bagaimana factory memisahkan pembuatan object dari kode client.

Kamu akan mengatur kodemu dalam empat file:

  • Document.h: Definisikan hierarki produk dokumenmu.

    Buat class dasar abstrak Document dengan method virtual murni generate() yang mengembalikan string berisi deskripsi dokumen yang dihasilkan, serta destructor virtual.

    Lalu buat empat class dokumen konkret:

    • PDFReport: generate() mengembalikan "Generating PDF Report"
    • HTMLReport: generate() mengembalikan "Generating HTML Report"
    • PDFInvoice: generate() mengembalikan "Generating PDF Invoice"
    • HTMLInvoice: generate() mengembalikan "Generating HTML Invoice"
  • DocumentFactory.h: Implementasikan fungsi factory sederhana dan abstract factory.

    Pertama, buat fungsi factory sederhana bernama createDocument yang menerima dua string: jenis dokumen ("report" atau "invoice") dan format ("pdf" atau "html"). Fungsi ini harus mengembalikan std::unique_ptr<Document> yang menunjuk ke dokumen konkret yang sesuai. Kembalikan nullptr untuk kombinasi yang tidak valid.

    Lalu buat class abstract factory bernama DocumentFactory dengan dua method virtual murni:

    • createReport(): mengembalikan std::unique_ptr<Document>
    • createInvoice(): mengembalikan std::unique_ptr<Document>

    Implementasikan dua factory konkret:

    • PDFFactory: membuat PDFReport dan PDFInvoice
    • HTMLFactory: membuat HTMLReport dan HTMLInvoice
  • DocumentService.h: Buat service yang menggunakan abstract factory.

    Definisikan class DocumentService yang menerima std::unique_ptr<DocumentFactory> di constructornya. Class ini harus memiliki method bernama generateAllDocuments() yang menggunakan factory untuk membuat laporan dan faktur, lalu mencetak hasil pemanggilan generate() pada masing-masing dokumen, satu per baris.

  • main.cpp: Tunjukkan kedua pendekatan factory.

    Baca dua input:

    1. Jenis dokumen (report atau invoice)
    2. Format (pdf atau html)

    Pertama, gunakan fungsi factory sederhana untuk membuat dokumen berdasarkan input. Cetak hasil pemanggilan generate() pada dokumen tersebut.

    Lalu cetak satu baris kosong.

    Selanjutnya, buat DocumentService dengan factory yang sesuai berdasarkan input format (gunakan PDFFactory untuk pdf, HTMLFactory untuk html). Panggil generateAllDocuments() untuk menunjukkan bagaimana abstract factory membuat kumpulan dokumen yang saling terkait.

Contohnya, dengan input report dan pdf:

Generating PDF Report

Generating PDF Report
Generating PDF Invoice

Dengan input invoice dan html:

Generating HTML Invoice

Generating HTML Report
Generating HTML Invoice

Perhatikan bagaimana factory sederhana membuat satu dokumen berdasarkan kedua parameter, sedangkan abstract factory memastikan bahwa semua dokumen yang dibuat oleh sebuah service memiliki format yang sama. Inilah manfaat utama Abstract Factory saat kamu membutuhkan kumpulan object terkait yang bekerja bersama secara konsisten.

Coba sendiri

#include <iostream>
#include <string>
#include <memory>
#include "Document.h"
#include "DocumentFactory.h"
#include "DocumentService.h"

using namespace std;

int main() {
    // Baca input
    string documentType;
    string format;
    cin >> documentType;
    cin >> format;
    
    // TODO: Gunakan fungsi simple factory untuk membuat dokumen
    // berdasarkan input documentType dan format
    // Cetak hasil pemanggilan generate() pada dokumen tersebut
    
    // Cetak baris kosong
    cout << endl;
    
    // TODO: Buat DocumentService dengan factory yang sesuai
    // berdasarkan input format (PDFFactory untuk "pdf", HTMLFactory untuk "html")
    // Panggil generateAllDocuments() untuk menunjukkan cara kerja abstract factory
    
    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online