hello! Hari ini kita akan terus mengkaji corak reka bentuk dan bercakap tentang Kaedah Kilang. Anda akan mengetahui apa itu dan apa tugas templat ini sesuai untuknya. Kami akan melihat corak reka bentuk ini secara praktikal dan meneroka strukturnya. Untuk membuat semua perkara di atas jelas kepada anda, anda perlu memahami topik berikut:
- Warisan di Jawa.
- Kaedah dan kelas abstrak di Jawa.
Apakah masalah yang diselesaikan oleh kaedah kilang?
Dalam semua corak reka bentuk kilang, terdapat dua kumpulan peserta - pencipta (kilang itu sendiri) dan produk (objek yang dicipta oleh kilang). Bayangkan keadaannya: kami mempunyai kilang yang mengeluarkan kereta di bawah jenama AutoRush. Dia tahu cara mencipta model kereta dengan pelbagai jenis badan:- kereta sedan
- gerabak stesen
- coupe
- kereta sedan AutoRush
- Kereta stesen AutoRush
- coupe AutoRush
- kereta sedan OneAuto
- Gerabak stesen OneAuto
- coupe OneAuto
Sedikit tentang templat kilang
Biar saya ingatkan anda: kami membina kedai kopi maya kecil dengan anda. Di dalamnya, kami belajar cara mencipta pelbagai jenis kopi menggunakan kilang yang ringkas. Hari ini kita akan memperhalusi contoh ini. Mari kita ingat bagaimana rupa kedai kopi kita dengan kilang yang ringkas. Kami mempunyai kelas kopi:public class Coffee {
public void grindCoffee(){
// перемалываем кофе
}
public void makeCoffee(){
// делаем кофе
}
public void pourIntoCup(){
// наливаем в чашку
}
}
Dan juga beberapa ahli warisnya - 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 {}
Untuk kemudahan menerima tempahan, kami telah memperkenalkan pemindahan:
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:
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;
}
}
Pemodenan kilang ringkas
Kedai kopi kami berjalan lancar. Sehinggakan kami terfikir untuk meluaskan. Kami mahu membuka beberapa mata baru. Sebagai lelaki yang berdaya usaha, kami tidak akan membuat kedai kopi yang membosankan. Saya mahu setiap orang mempunyai kelainan tersendiri. Oleh itu, sebagai permulaan, kami akan membuka dua mata: dalam gaya Itali dan Amerika. Perubahan akan menjejaskan bukan sahaja bahagian dalam, tetapi juga minuman:- di kedai kopi Itali kami akan menggunakan jenama kopi Itali secara eksklusif, dengan pengisaran dan pemanggangan istimewa.
- Bahagian Amerika akan menjadi lebih besar sedikit, dan dengan setiap pesanan kami akan menyajikan marshmallow cair - marshmallow.
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Dan ia 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 {}
Memandangkan kami mahu mengekalkan model perniagaan semasa tidak berubah, kami mahu kaedah itu orderCoffee(CoffeeType type)
mengalami bilangan perubahan minimum. Mari kita lihat:
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = coffeeFactory.createCoffee(type);
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
Apakah pilihan yang kita ada? Kita dah tahu menulis kilang kan? Perkara paling mudah yang segera terlintas di fikiran ialah menulis dua kilang yang serupa, dan kemudian lulus pelaksanaan yang diperlukan ke kedai kopi kami dalam pembina. Kemudian kelas kedai kopi tidak akan berubah. Pertama, kita perlu mencipta kelas kilang baharu, mewarisi daripada kilang ringkas kami dan mengatasi createCoffee (CoffeeType type)
. Mari kita tulis kilang untuk membuat kopi dalam gaya Itali 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;
}
}
Kini kita boleh menghantar pelaksanaan kilang yang diperlukan kepada CoffeeShop. Mari lihat rupa kod untuk memesan kopi dari kedai kopi yang berbeza. Contohnya, cappuccino dalam gaya Itali 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 mencipta dua kedai kopi berbeza, memindahkan setiap kedai ke kilang yang diperlukan. Di satu pihak, kita telah mencapai matlamat kita, tetapi di sisi lain... Ada sesuatu yang mengguris jiwa usahawan yang tidak dapat ditekan... Mari kita fikirkan apa yang salah. Pertama, banyaknya kilang. Adakah mungkin untuk membuat kilang anda sendiri setiap kali untuk titik baru dan, sebagai tambahan, pastikan bahawa apabila membuat kedai kopi, kilang yang diperlukan dipindahkan ke pembina? Kedua, ia masih kilang yang mudah. Cuma dimodenkan sedikit. Kami masih mengkaji corak baru di sini. Ketiga, bukankah mungkin untuk melakukannya secara berbeza? Alangkah baiknya jika kita boleh menyetempatkan semua soalan tentang membuat kopi di dalam bilik darjah CoffeeShop
, menghubungkan proses membuat kopi dan menyediakan pesanan, tetapi pada masa yang sama mengekalkan fleksibiliti yang mencukupi untuk membuat kopi dalam gaya yang berbeza. Jawapannya ya, boleh. Ini dipanggil corak reka bentuk kaedah kilang.
Dari kilang yang mudah kepada kaedah kilang
Untuk menyelesaikan masalah secekap mungkin, kami:- Mari kita kembalikan kaedah
createCoffee(CoffeeType type)
kepada kelasCoffeeShop
. - Mari jadikan kaedah ini abstrak.
- Kelas itu sendiri
CoffeeShop
akan menjadi abstrak. - Kelas
CoffeeShop
akan mempunyai waris.
CoffeeShop
, melaksanakan kaedah createCoffee(CoffeeType type)
mengikut tradisi terbaik barista Itali. Jadi, mengikut urutan. Langkah 1. Mari jadikan kelas Coffee
abstrak. Kami kini mempunyai dua keluarga produk yang berbeza. Minuman kopi Itali dan Amerika masih berkongsi nenek moyang yang sama: Coffee
. Adalah betul untuk menjadikannya abstrak:
public abstract class Coffee {
public void makeCoffee(){
// делаем кофе
}
public void pourIntoCup(){
// наливаем в чашку
}
}
Langkah 2. Jadikan ia CoffeeShop
abstrak, dengan kaedah 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. Cipta kedai kopi Itali, kelas keturunan kedai kopi abstrak. Di dalamnya kami melaksanakan kaedah createCoffee(CoffeeType type)
dengan mengambil kira spesifik 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. Mari kita lakukan 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. Mari kita lihat bagaimana pesanan latte gaya Amerika dan Itali akan kelihatan seperti:
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 baru sahaja melaksanakan corak reka bentuk kaedah kilang di kedai kopi kami.
Bagaimana kaedah kilang berfungsi
Sekarang mari kita lihat lebih dekat apa yang kita dapat. Rajah di bawah menunjukkan kelas yang terhasil. Blok hijau ialah kelas pencipta, blok biru ialah kelas produk. Apakah kesimpulan yang boleh dibuat?- Semua produk adalah pelaksanaan kelas abstrak
Coffee
. - Semua pencipta adalah pelaksanaan kelas abstrak
CoffeeShop
. - Kami memerhatikan dua hierarki kelas selari:
- Hierarki produk. Kami melihat keturunan Itali dan keturunan Amerika
- Hierarki pencipta. Kami melihat keturunan Itali dan keturunan Amerika
- Superclass
CoffeeShop
tidak mempunyai maklumat tentang pelaksanaan produk tertentu (Coffee
) yang akan dibuat. - Kelas super
CoffeeShop
mewakilkan penciptaan produk tertentu kepada keturunannya. - Setiap kelas keturunan
CoffeeShop
melaksanakan kaedah kilangcreateCoffee()
mengikut spesifikasinya. Dalam erti kata lain, dalam pelaksanaan kelas pencipta, keputusan dibuat untuk menyediakan produk khusus berdasarkan spesifikasi kelas pencipta.
Struktur kaedah kilang
Rajah di atas menunjukkan struktur umum corak kaedah kilang. Apa lagi yang penting di sini?- Kelas Pencipta mengandungi pelaksanaan semua kaedah yang berinteraksi dengan produk, kecuali kaedah kilang.
- Kaedah abstrak
factoryMethod()
mesti dilaksanakan oleh semua keturunan kelasCreator
. - Kelas
ConcreteCreator
melaksanakan kaedahfactoryMethod()
yang secara langsung menghasilkan produk. - Kelas ini bertanggungjawab untuk mencipta produk tertentu. Ini adalah satu-satunya kelas dengan maklumat tentang mencipta produk ini.
- Semua produk mesti melaksanakan antara muka biasa - menjadi keturunan kelas produk biasa. Ini adalah perlu supaya kelas yang menggunakan produk boleh beroperasi pada mereka pada tahap abstraksi dan bukannya pelaksanaan konkrit.
GO TO FULL VERSION