CodeGym /Java Blogu /Rastgele /Tasarım kalıpları: Fabrika yöntemi
John Squirrels
Seviye
San Francisco

Tasarım kalıpları: Fabrika yöntemi

grupta yayınlandı
MERHABA! Bugün tasarım modellerini incelemeye devam edeceğiz ve fabrika yöntem modelini tartışacağız. Tasarım desenleri: Fabrika yöntemi - 1 Ne olduğunu ve bu kalıbın hangi görevler için uygun olduğunu öğreneceksiniz. Bu tasarım modelini pratikte ele alacağız ve yapısını inceleyeceğiz. Her şeyin net olduğundan emin olmak için aşağıdaki konuları anlamanız gerekir:
  1. Java'da kalıtım.
  2. Java'da soyut yöntemler ve sınıflar

Fabrika yöntemi hangi sorunu çözer?

Tüm fabrika tasarım kalıplarının iki tür katılımcısı vardır: yaratıcılar (fabrikaların kendileri) ve ürünler (fabrikalar tarafından yaratılan nesneler). Şu durumu hayal edin: CodeGym markalı arabalar üreten bir fabrikamız var. Çeşitli gövde türlerine sahip araba modellerinin nasıl oluşturulacağını bilir:
  • sedanlar
  • istasyon vagonları
  • darbeler
İşimiz o kadar gelişti ki, bir gün başka bir otomobil üreticisi olan OneAuto'yu satın aldık. Mantıklı işletme sahipleri olarak, herhangi bir OneAuto müşterisini kaybetmek istemiyoruz ve bu nedenle, aşağıdakileri üretebilmemiz için üretimi yeniden yapılandırma göreviyle karşı karşıyayız:
  • CodeGym sedanları
  • CodeGym istasyon vagonları
  • CodeGym kupaları
  • OneAuto sedanlar
  • OneAuto istasyon vagonları
  • OneAuto kupaları
Gördüğünüz gibi bir ürün grubu yerine artık iki ürün grubumuz var ve bunlar belirli detaylarda farklılık gösteriyor. Fabrika yöntemi tasarım deseni, her biri belirli özelliklere sahip farklı ürün grupları oluşturmamız gerektiğinde kullanılır. Önceki derslerden birinde oluşturduğumuz kahve dükkanı örneğini kullanarak, basitten karmaşığa doğru yavaş yavaş ilerleyerek bu kalıbın yol gösterici ilkesini pratikte ele alacağız .

Fabrika modeli hakkında biraz

Daha önce küçük bir sanal kahve dükkanı yaptığımızı hatırlatayım. Basit bir fabrikanın yardımıyla farklı kahve türlerinin nasıl yapıldığını öğrendik. Bugün bu örneği yeniden işleyeceğiz. Basit fabrikasıyla kahvehanemizin nasıl göründüğünü hatırlayalım. Bir kahve dersimiz vardı:

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Ve fabrikamızın üretebileceği belirli kahve türlerine karşılık gelen birkaç alt sınıf:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Sipariş vermeyi kolaylaştırmak için bir sıralama oluşturduk:

public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Kahve fabrikasının kendisi şöyle görünüyordu:

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;
    }
}
Ve son olarak, kahve dükkanının kendisi şuna benziyordu:

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;
    }
}

Basit bir fabrikayı modernize etmek

Kahvehanemiz çok iyi gidiyor. O kadar ki genişletmeyi düşünüyoruz. Yeni yerler açmak istiyoruz. Cesur ve girişimciyiz, bu yüzden sıkıcı kahve dükkanlarını mahvetmeyeceğiz. Her mağazanın özel bir dokunuşu olmasını istiyoruz. Buna göre, başlangıç ​​olarak iki lokasyon açacağız: bir İtalyan ve bir Amerikan. Bu değişiklikler sadece iç tasarımı değil, sunulan içecekleri de etkileyecek:
  • İtalyan kahve dükkanında, özel öğütme ve kavurma ile sadece İtalyan kahve markalarını kullanacağız.
  • Amerika lokasyonu daha büyük porsiyonlara sahip olacak ve her siparişte marshmallow sunacağız.
Değişmeyen tek şey mükemmel olduğunu kanıtlamış iş modelimizdir. Kod açısından, olan budur. Ürünlerimize karşılık gelen 4 sınıfımız vardı:

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Ama şimdi 8'e sahip olacağız:

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 {}
Mevcut iş modelini korumak istediğimiz için, orderCoffee(CoffeeType type)yöntemin mümkün olduğunca az değişikliğe uğramasını istiyoruz. Ona bir göz atın:

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;
}
Hangi seçeneklerimiz var? Fabrika yazmayı zaten biliyoruz, değil mi? Hemen akla gelen en basit şey, iki benzer fabrika yazmak ve ardından istenen uygulamayı kahvehanemizin kurucusuna iletmek. Bunu yaparak kahvehanenin sınıfı değişmeyecektir. İlk olarak, yeni bir fabrika sınıfı yaratmalı, basit fabrikamızı devralmalı ve ardından yöntemi geçersiz kılmalıyız createCoffee(CoffeeType type). İtalyan tarzı kahve ve Amerikan tarzı kahve yapmak için fabrikaları yazalım:

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;
    }

}
Artık istediğimiz fabrika uygulamasını CoffeeShop'a geçirebiliriz. Farklı kahve dükkanlarından kahve sipariş etme kodunun nasıl görüneceğine bakalım. Örneğin, İtalyan tarzı ve Amerikan tarzı kapuçino:

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);
    }
}
Her birine istediğimiz fabrikayı geçirerek iki farklı kahvehane oluşturduk. Bir yandan amacımıza ulaştık ama diğer yandan... Bu durum girişimcilerin pek hoşuna gitmiyor nedense... Hadi bakalım sorun neymiş. Birincisi, fabrikaların bolluğu. Ne? Şimdi her yeni lokasyon için kendi fabrikasını kurmamız ve buna ek olarak bir kahvehane kurarken ilgili fabrikanın müteahhide geçtiğinden emin olmamız mı gerekiyor? İkincisi, hala basit bir fabrika. Sadece biraz modernize edildi. Ama yeni bir model öğrenmek için buradayız. Üçüncüsü, farklı bir yaklaşım mümkün değil mi? Kahve hazırlama ile ilgili tüm konuları gündeme getirebilsek harika olurdu.CoffeeShopAynı anda çeşitli kahve stilleri yapmak için yeterli esnekliği korurken, kahve oluşturma ve sipariş verme süreçlerini birbirine bağlayarak sınıf. Cevap evet, yapabiliriz. Buna fabrika yöntemi tasarım modeli denir.

Basit bir fabrikadan fabrika yöntemine

Görevi olabildiğince verimli bir şekilde çözmek için:
  1. createCoffee(CoffeeType type)Yöntemi sınıfa geri döndürüyoruz CoffeeShop.
  2. Bu yöntemi soyut hale getireceğiz.
  3. Sınıfın CoffeeShopkendisi soyut hale gelecektir.
  4. Sınıfın CoffeeShopçocuk sınıfları olacaktır.
Evet arkadaş. İtalyan kahve dükkanı, yöntemi İtalyan baristalarının en iyi geleneklerine göre CoffeeShopuygulayan sınıfın soyundan başka bir şey değildir . createCoffee(CoffeeType type)Şimdi, her seferinde bir adım. Adım 1. CoffeeSınıfı özetleyin. Farklı ürünlerden oluşan iki ailemiz var. Yine de, İtalyan ve Amerikan kahvelerinin ortak bir ataları vardır: sınıf Coffee. Soyutlamak uygun olacaktır:

public abstract class Coffee {
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Adım 2. CoffeeShopSoyut bir yöntemle soyut createCoffee(CoffeeType type)yapın

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);
}
Adım 3. Soyut kahve dükkanının soyundan gelen bir İtalyan kahve dükkanı oluşturun. createCoffee(CoffeeType type)İtalyan tariflerinin özelliklerini dikkate alarak içindeki yöntemi uyguluyoruz .

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;
    }
}
Adım 4. Amerikan tarzı kahve dükkanı için de aynısını yapıyoruz.

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;
    }
}
Adım 5. Amerikan ve İtalyan lattelerinin nasıl görüneceğine bakın:

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);
    }
}
Tebrikler. Örnek olarak kahve dükkanımızı kullanarak fabrika yöntemi tasarım modelini az önce uyguladık.

Fabrika yöntemlerinin arkasındaki ilke

Şimdi neye sahip olduğumuzu daha ayrıntılı olarak ele alalım. Aşağıdaki diyagram sonuçta ortaya çıkan sınıfları göstermektedir. Yeşil bloklar yaratıcı sınıfları, mavi bloklar ise ürün sınıflarıdır. Tasarım kalıpları: Fabrika yöntemi - 2Hangi sonuçlara varabiliriz?
  1. Tüm ürünler soyut sınıfın uygulamalarıdır Coffee.
  2. Tüm yaratıcılar, soyut sınıfın uygulamalarıdır CoffeeShop.
  3. İki paralel sınıf hiyerarşisi görüyoruz:
    • Ürünlerin hiyerarşisi. İtalyan torunlarını ve Amerikan torunlarını görüyoruz
    • Yaratıcıların hiyerarşisi. İtalyan torunlarını ve Amerikan torunlarını görüyoruz
  4. Üst sınıf, hangi belirli ürünün ( ) oluşturulacağı CoffeeShophakkında hiçbir bilgiye sahip değildir .Coffee
  5. Üst CoffeeShopsınıf, belirli bir ürünün yaratılmasını soyundan gelenlere devreder.
  6. Sınıfın her soyundan gelen, kendi özelliklerine uygun olarak CoffeeShopbir fabrika yöntemi uygular . createCoffee()Diğer bir deyişle, üretici sınıflarının uygulamaları, üretici sınıfının özelliklerine göre belirli ürünler hazırlar.
Artık fabrika yöntemi modelinin tanımı için hazırsınız . Fabrika yöntemi modeli, bir nesne oluşturmak için bir arabirim tanımlar, ancak alt sınıfların oluşturulan nesnenin sınıfını seçmesine izin verir. Bu nedenle, bir fabrika yöntemi, bir örneğin oluşturulmasını alt sınıflara devreder. Genel olarak, tanımı hatırlamak, her şeyin nasıl çalıştığını anlamak kadar önemli değildir.

Bir fabrika yönteminin yapısı

Tasarım desenleri: Fabrika yöntemi - 3Yukarıdaki diyagram, fabrika yöntemi modelinin genel yapısını göstermektedir. Burada başka ne önemlidir?
  1. Creator sınıfı, fabrika yöntemi dışında ürünlerle etkileşime giren tüm yöntemleri uygular.
  2. Soyut factoryMethod()yöntem, sınıfın tüm torunları tarafından uygulanmalıdır Creator.
  3. Sınıf , ürünü doğrudan oluşturan yöntemi ConcreteCreatoruygular .factoryMethod()
  4. Bu sınıf, belirli ürünler oluşturmaktan sorumludur. Bu ürünlerin oluşturulması hakkında bilgi içeren tek sınıf budur.
  5. Tüm ürünler ortak bir arayüz uygulamalıdır, yani ortak bir ürün sınıfının torunları olmalıdır. Bu, ürünleri kullanan sınıfların bunlar üzerinde belirli uygulamalar yerine soyutlamalar olarak çalışabilmeleri için gereklidir.

Ev ödevi

Bugün oldukça fazla iş yaptık ve fabrika yöntemi tasarım modelini inceledik. Malzemeyi güçlendirme zamanı! Alıştırma 1. Başka bir kahve dükkanı açmak için işi yapın. İngiliz tarzı veya İspanyol tarzı bir kahve dükkanı olabilir. Hatta uzay gemisi tarzı. Parlatmak için kahveye gıda boyası ekleyin ve kahveniz bu dünyanın dışında olacak! Alıştırma 2. Geçen derste , sanal bir suşi barı veya sanal bir pizzacı yarattığınız bir alıştırma yaptınız. Şimdi egzersiziniz hareketsiz durmamaktır. Bugün fabrika yöntemi modelini kendi avantajınıza nasıl kullanacağınızı öğrendiniz. Bu bilgiyi kullanmanın ve kendi işinizi büyütmenin zamanı geldi;)
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION