JavaRush /Java Blog /Random-ID /Pola Desain: Metode Pabrik

Pola Desain: Metode Pabrik

Dipublikasikan di grup Random-ID
Halo! Hari ini kita akan terus mempelajari pola desain dan membicarakan metode pabrik (FactoryMethod). Pola Desain: Metode Pabrik - 1Anda akan mengetahui apa itu dan tugas apa yang cocok untuk template ini. Kita akan melihat pola desain ini dalam praktiknya dan mengeksplorasi strukturnya. Untuk memperjelas semua hal di atas, Anda perlu memahami topik berikut:
  1. Warisan di Jawa.
  2. Metode dan kelas abstrak di Java.

Masalah apa yang dipecahkan oleh metode pabrik?

Dalam semua pola desain pabrik, ada dua kelompok peserta – pencipta (pabrik itu sendiri) dan produk (objek yang dibuat oleh pabrik). Bayangkan situasinya: kita memiliki pabrik yang memproduksi mobil dengan merek AutoRush. Dia tahu cara membuat model mobil dengan tipe bodi berbeda:
  • sedan
  • station wagon
  • mobil tertutup berpintu dua
Segalanya berjalan sangat baik bagi kami sehingga suatu hari kami menyerap perhatian OneAuto. Sebagai manajer yang bijaksana, kami tidak ingin kehilangan pelanggan OneAuto, dan tugas kami adalah merestrukturisasi produksi sedemikian rupa sehingga kami dapat menghasilkan:
  • Sedan AutoRush
  • Gerobak stasiun AutoRush
  • coupe AutoRush
  • Sedan OneAuto
  • Gerobak stasiun OneAuto
  • coupe OneAuto
Seperti yang Anda lihat, alih-alih satu kelompok produk turunan, muncul dua kelompok, yang berbeda dalam beberapa detail. Pola desain metode pabrik memecahkan masalah pembuatan kelompok produk yang berbeda, yang masing-masing memiliki kekhususan tertentu. Kami akan mempertimbangkan prinsip templat ini dalam praktiknya, secara bertahap beralih dari yang sederhana ke yang rumit, menggunakan contoh kedai kopi kami, yang kami buat di salah satu kuliah sebelumnya .

Sedikit tentang template pabrik

Izinkan saya mengingatkan Anda: kami membangun kedai kopi virtual kecil bersama Anda. Di dalamnya, kami belajar cara membuat berbagai jenis kopi dengan menggunakan pabrik sederhana. Hari ini kita akan menyempurnakan contoh ini. Mari kita ingat seperti apa kedai kopi kita yang pabriknya sederhana. Kami mengadakan kelas kopi:

public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
Dan juga beberapa ahli warisnya - jenis kopi tertentu yang dapat diproduksi oleh pabrik kami:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Untuk kenyamanan menerima pesanan, kami telah memperkenalkan transfer:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Pabrik kopinya sendiri terlihat seperti ini:

public class SimpleCoffeeFactory {
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }
        
        return coffee;
    }
}
Dan terakhir, kedai kopi itu sendiri:

public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}

Modernisasi pabrik sederhana

Kedai kopi kami berjalan dengan baik. Sedemikian rupa sehingga kami berpikir untuk memperluas. Kami ingin membuka beberapa poin baru. Sebagai orang yang giat, kami tidak akan membuat kedai kopi yang monoton. Saya ingin masing-masing memiliki twistnya sendiri. Oleh karena itu, untuk memulainya, kami akan membuka dua poin: dalam gaya Italia dan Amerika. Perubahan tersebut tidak hanya mempengaruhi interior, tetapi juga minuman:
  • di kedai kopi Italia kami akan menggunakan merek kopi eksklusif Italia, dengan penggilingan dan pemanggangan khusus.
  • Porsi Amerika akan sedikit lebih besar, dan setiap pesanan kami akan menyajikan marshmallow leleh - marshmallow.
Satu-satunya hal yang tidak berubah adalah model bisnis kami, yang telah terbukti dengan baik. Jika kita berbicara dalam bahasa kode, inilah yang terjadi. Kami memiliki 4 kelas produk:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Dan itu menjadi 8:

public class ItalianStyleAmericano extends Coffee {}
public class ItalianStyleCappucino extends Coffee {}
public class ItalianStyleCaffeLatte extends Coffee {}
public class ItalianStyleEspresso extends Coffee {}

public class AmericanStyleAmericano extends Coffee {}
public class AmericanStyleCappucino extends Coffee {}
public class AmericanStyleCaffeLatte extends Coffee {}
public class AmericanStyleEspresso extends Coffee {}
Karena kami ingin model bisnis saat ini tidak berubah, kami ingin metode ini orderCoffee(CoffeeType type)mengalami sedikit perubahan. Mari kita lihat:

public Coffee orderCoffee(CoffeeType type) {
    Coffee coffee = coffeeFactory.createCoffee(type);
    coffee.grindCoffee();
    coffee.makeCoffee();
    coffee.pourIntoCup();

    System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
    return coffee;
}
Pilihan apa yang kita punya? Kita sudah tahu cara menulis pabrik kan? Hal paling sederhana yang langsung terlintas dalam pikiran adalah menulis dua pabrik serupa, dan kemudian meneruskan implementasi yang diperlukan ke kedai kopi kita di konstruktor. Maka kelas kedai kopi tersebut tidak akan berubah. Pertama, kita perlu membuat kelas pabrik baru, mewarisi dari pabrik sederhana kita dan mengganti kelas createCoffee (CoffeeType type). Mari kita tulis pabrik untuk membuat kopi dengan gaya Italia dan Amerika:

public class SimpleItalianCoffeeFactory extends SimpleCoffeeFactory {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}

public class SimpleAmericanCoffeeFactory extends SimpleCoffeeFactory{

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }

}
Sekarang kita dapat meneruskan implementasi pabrik yang diperlukan ke CoffeeShop. Mari kita lihat seperti apa kode untuk memesan kopi dari kedai kopi yang berbeda. Misalnya, cappuccino gaya Italia dan Amerika:

public class Main {
    public static void main(String[] args) {
        /*
            Закажем капучино в итальянском стиле:
            1. Создадим фабрику для приготовления итальянского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику итальянского кофе
            3. Закажем наш кофе
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
        
        
         /*
            Закажем капучино в американском стиле
            1. Создадим фабрику для приготовления американского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику американского кофе
            3. Закажем наш кофе
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
Kami membuat dua kedai kopi berbeda, memindahkan masing-masing ke pabrik yang dibutuhkan. Di satu sisi, kami telah mencapai tujuan kami, tetapi di sisi lain... Ada sesuatu yang menggores jiwa pengusaha yang tak tertahankan... Mari kita cari tahu apa yang salah. Pertama, banyaknya pabrik. Apakah mungkin untuk membuat pabrik Anda sendiri setiap saat untuk titik baru dan, sebagai tambahan, memastikan bahwa saat membuat kedai kopi, pabrik yang diperlukan dipindahkan ke konstruktor? Kedua, masih berupa pabrik sederhana. Hanya sedikit dimodernisasi. Kami masih mempelajari pola baru di sini. Ketiga, apakah mungkin untuk melakukannya secara berbeda? Akan sangat bagus jika kita dapat melokalisasi semua pertanyaan tentang membuat kopi di dalam kelas CoffeeShop, menghubungkan proses pembuatan kopi dan melayani pesanan, namun pada saat yang sama menjaga fleksibilitas yang cukup untuk membuat kopi dengan gaya yang berbeda. Jawabannya adalah ya, Anda bisa. Ini disebut pola desain metode pabrik.

Dari metode pabrik sederhana hingga metode pabrik

Untuk memecahkan masalah seefisien mungkin, kami:
  1. Mari kita kembalikan metodenya createCoffee(CoffeeType type)ke kelas CoffeeShop.
  2. Mari kita jadikan metode ini abstrak.
  3. Kelas itu sendiri CoffeeShopakan menjadi abstrak.
  4. Kelas tersebut CoffeeShopakan mempunyai ahli waris.
Ya teman. Sebuah kedai kopi Italia tidak lebih dari pewaris kelas CoffeeShopyang menerapkan metode createCoffee(CoffeeType type)sesuai dengan tradisi terbaik barista Italia. Jadi, secara berurutan. Langkah 1. Mari kita membuat kelas menjadi Coffeeabstrak. Kami sekarang memiliki dua keluarga produk yang berbeda. Minuman kopi Italia dan Amerika masih memiliki nenek moyang yang sama: Coffee. Akan benar jika menjadikannya abstrak:

public abstract class Coffee {
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
Langkah 2. Jadikan CoffeeShopabstrak, dengan metode abstrakcreateCoffee(CoffeeType type)

public abstract class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = createCoffee(type);

        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
Langkah 3. Buat kedai kopi Italia, kelas turunan dari kedai kopi abstrak. Di dalamnya kami menerapkan metode createCoffee(CoffeeType type)dengan mempertimbangkan spesifikasi Italia.

public class ItalianCoffeeShop extends CoffeeShop {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}
Langkah 4. Mari kita lakukan hal yang sama untuk kedai kopi bergaya Amerika.

public class AmericanCoffeeShop extends CoffeeShop {
    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }
}
Langkah 5. Mari kita lihat seperti apa bentuk pemesanan latte ala Amerika dan Italia:

public class Main {
    public static void main(String[] args) {
        CoffeeShop italianCoffeeShop = new ItalianCoffeeShop();
        italianCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);

        CoffeeShop americanCoffeeShop = new AmericanCoffeeShop();
        americanCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);
    }
}
Selamat. Kami baru saja menerapkan pola desain metode pabrik di kedai kopi kami.

Cara kerja metode pabrik

Sekarang mari kita lihat lebih dekat apa yang kita dapatkan. Diagram di bawah menunjukkan kelas yang dihasilkan. Blok hijau adalah kelas pencipta, blok biru adalah kelas produk. Pola Desain: Metode Pabrik - 2Kesimpulan apa yang bisa diambil?
  1. Semua produk merupakan implementasi dari kelas abstrak Coffee.
  2. Semua pencipta adalah implementasi dari kelas abstrak CoffeeShop.
  3. Kami mengamati dua hierarki kelas paralel:
    • Hirarki produk. Kita melihat keturunan Italia dan keturunan Amerika
    • Hirarki pencipta. Kita melihat keturunan Italia dan keturunan Amerika
  4. Superclass CoffeeShoptidak memiliki informasi tentang implementasi produk spesifik mana ( Coffee) yang akan dibuat.
  5. Superclass CoffeeShopmendelegasikan pembuatan produk tertentu kepada turunannya.
  6. Setiap kelas turunan CoffeeShopmengimplementasikan metode pabrik createCoffee()sesuai dengan spesifikasinya. Dengan kata lain, dalam implementasi kelas pencipta, keputusan dibuat untuk menyiapkan produk tertentu berdasarkan spesifikasi kelas pencipta.
Sekarang Anda siap untuk menentukan pola metode pabrik . Pola metode pabrik mendefinisikan antarmuka untuk membuat objek, tetapi memungkinkan subkelas memilih kelas instance yang akan dibuat. Dengan demikian, metode Pabrik mendelegasikan operasi instantiasi ke subkelas. Secara umum, mengingat definisinya tidak sepenting memahami cara kerja sesuatu.

Struktur metode pabrik

Pola Desain: Metode Pabrik - 3Diagram di atas menunjukkan struktur umum pola metode pabrik. Apa lagi yang penting di sini?
  1. Kelas Creator berisi implementasi semua metode yang berinteraksi dengan produk, kecuali metode pabrik.
  2. Metode abstrak factoryMethod()harus diimplementasikan oleh semua turunan kelas Creator.
  3. Kelas ConcreteCreatormengimplementasikan metode factoryMethod()yang secara langsung menghasilkan suatu produk.
  4. Kelas ini bertanggung jawab untuk menciptakan produk tertentu. Ini adalah satu-satunya kelas yang memiliki informasi tentang pembuatan produk ini.
  5. Semua produk harus mengimplementasikan antarmuka yang sama - menjadi turunan dari kelas produk yang sama. Hal ini diperlukan agar kelas yang menggunakan produk dapat mengoperasikannya pada tingkat abstraksi daripada implementasi konkrit.

Pekerjaan rumah

Jadi, hari ini kami melakukan cukup banyak pekerjaan dan mempelajari pola desain metode pabrik. Saatnya untuk mengkonsolidasikan materi yang telah Anda bahas! Tugas 1. Bekerja untuk membuka kedai kopi lain. Itu bisa dibuat dalam gaya Inggris atau Spanyol. Atau bahkan bergaya pesawat luar angkasa. Mari tambahkan pewarna makanan pada kopi agar mengkilat, dan secara umum, kopi hanya akan menjadi ruang! Tugas 2. Pada kuliah terakhir, Anda mendapat tugas membuat bar sushi virtual atau restoran pizza virtual. Tugas Anda bukanlah tinggal diam. Hari ini Anda mempelajari bagaimana Anda dapat menggunakan pola metode pabrik untuk mencapai kesuksesan. Saatnya memanfaatkan pengetahuan ini dan mengembangkan bisnis Anda sendiri ;)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION