CodeGym /Java Blog /Acak /Pola desain: Pabrik abstrak
John Squirrels
Level 41
San Francisco

Pola desain: Pabrik abstrak

Dipublikasikan di grup Acak
Hai! Hari ini kita akan melanjutkan mempelajari pola desain dan kita akan membahas pola pabrik abstrak . Pola desain: Pabrik abstrak - 1Inilah yang akan kita bahas dalam pelajaran:
  • Kita akan membahas apa itu pabrik abstrak dan masalah apa yang dipecahkan oleh pola ini
  • Kami akan membuat kerangka aplikasi lintas platform untuk memesan kopi melalui antarmuka pengguna
  • Kami akan mempelajari instruksi tentang cara menggunakan pola ini, termasuk melihat diagram dan kode
  • Dan sebagai bonus, pelajaran ini menyertakan telur Paskah tersembunyi yang akan membantu Anda mempelajari cara menggunakan Java untuk menentukan nama sistem operasi dan, bergantung pada hasilnya, untuk melakukan tindakan lain atau lainnya.
Untuk sepenuhnya memahami pola ini, Anda harus menguasai topik-topik berikut:
  • warisan di Jawa
  • kelas abstrak dan metode di Jawa

Masalah apa yang dipecahkan oleh pabrik abstrak?

Pabrik abstrak, seperti semua pola pabrik, membantu kita memastikan objek baru dibuat dengan benar. Kami menggunakannya untuk mengelola "produksi" berbagai keluarga objek yang saling berhubungan. Berbagai keluarga objek yang saling berhubungan... Apa artinya? Jangan khawatir: dalam praktiknya, semuanya lebih sederhana dari yang terlihat. Pertama-tama, apa yang bisa menjadi keluarga objek yang saling berhubungan? Misalkan kita sedang mengembangkan strategi militer yang melibatkan beberapa jenis unit:
  • infanteri
  • kavaleri
  • pemanah
Jenis unit ini saling berhubungan, karena mereka bertugas di pasukan yang sama. Kita dapat mengatakan bahwa kategori yang tercantum di atas adalah sekumpulan objek yang saling berhubungan. Kami memahami ini. Tetapi pola pabrik abstrak digunakan untuk mengatur penciptaan berbagai keluarga objek yang saling berhubungan. Tidak ada yang rumit di sini juga. Mari kita lanjutkan dengan contoh strategi militer. Secara umum, unit militer milik beberapa pihak yang bertikai. Bergantung pada pihak mana mereka berada, unit militer dapat sangat bervariasi dalam penampilan. Prajurit kaki, penunggang kuda, dan pemanah tentara Romawi tidak sama dengan prajurit kaki, penunggang kuda, dan pemanah Viking. Dalam strategi militer, prajurit dari pasukan yang berbeda adalah keluarga berbeda dari objek yang saling berhubungan. Akan lucu jika seorang programmer' Kesalahan itu menyebabkan seorang prajurit berseragam Prancis era Napoleon, senapan siap, ditemukan berjalan di antara barisan infanteri Romawi. Pola desain pabrik abstrak dibutuhkan secara tepat untuk menyelesaikan masalah ini. Bukan, bukan masalah rasa malu yang bisa datang dari perjalanan waktu, tapi masalah membuat berbagai kelompok objek yang saling berhubungan. Pabrik abstrak menyediakan antarmuka untuk membuat semua produk yang tersedia (kumpulan objek). Pabrik abstrak biasanya memiliki banyak implementasi. Masing-masing bertanggung jawab untuk membuat produk salah satu keluarga. Strategi militer kami akan mencakup pabrik abstrak yang menciptakan prajurit, pemanah, dan kavaleri abstrak, serta implementasi dari pabrik ini. Misalnya, pabrik yang menciptakan legiuner Romawi dan pabrik yang menciptakan tentara Kartago. Abstraksi adalah prinsip panduan yang paling penting dari pola ini. Klien pabrik bekerja dengan pabrik dan produknya hanya melalui antarmuka abstrak. Akibatnya, Anda tidak perlu memikirkan tentara mana yang sedang dibuat. Alih-alih, Anda menyerahkan tanggung jawab ini ke implementasi konkret dari pabrik abstrak.

Mari lanjutkan otomatisasi kedai kopi kita

Di pelajaran terakhir, kami mempelajari pola metode pabrik. Kami menggunakannya untuk memperluas bisnis kopi kami dan membuka beberapa lokasi baru. Hari ini kami akan terus memodernisasi bisnis kami. Menggunakan pola pabrik abstrak, kami akan meletakkan dasar untuk aplikasi desktop baru untuk memesan kopi secara online. Saat menulis aplikasi desktop, kita harus selalu memikirkan dukungan lintas platform. Aplikasi kami harus bekerja pada macOS dan Windows (spoiler: Dukungan untuk Linux diserahkan kepada Anda untuk diterapkan sebagai pekerjaan rumah). Seperti apa tampilan aplikasi kita? Cukup sederhana: ini akan menjadi formulir yang terdiri dari bidang teks, bidang pemilihan, dan tombol. Jika Anda memiliki pengalaman menggunakan sistem operasi yang berbeda, Anda pasti memperhatikan bahwa tombol di Windows dirender secara berbeda dari pada Mac. Seperti yang lainnya... Baiklah, mari kita mulai.
  • tombol
  • bidang teks
  • bidang pilihan
Penafian: Di setiap antarmuka, kita dapat menentukan metode seperti onClick, onValueChanged, atau onInputChanged. Dengan kata lain, kita dapat menentukan metode yang memungkinkan kita menangani berbagai peristiwa (menekan tombol, memasukkan teks, memilih nilai dalam kotak pilihan). Semua ini sengaja dihilangkan di sini agar tidak membebani contoh dan membuatnya lebih jelas saat kita mempelajari pola pabrik. Mari kita definisikan antarmuka abstrak untuk produk kita:

public interface Button {}
public interface Select {}
public interface TextField {}
Untuk setiap sistem operasi, kita harus membuat elemen antarmuka dengan gaya sistem operasi. Kami akan menulis kode untuk Windows dan MacOS. Mari buat implementasi untuk Windows:

public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
Sekarang kami melakukan hal yang sama untuk MacOS:

public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
Bagus sekali. Sekarang kita dapat melanjutkan ke pabrik abstrak kita, yang akan membuat semua jenis produk abstrak yang tersedia:

public interface GUIFactory {

    Button createButton();
    TextField createTextField();
    Select createSelect();

}
Hebat. Seperti yang Anda lihat, kami belum melakukan sesuatu yang rumit. Segala sesuatu yang mengikuti juga sederhana. Dengan analogi dengan produk, kami membuat berbagai implementasi pabrik untuk setiap OS. Mari kita mulai dengan Windows:

public class WindowsGUIFactory implements GUIFactory {
    public WindowsGUIFactory() {
        System.out.println("Creating GUIFactory for Windows OS");
    }

    public Button createButton() {
        System.out.println("Creating Button for Windows OS");
        return new WindowsButton();
    }

    public TextField createTextField() {
        System.out.println("Creating TextField for Windows OS");
        return new WindowsTextField();
    }

    public Select createSelect() {
        System.out.println("Creating Select for Windows OS");
        return new WindowsSelect();
    }
}
Kami telah menambahkan beberapa keluaran konsol di dalam metode dan konstruktor untuk mengilustrasikan lebih lanjut apa yang terjadi. Sekarang untuk macOS:

public class MacGUIFactory implements GUIFactory {
    public MacGUIFactory() {
        System.out.println("Creating GUIFactory for macOS");
    }

    @Override
    public Button createButton() {
        System.out.println("Creating Button for macOS");
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        System.out.println("Creating TextField for macOS");
        return new MacTextField();
    }

    @Override
    public Select createSelect() {
        System.out.println("Creating Select for macOS");
        return new MacSelect();
    }
}
Perhatikan bahwa setiap tanda tangan metode menunjukkan bahwa metode mengembalikan tipe abstrak. Namun di dalam metode, kami membuat implementasi spesifik dari produk. Ini adalah satu-satunya tempat kami mengontrol pembuatan instance tertentu. Sekarang saatnya menulis kelas untuk formulir. Ini adalah kelas Java yang bidangnya adalah elemen antarmuka:

public class CoffeeOrderForm {
    private final TextField customerNameTextField;
    private final Select coffeeTypeSelect;
    private final Button orderButton;

    public CoffeeOrderForm(GUIFactory factory) {
        System.out.println("Creating coffee order form");
        customerNameTextField = factory.createTextField();
        coffeeTypeSelect = factory.createSelect();
        orderButton = factory.createButton();
    }
}
Pabrik abstrak yang membuat elemen antarmuka diteruskan ke konstruktor formulir. Kami akan meneruskan implementasi pabrik yang diperlukan ke konstruktor untuk membuat elemen antarmuka untuk OS tertentu.

public class Application {
    private CoffeeOrderForm coffeeOrderForm;

    public void drawCoffeeOrderForm() {
        // Determine the name of the operating system through System.getProperty()
        String osName = System.getProperty("os.name").toLowerCase();
        GUIFactory guiFactory;

        if (osName.startsWith("win")) { // For Windows
            guiFactory = new WindowsGUIFactory();
        } else if (osName.startsWith("mac")) { // For Mac
            guiFactory = new MacGUIFactory();
        } else {
            System.out.println("Unknown OS. Unable to draw form :(");
            return;
        }
        coffeeOrderForm = new CoffeeOrderForm(guiFactory);
    }

    public static void main(String[] args) {
        Application application = new Application();
        application.drawCoffeeOrderForm();
    }
}
Jika kami menjalankan aplikasi di Windows, kami mendapatkan output berikut:

Creating GUIFactory for Windows OS
Creating coffee order form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
Di Mac, hasilnya adalah sebagai berikut:

Creating GUIFactory for macOS
Creating coffee order form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
Di Linux:

Unknown OS. Unable to draw form :( 
Dan sekarang kami meringkas. Kami menulis kerangka aplikasi berbasis GUI di mana elemen antarmuka dibuat khusus untuk OS yang relevan. Kami akan secara ringkas mengulangi apa yang telah kami buat:
  • Keluarga produk yang terdiri dari bidang input, bidang pilihan, dan tombol.
  • Implementasi yang berbeda dari rangkaian produk untuk Windows dan macOS.
  • Pabrik abstrak yang mendefinisikan antarmuka untuk membuat produk kami.
  • Dua implementasi dari pabrik kami, masing-masing bertanggung jawab untuk menciptakan rangkaian produk tertentu.
  • Formulir (kelas Java) yang bidangnya adalah elemen antarmuka abstrak yang diinisialisasi dengan nilai yang diperlukan dalam konstruktor menggunakan pabrik abstrak.
  • Kelas aplikasi Di dalam kelas ini, kami membuat formulir, meneruskan implementasi pabrik yang diinginkan ke konstruktornya.
Hasilnya adalah kami menerapkan pola pabrik abstrak.

Pabrik abstrak: cara menggunakan

Pabrik abstrak adalah pola desain untuk mengelola penciptaan berbagai keluarga produk tanpa terikat pada kelas produk konkret. Saat menggunakan pola ini, Anda harus:
  1. Tentukan keluarga produk. Misalkan kita memiliki dua di antaranya:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. Untuk setiap produk dalam keluarga, tentukan kelas abstrak (antarmuka). Dalam kasus kami, kami memiliki:
    • ProductA
    • ProductB
  3. Dalam setiap keluarga produk, setiap produk harus mengimplementasikan antarmuka yang ditentukan pada langkah 2.
  4. Buat pabrik abstrak, dengan metode untuk membuat setiap produk yang ditentukan pada langkah 2. Dalam kasus kita, metode ini adalah:
    • ProductA createProductA();
    • ProductB createProductB();
  5. Buat implementasi pabrik abstrak sehingga setiap implementasi mengontrol pembuatan produk dari satu keluarga. Untuk melakukan ini, di dalam setiap implementasi pabrik abstrak, Anda perlu mengimplementasikan semua metode kreasi sehingga mereka membuat dan mengembalikan implementasi produk tertentu.
Diagram UML berikut mengilustrasikan instruksi yang diuraikan di atas: Pola desain: Pabrik abstrak - 3Sekarang kita akan menulis kode sesuai dengan instruksi ini:

    // Define common product interfaces
    public interface ProductA {}
    public interface ProductB {}

    // Create various implementations (families) of our products
    public class SpecificProductA1 implements ProductA {}
    public class SpecificProductB1 implements ProductB {}

    public class SpecificProductA2 implements ProductA {}
    public class SpecificProductB2 implements ProductB {}

    // Create an abstract factory
    public interface AbstractFactory {
        ProductA createProductA();
        ProductB createProductB();
    }

    // Implement the abstract factory in order to create products in family 1
    public class SpecificFactory1 implements AbstractFactory {

        @Override
        public ProductA createProductA() {
            return new SpecificProductA1();
        }

        @Override
        public ProductB createProductB() {
            return new SpecificProductB1();
        }
    }

    // Implement the abstract factory in order to create products in family 2
    public class SpecificFactory2 implements AbstractFactory {

        @Override
        public ProductA createProductA() {
            return new SpecificProductA2();
        }

        @Override
        public ProductB createProductB() {
            return new SpecificProductB2();
        }
    }

Pekerjaan rumah

Untuk memperkuat materi, Anda dapat melakukan 2 hal:
  1. Sempurnakan aplikasi pemesanan kopi agar juga berfungsi di Linux.
  2. Buat pabrik abstrak Anda sendiri untuk memproduksi unit yang terlibat dalam strategi militer apa pun. Ini bisa berupa strategi militer historis yang melibatkan pasukan sungguhan, atau fantasi dengan orc, gnome, dan elf. Yang penting adalah memilih sesuatu yang menarik minat Anda. Jadilah kreatif, cetak pesan di konsol, dan nikmati belajar tentang pola!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION