CodeGym /Blog Java /rawak /Corak reka bentuk: Kaedah kilang
John Squirrels
Tahap
San Francisco

Corak reka bentuk: Kaedah kilang

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan terus mengkaji corak reka bentuk dan kita akan membincangkan corak kaedah kilang. Corak reka bentuk: Kaedah kilang - 1 Anda akan mengetahui apakah itu dan tugas apa yang sesuai untuk corak ini. Kami akan mempertimbangkan corak reka bentuk ini dalam amalan dan mengkaji strukturnya. Untuk memastikan semuanya jelas, anda perlu memahami topik berikut:
  1. Warisan di Jawa.
  2. Kaedah dan kelas abstrak di Jawa

Apakah masalah yang diselesaikan oleh kaedah kilang?

Semua corak reka bentuk kilang mempunyai dua jenis peserta: pencipta (kilang itu sendiri) dan produk (objek yang dicipta oleh kilang). Bayangkan situasi berikut: kami mempunyai kilang yang mengeluarkan kereta berjenama CodeGym. Ia tahu cara mencipta model kereta dengan pelbagai jenis badan:
  • kereta sedan
  • gerabak stesen
  • coupe
Perniagaan kami berkembang pesat sehingga satu hari yang baik kami memperoleh pengeluar kereta lain — OneAuto. Sebagai pemilik perniagaan yang bijak, kami tidak mahu kehilangan mana-mana pelanggan OneAuto, oleh itu kami berhadapan dengan tugas untuk menstruktur semula pengeluaran supaya kami boleh menghasilkan:
  • kereta sedan CodeGym
  • gerabak stesen CodeGym
  • CodeGym coupes
  • kereta sedan OneAuto
  • Gerabak stesen OneAuto
  • OneAuto coupe
Seperti yang anda lihat, bukannya satu kumpulan produk, kami kini mempunyai dua, dan ia berbeza dalam butiran tertentu. Corak reka bentuk kaedah kilang adalah untuk apabila kita perlu mencipta kumpulan produk yang berbeza, yang setiap satunya mempunyai beberapa ciri khusus. Kami akan mempertimbangkan prinsip panduan corak ini dalam amalan, secara beransur-ansur bergerak dari yang mudah kepada yang kompleks, menggunakan contoh kedai kopi kami, yang kami buat dalam salah satu pelajaran sebelumnya .

Sedikit tentang corak kilang

Izinkan saya mengingatkan anda bahawa sebelum ini kami telah membina sebuah kedai kopi maya kecil. Dengan bantuan kilang yang ringkas, kami belajar cara mencipta pelbagai jenis kopi. Hari ini kita akan mengolah semula contoh ini. Mari kita ingat bagaimana rupa kedai kopi kami, dengan kilangnya yang ringkas. Kami mempunyai kelas kopi:

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Dan beberapa kelas kanak-kanak yang sepadan dengan jenis kopi tertentu yang boleh dihasilkan oleh kilang kami:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Kami mencipta enum untuk memudahkan anda membuat pesanan:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Kilang kopi itu sendiri kelihatan 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 akhirnya, kedai kopi itu sendiri kelihatan seperti ini:

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("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}

Memodenkan kilang yang ringkas

Kedai kopi kami berjalan dengan baik. Sehinggakan kami sedang mempertimbangkan untuk berkembang. Kami ingin membuka beberapa lokasi baharu. Kami berani dan berdaya usaha, jadi kami tidak akan membuka kedai kopi yang membosankan. Kami mahu setiap kedai mempunyai kelainan yang istimewa. Sehubungan itu, sebagai permulaan, kami akan membuka dua lokasi: satu Itali dan satu Amerika. Perubahan ini akan menjejaskan bukan sahaja reka bentuk dalaman, tetapi juga minuman yang ditawarkan:
  • di kedai kopi Itali, kami akan menggunakan jenama kopi Itali secara eksklusif, dengan pengisaran dan pemanggangan khas.
  • lokasi Amerika akan mempunyai bahagian yang lebih besar, dan kami akan menyediakan marshmallow dengan setiap pesanan.
Satu-satunya perkara yang kekal tidak berubah ialah model perniagaan kami, yang telah membuktikan dirinya cemerlang. Dari segi kod, inilah yang berlaku. Kami mempunyai 4 kelas yang sepadan dengan produk kami:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Tetapi sekarang kita akan mempunyai 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 {}
Memandangkan kami ingin mengekalkan model perniagaan semasa, kami mahu orderCoffee(CoffeeType type)kaedah itu mengalami sedikit perubahan yang mungkin. Lihatlah ia:

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

    System.out.println("Here's your coffee! Thanks! Come again!");
    return coffee;
}
Apakah pilihan yang kita ada? Nah, kita sudah tahu cara menulis kilang, bukan? Perkara paling mudah yang segera terlintas di fikiran ialah menulis dua kilang yang serupa, dan kemudian menyerahkan pelaksanaan yang dikehendaki kepada pembina kedai kopi kami. Dengan melakukan ini, kelas kedai kopi tidak akan berubah. Mula-mula, kita perlu mencipta kelas kilang baharu, menjadikannya mewarisi kilang ringkas kami, dan kemudian mengatasi createCoffee(CoffeeType type)kaedah tersebut. Mari kita tulis kilang untuk mencipta kopi gaya Itali dan kopi gaya 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;
    }

}
Kini kita boleh menghantar pelaksanaan kilang yang dikehendaki kepada CoffeeShop. Mari lihat rupa kod untuk memesan kopi dari kedai kopi yang berbeza. Contohnya, cappucino gaya Itali dan gaya Amerika:

public class Main {
    public static void main(String[] args) {
        /*
            Order an Italian-style cappuccino:
            1. Create a factory for making Italian coffee
            2. Create a new coffee shop, passing the Italian coffee factory to it through the constructor
            3. Order our coffee
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
        
        
         /*
            Order an American-style cappuccino
            1. Create a factory for making American coffee
            2. Create a new coffee shop, passing the American coffee factory to it through the constructor
            3. Order our coffee
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
Kami mencipta dua kedai kopi yang berbeza, memberikan kilang yang dikehendaki kepada setiap kedai. Di satu pihak, kami telah mencapai objektif kami, tetapi di sisi lain... Entah bagaimana ini tidak sesuai dengan usahawan... Mari kita fikirkan apa yang salah. Pertama, kelimpahan kilang. Apa? Sekarang untuk setiap lokasi baharu, kami sepatutnya mencipta kilangnya sendiri dan, sebagai tambahan kepada itu, pastikan kilang yang berkaitan diserahkan kepada pembina semasa membuat kedai kopi? Kedua, ia masih kilang yang ringkas. Baru dimodenkan sedikit. Tetapi kami di sini untuk mempelajari corak baharu. Ketiga, bukankah pendekatan yang berbeza mungkin? Alangkah baiknya jika kita boleh meletakkan semua isu yang berkaitan dengan penyediaan kopi ke dalamCoffeeShopkelas dengan menghubungkan proses mencipta kopi dan melayan pesanan, pada masa yang sama mengekalkan fleksibiliti yang mencukupi untuk membuat pelbagai gaya kopi. Jawapannya ya, kita boleh. Ini dipanggil corak reka bentuk kaedah kilang.

Dari kilang yang mudah kepada kaedah kilang

Untuk menyelesaikan tugasan secekap mungkin:
  1. Kami mengembalikan createCoffee(CoffeeType type)kaedah ke CoffeeShopkelas.
  2. Kami akan menjadikan kaedah ini abstrak.
  3. Kelas CoffeeShopitu sendiri akan menjadi abstrak.
  4. Kelas CoffeeShopakan mempunyai kelas kanak-kanak.
Ya kawan. Kedai kopi Itali tidak lebih daripada keturunan kelas CoffeeShop, yang melaksanakan createCoffee(CoffeeType type)kaedah mengikut tradisi terbaik barista Itali. Sekarang, satu langkah pada satu masa. Langkah 1. Jadikan Coffeekelas abstrak. Kami mempunyai dua keluarga keseluruhan produk yang berbeza. Namun, kopi Itali dan Amerika mempunyai nenek moyang yang sama - kelasnya Coffee. Adalah wajar untuk menjadikannya abstrak:

public abstract class Coffee {
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Langkah 2. Buat abstrak, dengan kaedah CoffeeShopabstrakcreateCoffee(CoffeeType type)

public abstract class CoffeeShop {

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

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

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
Langkah 3. Buat kedai kopi Itali, yang merupakan keturunan kedai kopi abstrak. Kami melaksanakan createCoffee(CoffeeType type)kaedah di dalamnya, dengan mengambil kira spesifik resipi Itali.

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. Kami melakukan perkara yang sama untuk kedai kopi gaya 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. Lihat bagaimana latte Amerika dan Itali akan kelihatan:

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);
    }
}
tahniah. Kami hanya melaksanakan corak reka bentuk kaedah kilang menggunakan kedai kopi kami sebagai contoh.

Prinsip di sebalik kaedah kilang

Sekarang mari kita pertimbangkan dengan lebih terperinci apa yang kita dapat. Rajah di bawah menunjukkan kelas yang terhasil. Blok hijau ialah kelas pencipta, dan blok biru ialah kelas produk. Corak reka bentuk: Kaedah kilang - 2Apakah kesimpulan yang boleh kita buat?
  1. Semua produk adalah pelaksanaan Coffeekelas abstrak.
  2. Semua pencipta adalah pelaksanaan CoffeeShopkelas abstrak.
  3. Kami melihat dua hierarki kelas selari:
    • Hierarki produk. Kami melihat keturunan Itali dan keturunan Amerika
    • Hierarki pencipta. Kami melihat keturunan Itali dan keturunan Amerika
  4. Superclass CoffeeShoptidak mempunyai maklumat tentang produk tertentu ( Coffee) yang akan dibuat.
  5. Kelas CoffeeShopsuper mewakilkan penciptaan produk tertentu kepada keturunannya.
  6. Setiap keturunan CoffeeShopkelas melaksanakan createCoffee()kaedah kilang mengikut ciri khususnya sendiri. Dengan kata lain, pelaksanaan kelas pengeluar menyediakan produk khusus berdasarkan spesifikasi kelas pengeluar.
Anda kini bersedia untuk definisi corak kaedah kilang . Corak kaedah kilang mentakrifkan antara muka untuk mencipta objek, tetapi membenarkan subkelas untuk memilih kelas objek yang dicipta. Oleh itu, kaedah kilang mewakilkan penciptaan contoh kepada subkelas. Secara umum, mengingati definisi tidak sepenting memahami cara semuanya berfungsi.

Struktur kaedah kilang

Corak reka bentuk: Kaedah kilang - 3Rajah di atas menunjukkan struktur umum corak kaedah kilang. Apa lagi yang penting di sini?
  1. Kelas Pencipta melaksanakan semua kaedah yang berinteraksi dengan produk, kecuali kaedah kilang.
  2. Kaedah abstrak factoryMethod()mesti dilaksanakan oleh semua keturunan kelas Creator.
  3. Kelas ConcreteCreatormelaksanakan factoryMethod()kaedah, yang secara langsung mencipta produk.
  4. Kelas ini bertanggungjawab untuk mencipta produk tertentu. Ini adalah satu-satunya kelas dengan maklumat tentang mencipta produk ini.
  5. Semua produk mesti melaksanakan antara muka biasa, iaitu mereka mestilah keturunan kelas produk biasa. Ini adalah perlu supaya kelas yang menggunakan produk boleh beroperasi pada mereka sebagai abstraksi, bukannya pelaksanaan khusus.

Kerja rumah

Hari ini kami telah melakukan banyak kerja dan mengkaji corak reka bentuk kaedah kilang. Sudah tiba masanya untuk mengukuhkan bahan! Latihan 1. Buat kerja membuka kedai kopi lain. Ia boleh menjadi kedai kopi gaya Inggeris atau Sepanyol. Atau pun gaya kapal angkasa. Tambahkan pewarna makanan pada kopi untuk menjadikannya bersinar, dan kopi anda akan hilang begitu saja! Latihan 2. Dalam pelajaran lepas , anda mempunyai latihan di mana anda mencipta bar sushi maya atau restoran pizza maya. Sekarang senaman anda adalah untuk tidak berdiri diam. Hari ini anda belajar cara menggunakan corak kaedah kilang untuk kelebihan anda. Sudah tiba masanya untuk menggunakan pengetahuan ini dan mengembangkan perniagaan anda sendiri ;)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION