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 bisa membuat object tanpa menentukan class persisnya. Ini berguna saat logika pembuatannya rumit 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 keluarga object yang saling terkait. Alih-alih menggunakan satu factory method, kamu memiliki antarmuka factory dengan beberapa method pembuatan:

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"; }
};

// Factory Abstrak
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 terkait bekerja bersama secara konsisten.

challenge icon

Tantangan

Mudah

Mari buat sistem Generator Dokumen 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 simple factory dan abstract factory.

    Pertama, buat fungsi simple factory 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 konstruktornya. 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 simple factory untuk membuat dokumen berdasarkan input. Cetak hasil pemanggilan generate() pada dokumen tersebut.

    Lalu cetak satu baris kosong.

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

Sebagai contoh, 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 bahwa simple factory membuat satu dokumen berdasarkan kedua parameter, sedangkan abstract factory memastikan semua dokumen yang dibuat oleh sebuah service memiliki format yang sama. Inilah manfaat utama Abstract Factory saat kamu membutuhkan keluarga 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 satu 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