Hai! Hari ini kita akan melanjutkan mempelajari pola desain dan kita akan membahas pola metode pabrik.
Anda akan mengetahui apa itu dan tugas apa yang cocok untuk pola ini. Kami akan mempertimbangkan pola desain ini dalam praktik dan mempelajari strukturnya. Untuk memastikan semuanya jelas, Anda perlu memahami topik-topik berikut:
Kesimpulan apa yang bisa kita buat?
Diagram di atas menunjukkan struktur umum pola metode pabrik. Apa lagi yang penting di sini?

- Warisan di Jawa.
- Metode dan kelas abstrak di Java
Masalah apa yang dipecahkan oleh metode pabrik?
Semua pola desain pabrik memiliki dua jenis peserta: pencipta (pabrik itu sendiri) dan produk (objek yang dibuat oleh pabrik). Bayangkan situasi berikut: kami memiliki pabrik yang memproduksi mobil bermerek CodeGym. Ia tahu cara membuat model mobil dengan berbagai tipe bodi:- sedan
- station wagon
- coupe
- Sedan CodeGym
- gerbong stasiun CodeGym
- coupe CodeGym
- Sedan OneAuto
- gerbong stasiun OneAuto
- coupe OneAuto
Sedikit tentang pola pabrik
Izinkan saya mengingatkan Anda bahwa kami sebelumnya membangun kedai kopi virtual kecil. Dengan bantuan pabrik sederhana, kami belajar cara membuat berbagai jenis kopi. Hari ini kita akan mengerjakan ulang contoh ini. Mari kita ingat bagaimana rupa kedai kopi kita, dengan pabriknya yang sederhana. Kami memiliki 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 anak yang sesuai dengan 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 {}
Kami membuat enum untuk memudahkan pemesanan:
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Pabrik kopi itu 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 akhirnya, kedai kopi itu sendiri terlihat 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;
}
}
Memodernisasi pabrik sederhana
Kedai kopi kami berjalan dengan sangat baik. Sedemikian rupa sehingga kami mempertimbangkan untuk memperluas. Kami ingin membuka beberapa lokasi baru. Kami berani dan giat, jadi kami tidak akan membuat kedai kopi yang membosankan. Kami ingin setiap toko memiliki sentuhan khusus. Oleh karena itu, sebagai permulaan, kami akan membuka dua lokasi: satu Italia dan satu Amerika. Perubahan ini tidak hanya memengaruhi desain interior, tetapi juga minuman yang ditawarkan:- di kedai kopi Italia, kami akan menggunakan merek kopi eksklusif Italia, dengan penggilingan dan pemanggangan khusus.
- lokasi Amerika akan memiliki porsi yang lebih besar, dan kami akan menyajikan marshmallow dengan setiap pesanan.
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Tapi sekarang kita akan memiliki 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 mempertahankan model bisnis saat ini, kami ingin orderCoffee(CoffeeType type)
metode ini mengalami perubahan sesedikit mungkin. Lihatlah itu:
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;
}
Pilihan apa yang kita miliki? Nah, 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 diinginkan ke konstruktor kedai kopi kita. Dengan melakukan ini, kelas kedai kopi tidak akan berubah. Pertama, kita perlu membuat kelas pabrik baru, membuatnya mewarisi pabrik sederhana kita, dan kemudian mengganti metodenya createCoffee(CoffeeType type)
. Mari tulis pabrik untuk membuat kopi ala Italia dan kopi ala 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 diinginkan ke CoffeeShop. Mari kita lihat seperti apa kode untuk memesan kopi dari kedai kopi yang berbeda. Misalnya, cappucino ala Italia dan ala 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 membuat dua kedai kopi yang berbeda, melewati masing-masing pabrik yang diinginkan. Di satu sisi, kami telah mencapai tujuan kami, tetapi di sisi lain... Entah bagaimana hal ini tidak sesuai dengan para pengusaha... Mari kita cari tahu apa yang salah. Pertama, banyaknya pabrik. Apa? Sekarang untuk setiap lokasi baru, kita harus membuat pabriknya sendiri dan, selain itu, memastikan bahwa pabrik yang relevan diteruskan ke konstruktor saat membuat kedai kopi? Kedua, pabriknya masih sederhana. Hanya dimodernisasi sedikit. Tapi kami di sini untuk mempelajari pola baru. Ketiga, bukankah pendekatan yang berbeda mungkin? Alangkah baiknya jika kita bisa memasukkan semua masalah yang berkaitan dengan persiapan kopi ke dalamCoffeeShop
kelas dengan menghubungkan proses pembuatan kopi dan melayani pesanan, sekaligus mempertahankan fleksibilitas yang cukup untuk membuat berbagai jenis kopi. Jawabannya adalah ya, kita bisa. Ini disebut pola desain metode pabrik.
Dari pabrik sederhana hingga metode pabrik
Untuk menyelesaikan tugas seefisien mungkin:- Kami mengembalikan
createCoffee(CoffeeType type)
metode keCoffeeShop
kelas. - Kami akan membuat metode ini abstrak.
- Kelas
CoffeeShop
itu sendiri akan menjadi abstrak. - Kelas
CoffeeShop
akan memiliki kelas anak.
CoffeeShop
yang menerapkan createCoffee(CoffeeType type)
metode sesuai dengan tradisi terbaik barista Italia. Sekarang, selangkah demi selangkah. Langkah 1. Buat Coffee
abstrak kelas. Kami memiliki dua keluarga utuh dari produk yang berbeda. Tetap saja, kopi Italia dan Amerika memiliki nenek moyang yang sama — kelasnya Coffee
. Akan tepat untuk membuatnya abstrak:
public abstract class Coffee {
public void makeCoffee(){
// Brew the coffee
}
public void pourIntoCup(){
// Pour into a cup
}
}
Langkah 2. Buat abstrak, dengan metode CoffeeShop
abstrakcreateCoffee(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 Italia, yang merupakan turunan dari kedai kopi abstrak. Kami menerapkan createCoffee(CoffeeType type)
metode di dalamnya, dengan mempertimbangkan spesifikasi resep 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. Kami melakukan 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. Lihat bagaimana tampilan latte 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 menggunakan kedai kopi kami sebagai contoh.
Prinsip di balik metode pabrik
Sekarang mari kita pertimbangkan lebih detail apa yang kita dapatkan. Diagram di bawah menunjukkan kelas yang dihasilkan. Blok hijau adalah kelas pembuat, dan blok biru adalah kelas produk.
- Semua produk adalah implementasi dari
Coffee
kelas abstrak. - Semua pembuat adalah implementasi dari
CoffeeShop
kelas abstrak. - Kami melihat dua hierarki kelas paralel:
- Hirarki produk. Kami melihat keturunan Italia dan keturunan Amerika
- Hirarki pencipta. Kami melihat keturunan Italia dan keturunan Amerika
- Superclass
CoffeeShop
tidak memiliki informasi tentang produk tertentu (Coffee
) yang akan dibuat. - Superclass
CoffeeShop
mendelegasikan pembuatan produk tertentu kepada keturunannya. - Setiap keturunan kelas
CoffeeShop
mengimplementasikancreateCoffee()
metode pabrik sesuai dengan fitur spesifiknya sendiri. Dengan kata lain, implementasi kelas produsen menyiapkan produk spesifik berdasarkan spesifikasi kelas produsen.
Struktur metode pabrik

- Kelas Creator mengimplementasikan semua metode yang berinteraksi dengan produk, kecuali metode pabrik.
- Metode abstrak
factoryMethod()
harus diimplementasikan oleh semua keturunan kelasCreator
. - Kelas
ConcreteCreator
mengimplementasikanfactoryMethod()
metode, yang secara langsung menciptakan produk. - Kelas ini bertanggung jawab untuk menciptakan produk tertentu. Ini adalah satu-satunya kelas dengan informasi tentang pembuatan produk ini.
- Semua produk harus mengimplementasikan antarmuka umum, yaitu mereka harus turunan dari kelas produk umum. Hal ini diperlukan agar kelas yang menggunakan produk dapat mengoperasikannya sebagai abstraksi, bukan implementasi khusus.
GO TO FULL VERSION