Tasarım Desenleri: Fabrika vs Fabrika yöntemi vs Soyut Fabrika


183

Bir web sitesinden tasarım kalıpları okuyordum

Orada Fabrika, Fabrika yöntemi ve Soyut fabrika hakkında okudum ama çok kafa karıştırıcı, tanımı net değil. Tanımlara göre

Fabrika - Örnekleme mantığını istemciye maruz bırakmadan nesneler oluşturur ve ortak bir arabirim aracılığıyla yeni oluşturulan nesneyi ifade eder. Fabrika Yönteminin basitleştirilmiş bir versiyonudur

Fabrika Yöntemi - Nesneler oluşturmak için bir arabirim tanımlar, ancak alt sınıfların hangi sınıfın örnekleneceğine karar vermesine izin verir ve ortak bir arabirim aracılığıyla yeni oluşturulan nesneyi ifade eder.

Abstract Factory - Sınıflarını açıkça belirtmeden ilgili nesnelerin bir ailesini oluşturmak için arabirim sunar.

Ayrıca Abstract Factory vs Factory Method ile ilgili diğer yığın akışı konularına da baktım, ancak orada çizilen UML diyagramları anlayışımı daha da kötüleştiriyor.

Kimse bana söyleyebilir mi

  1. Bu üç örüntü birbirinden nasıl farklı?
  2. Hangisi ne zaman kullanılır?
  3. Ve ayrıca mümkünse, bu modellerle ilgili herhangi bir java örneği var mı?

3
Ben OP ile kabaca aynı soruya cevap ararken, bu makaleyi buldum: Fabrikadan Fabrika Metoduna . Örnek bir projenin gelişimini takip ederek içgörü sağlar (başlıkta bahsedilen fabrika yöntemi evrimsel adımlardan biridir).
Nick Alexeev

Yanıtlar:


252

Her üç Fabrika tipi de aynı şeyi yapar: Bunlar "akıllı bir kurucu" dur.

Diyelim ki iki çeşit Meyve yaratmak istiyorsunuz: Elma ve Portakal.

Fabrika

Fabrika "sabit", alt sınıflama olmadan sadece bir uygulama var. Bu durumda, böyle bir sınıfınız olacaktır:

class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

Kullanım örneği: Bir Apple veya Portakal oluşturmak, her ikisi için de yapıcıda işlemek için biraz karmaşıktır.

Fabrika Yöntemi

Fabrika yöntemi genellikle bir sınıfta genel bir işleme sahip olduğunuzda kullanılır, ancak gerçekte kullandığınız meyve türünü değiştirmek istediğinizde. Yani:

abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

... daha sonra FruitPicker.pickFruit()alt sınıflarda fabrika yöntemi uygulayarak ortak işlevselliği yeniden kullanabilirsiniz :

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

Soyut Fabrika

Soyut fabrika, normalde bağımlılık enjeksiyonu / stratejisi gibi, "aynı türden" olması gereken ve bazı ortak temel sınıflara sahip olması gereken bir nesne ailesi oluşturmak istediğinizde kullanılır. İşte belirsiz bir meyve ile ilgili örnek. Buradaki kullanım örneği, bir Apple'da yanlışlıkla bir OrangePicker kullanmadığımızdan emin olmak istiyoruz. Sürece bizim meyve ve seçici aynı fabrikadan, onlar maç.

interface PlantFactory {

  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}

8
+1 Bu, bu kalıpları anlamama en çok benzeyen cevap. Arama kodu (İstemci) örnekleri eklemek de yardımcı olur mu? Beni çok rahatsız eden soru şudur: Soyut Fabrika Deseni'nin Fabrika Yöntemi ile sadece Fabrika genişletilmiş olduğunu söyleyebilir miyiz (bu doğruysa, bu konuda açıkım)?
croraf

9
Yıllarca aradığım örnek budur.
Taztingo

Bu harika bir açıklama! Teşekkürler!
André Andrade

@ AndréAndrade Fabrika Yöntemini nasıl çağırırım ? Küçük bir kod samle pls :) Kullanımıyla ilgili şüphemizi temizleyecek
Arnab Dutta

25
  1. Bu üç örüntü birbirinden nasıl farklı?

Fabrika: Örnekleme mantığını istemciye göstermeden nesneler oluşturur.

Fabrika Yöntemi: Nesne oluşturmak için bir arabirim tanımlayın, ancak alt sınıfların hangi sınıfı başlatacağına karar vermesine izin verin. Fabrika yöntemi, bir sınıfın alt sınıflara örnek oluşturmayı ertelemesine

Özet Fabrika: İlgili veya bağımlı nesnelerin ailelerini, somut sınıflarını belirtmeden oluşturmak için bir arayüz sağlar.

AbstractFactory deseni, nesne oluşturma sorumluluğunu başka bir sınıfa devretmek için kompozisyon kullanır, Fabrika yöntemi tasarım deseni miras kullanır ve nesne oluşturmak için türetilmiş sınıf veya alt sınıfa dayanır

  1. Hangisi ne zaman kullanılır?

Fabrika: Müşteri sadece bir sınıfa ihtiyaç duyar ve hangi somut uygulamayı aldığını umursamaz.

Fabrika Metodu: Müşteri, çalışma zamanında hangi somut sınıfları oluşturması gerektiğini bilmez, ancak sadece işi yapacak bir sınıf almak ister.

AbstactFactory: Sisteminizin birden fazla ürün ailesi oluşturması gerektiğinde veya uygulama ayrıntılarını göstermeden bir ürün kütüphanesi sağlamak istediğinizde.

Özet Fabrika sınıfları genellikle Fabrika Yöntemi ile uygulanır. Fabrika Yöntemleri genellikle Şablon Yöntemleri içinde çağrılır.

  1. Ve ayrıca mümkünse, bu modellerle ilgili herhangi bir java örneği var mı?

Fabrika ve Fabrika Metodu

niyet:

Nesne oluşturmak için bir arabirim tanımlayın, ancak alt sınıfların hangi sınıfı başlatacağına karar vermesine izin verin. Fabrika Yöntemi, bir sınıfın alt sınıflara örnek oluşturmayı ertelemesini sağlar.

UML diyagramı :

resim açıklamasını buraya girin

Ürün: Factory yönteminin oluşturduğu nesnelerin bir arayüzünü tanımlar.

ConcreteProduct: Ürün arayüzünü uygular

Oluşturan: Factory yöntemini beyan eder

ConcreateCreator: ConcreteProduct örneğini döndürmek için Fabrika yöntemini uygular

Sorun bildirimi: Oyun arayüzünü tanımlayan Fabrika Yöntemlerini kullanarak bir Oyun Fabrikası oluşturun.

Kod snippet'i:

Fabrika düzeni. Fabrika yöntemleri ne zaman kullanılır?

Diğer yaratıcı desenlerle karşılaştırma:

  1. Tasarım , daha fazla esnekliğin gerekli olduğu yeri keşfederken Fabrika Yöntemini (daha az karmaşık, daha özelleştirilebilir, alt sınıflar çoğalır) kullanarak başlayın ve Soyut Fabrika, Prototip veya Oluşturucu'ya (daha esnek, daha karmaşık) doğru ilerleyin.

  2. Özet Fabrika sınıfları genellikle Fabrika Yöntemleri ile uygulanır , ancak Prototip kullanılarak da uygulanabilir

Daha fazla okuma için referanslar: Kaynak yapımı tasarım modelleri


Fabrika Yöntemi için, bir üst sınıf tanımlamamalı mı?
Tony Lin

21

Fabrika - Karmaşık nesne oluşturmak için ayrı Fabrika sınıfı.

Örn: Fruit nesnesi oluşturmak için FruitFactory sınıfı

class FruitFactory{

public static Fruit getFruit(){...}

}

Fabrika Yöntemi - Fabrika için ayrı bir sınıf yerine, bu sınıfın kendisine fabrika olarak bir yöntem ekleyin.

Ör:

Calendar.getInstance() (Java's Calendar)

Soyut Fabrika Yöntemi - Fabrika Fabrikası

Örn: Bilgisayar parçaları için fabrika kurmak istediğimizi varsayalım. Yani Dizüstü, Masaüstü, Sunucu gibi çeşitli bilgisayar türleri vardır.

Yani her bilgisayar türü için fabrikaya ihtiyacımız var. Bu yüzden aşağıdaki gibi fabrikaların bir üst düzey fabrikasını oluşturuyoruz

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Şimdi bu 3'ün kendisi yine fabrikalar. (PartFactory'nin kendisi ile ilgileneceksiniz, ancak başlık altında, soyut fabrikada verdiğiniz bilgilere dayanarak ayrı bir uygulama olacak)

  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

EDIT: yorumlardaki itirazlara göre Özet Fabrika için kesin arayüzler sağlamak üzere düzenlenmiştir.


1
Bunun arkasındaki fikir , önerdiğiniz gibi bilgisayar türü başına bir arabirim değil, ComputerFactoryortak bir oluşturma arabirimine ( getScreen(); getKeyboard(); getDiskdrive(); ...) sahip olmanızdır. Aynı kelimeyi aynı ifadede iki kez kullanırsanız bir tasarım sorunu koklayabilirsiniz: Laptop Factory.get Laptop Part ().
xtofl

Hayır hayır hayır, tam olarak kodun kendisine gitmeyin. Sadece anlamak için bir anolojiydi. Arayüzlerle tam bir örnek istiyorsanız, işte burada. Nesneler: Arayüz -> ComputerPart, Uygulama -> RAM, HDD, İşlemci Fabrika: Interface-> PartFactory. getComputerPart (Dize), Uygulamalar -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory. Abstract Factory: ComputerType.getPartFactory (“String s”) Kullanımı: yeni ComputerType (). GetFactory (“Laptop”). GetComputerPart (“RAM”)
Ravi K

2
Endişenizi gidermek için cevabı güncelledim. Aslında soyut fabrika sadece fabrika factoy başka bir şey değildir. Daha önce sadece referans için örnek verdim (gerçek uygulama sırasında okuyucuların arayüzlerle ilgileneceğini varsayalım). Bildirdiğiniz için teşekkür ederiz. Geliştirmek her zaman iyidir. :)
Ravi K

Hayır abstract Factorybir fabrika fabrikası değildir ... Farklı beton fabrikaları ile uygulanacak / genişletilecek bir nesne oluşturabilir abstract classveya interfaceyaratabilir. Kod ayrıntıları için kabul edilen cevaba bakınız. Lütfen cevabınızı buna göre kaldırın veya düzenleyin.
Julien__

Neden bu kadar isimlendirildiğini açıklayacak kadar özlü olan fabrika yönteminin açıklamasını seviyorum. Bu modelde fabrika yöntemdir, genellikle örnekleme yöntemlerini gruplamada yardımcı olan ancak kendi başına anlamlı olan sınıf DEĞİLDİR. Diğer daha ayrıntılı cevaplar maalesef bu noktayı kaçırdı.
wlnirvana

11

Her tasarım deseni yazılı, çalışma koduna dokunulmamasını sağlamaya çalışır. Hepimiz biliyoruz ki, çalışma koduna dokunduğumuzda, mevcut çalışma akışlarında kusurlar vardır ve hiçbir şeyi kırmadığımızdan emin olmak için çok daha fazla test yapılması gerekir.

Fabrika kalıbı, giriş ölçütlerine göre nesneler oluşturur, böylece kodun bu tür bir nesneyi oluşturması gibi kod yazmanıza gerek kalmamasını sağlar. Bunun iyi bir örneği bir seyahat web sitesidir. Bir seyahat web sitesi sadece seyahat (uçuş, tren, otobüs) sağlayabilir ve / veya otel veya / ve turistik cazibe paketleri sağlayabilir. Bir kullanıcı bir sonraki seçtiğinde, web sitesinin hangi nesneleri oluşturması gerektiğine karar vermesi gerekir. Sadece seyahat veya otel nesnesini de yaratmalı.

Şimdi, portföyünüze başka bir web sitesi eklemeyi planlıyorsanız ve aynı çekirdeğin, örneğin artık taksileri arayan ve çevrimiçi ödeme yapan bir carpooling web sitesi kullanıldığına inanıyorsanız, çekirdeğinizde soyut bir fabrika kullanabilirsiniz. Bu şekilde, bir kabin ve carpools fabrikasına daha girebilirsiniz.

Her iki fabrikanın birbiriyle ilgisi yok, bu yüzden onları farklı fabrikalarda tutmak için iyi bir tasarım.

Umarım bu şimdi açıktır. Bu örneği aklınızda tutarak web sitesini tekrar inceleyin, umarım yardımcı olacaktır. Umarım desenleri doğru bir şekilde temsil ederim :).


3

Bu cevap için "Dörtlü Çete" kitabına bakıyorum.

Orada hiçbir kitapta "Fabrika" ne de "Basit Fabrikası" ne de "Sanal Fabrikası" tanımları. Genellikle insanlar "Fabrika" kalıbından bahsederken , bir sınıfın belirli bir nesnesini yaratan (ancak "kurucu" kalıbından değil) bir şeyden bahsediyor olabilirler ; onlar olabilir veya olmayabilir "Fabrika Yöntemi" veya "Özet Fabrikası" desen bakın. Herkes resmi bir terim olmadığı için "Fabrika" yı uygulayabilir (bazı insanlar \ şirketler \ topluluklarının kendi sözcük dağarcığına sahip olabileceğini unutmayın).

Kitap sadece "Soyut Fabrika" ve "Fabrika Metodu" tanımlarını içermektedir.

İşte kitaptan tanımlar ve her ikisinin neden bu kadar kafa karıştırıcı olabileceğine dair kısa bir açıklama. Kod örneklerini atladım çünkü bunları diğer cevaplarda bulabilirsiniz:

Fabrika Yöntemi (GOF) : Nesne oluşturmak için bir arabirim tanımlayın, ancak alt sınıfların hangi sınıfı başlatacağına karar vermesine izin verin. Fabrika Yöntemi, bir sınıfın alt sınıflara örnek oluşturmayı ertelemesini sağlar.

Soyut Fabrika (GOF) : Somut sınıflarını belirtmeden ilgili veya bağımlı nesnelerin ailelerini oluşturmak için bir arayüz sağlayın.

Karışıklık Kaynağı : Genellikle "Fabrika Metodu" örüntüsünde kullanılan bir sınıfı "Fabrika" olarak adlandırabiliriz. Bu sınıf tanım gereği soyuttur. Bu yüzden bu sınıfa "Soyut Fabrika" demek kolay. Ama bu sadece sınıfın adı; "Abstract Factory" kalıbıyla karıştırmamalısınız (sınıf adı! = kalıp adı). "Soyut Fabrika" desen farklı - bu mu değil soyut sınıfını kullanın; daha büyük bir nesnenin parçalarını veya birbiriyle ilişkili veya belirli bir şekilde oluşturulması gereken nesneleri oluşturmak için bir arabirim (mutlaka bir programlama dili arabirimi değil) tanımlar.


2
AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB

interface Factory {
    AbstractProductA getProductA(); //Factory Method - generate A1/A2
}

Fabrika yöntemini kullanarak, kullanıcı AbstractProductA'nın A1 veya A2'sini oluşturabilir.

interface AbstractFactory {
    AbstractProductA getProductA(); //Factory Method
    AbstractProductB getProductB(); //Factory Method
}

Ancak 1'den fazla fabrika yöntemine (örn: 2 fabrika yöntemi) sahip Soyut Fabrika, bu fabrika yöntemlerini kullanarak nesne / ilgili nesne kümesini oluşturacaktır. Abstract Factory kullanarak, kullanıcı AbstractProductA, AbstractProductB'nin A1, B1 nesnelerini oluşturabilir


0

Hiç kimse “Yaratıcı Desenler Tartışması” (vurgu mayını) bölümünün ilk iki paragrafında cevap veren, Tasarım Desenleri: Yeniden Kullanılabilir Nesneye Yönelik Yazılım Öğeleri'ni alıntılamamıştır :

Bir sistemi, oluşturduğu nesne sınıflarına göre parametreleştirmenin iki yaygın yolu vardır. Bunun bir yolu, nesneleri oluşturan sınıfı alt sınıfa ayırmaktır; bu, Fabrika Yöntemi (107) deseninin kullanımına karşılık gelir. Bu yaklaşımın ana dezavantajı, sadece ürünün sınıfını değiştirmek için yeni bir alt sınıf gerektirebilmesidir. Bu tür değişiklikler basamaklandırılabilir. Örneğin, ürün yaratıcısının kendisi bir fabrika yöntemiyle oluşturulduğunda, yaratıcısını da geçersiz kılmanız gerekir.

Bir sistemi parametreleştirmenin diğer yolu daha çok nesne kompozisyonuna dayanır : Ürün nesnelerinin sınıfını bilmekle sorumlu olan bir nesneyi tanımlayın ve sistemin bir parametresi yapın. Bu, Abstract Factory (87), Builder (97) ve Prototype (117) modellerinin önemli bir özelliğidir. Her üçü de sorumluluğu ürün nesneleri yaratmak olan yeni bir “fabrika nesnesi” yaratmayı içerir. Özet Fabrika, çeşitli sınıflardan nesneler üreten fabrika nesnesine sahiptir. Oluşturucu, fabrika nesnesine, buna karşılık gelen karmaşık bir protokol kullanılarak aşamalı olarak karmaşık bir ürün inşa eder. Prototip, bir prototip nesnesini kopyalayarak bir ürün oluşturan fabrika nesnesine sahiptir. Bu durumda, fabrika nesnesi ve prototip aynı nesnedir, çünkü prototip ürünü iade etmekten sorumludur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.