Fabrika Kalıbı Açık / Kapalı İlkesini ihlal ediyor mu?


14

Bu ShapeFactory neden örneklenecek nesneyi belirlemek için koşullu ifadeler kullanır. İleride başka sınıflar eklemek istiyorsak ShapeFactory'yi değiştirmek zorunda değiliz mi? Bu neden açık kapalı ilkeyi ihlal etmiyor?

Fabrika Desen Tasarımı

Şekil Fabrika Tasarımı


2
Tam olarak hangi “fabrika modelinden” bahsediyorsunuz? Genel olarak fabrika, bir nesneyi somutlaştırmaya yarayan herhangi bir nesne veya yöntemdir. Daha sonra, bu fabrika fikrinin, her fabrika örneğinin, şartlar yerine alt sınıflandırma yoluyla yönetilen belirli bir seçenekler paletini temsil ettiği Soyut Fabrika Deseni gibi belirli varyasyonları vardır.
amon


3
Bu bilgi için teşekkürler, bu çok açık. Bu kesin olarak bir fabrika modelinin bir örneğidir, ancak yaygın olarak fabrika modelleriyle ilişkilendirilmiş Özet Fabrika Deseninin bir örneğidir. Bu makaledeki kod oldukça tartışmalı ve gerçek kodda böyle bir şey görmeyi beklemiyordum.
amon

@ArmonSafai: Bu blog yayınını çok bağlıyorsunuz, ama nedenini gerçekten açıklamıyorsunuz. Hepimiz bir şekilde modelden habersiz miyiz? Tıpkı sizin gibi Google da var.
Robert Harvey

1
@RobertHarvey Bu sayfadaki fabrika modelinin koşullu olarak nasıl kullanıldığını göstermek için bu blog gönderisini
bağlıyorum

Yanıtlar:


20

Geleneksel nesne yönelimli bilgelik, ififadelerden kaçınmak ve bunları soyut bir sınıfın alt sınıflarında geçersiz kılınmış yöntemlerin dinamik olarak gönderilmesiyle değiştirmektir. Çok uzak çok iyi.

Ancak fabrika modelinin amacı , sizi bireysel alt sınıflar hakkında bilgi sahibi olmaktan ve sadece soyut süper sınıfla çalışmaktan kurtarmaktır . Fikir, fabrikanın hangi sınıfın somutlaştırılacağını sizden daha iyi bilmesi ve sadece süper sınıf tarafından yayınlanan yöntemlerle daha iyi çalışmanızdır. Bu genellikle doğrudur ve değerli bir örüntüdür.

Bu nedenle, bir fabrika sınıfı yazmanın ififadelerden vazgeçmesinin bir yolu yoktur . Öyle arayan, belirli bir sınıfı seçerek yükünü kayacaktır tam desen kaçınmak için ne gerekiyor. Tüm ilkeler (aslında, mutlak olan hiçbir ilke mutlaktır) ve bu deseni kullanırsanız ondan fayda bir kullanmayan yararına daha büyük olduğunu varsaymak istiyorum if.


2
Çok fazla ifs olmadan bir fabrika deseni oluşturmak mükemmel bir şekilde mümkündür . Bunu nasıl başaracağınıza dair basit bir örnek için @ BЈовић cevabına bakınız. Downvoted.
David Arno


11
@DavidArno Doğal olarak, beton sınıfını seçmenin farklı yolları vardır. Servis Bulucu bir, yapılandırılabilir bir IoC Container ise bir diğeri. Bunlar sadece uygulama detaylarıdır; Killian'ın ana mesajından uzaklaşmazlar, yani Fabrika arayanı hangi somut sınıfı başlatacağına karar vermekten kurtarır. Detaylara saplanmayın.
Robert Harvey

1
Soruya hiçbir şekilde cevap vermeyen müthiş bir açıklama.
Martin Maat

1
@ R.Schmitz Sanırım varsayımda yanlışsın. Bence birçok kişi bu soruyu OP'den kaçırdı: "Gelecekte başka sınıflar eklemek istiyorsak ShapeFactory'yi değiştirmek zorunda değiliz mi?" Açıkça, OP, yeni işlevsellik eklemek için mevcut kodu değiştirmeniz gerektiğinden, bu modelin OCP'yi ihlal ettiğini düşünerek kafası karışır. Bu soruya doğru cevap cevabımda bulunabilir. Kısa cevap: Bu kodu yalnız bırakıyorsunuz ve mevcut fabrika işlevinizi UZATMA (değiştirmeme) için Soyut Fabrika kalıbını uyguluyorsunuz. Bu nedenle Kilian'ın cevabı soruyu SÖYLEMİYOR.
hfontanez

5

Örnek muhtemelen koşullu bir ifade kullanır çünkü en basitidir. Daha karmaşık bir uygulama, bir harita veya yapılandırma kullanabilir veya (gerçekten süslü olmak istiyorsanız), sınıfların kendilerini kaydedebileceği bir tür kayıt defteri kullanabilir. Ancak, eğer sınıf sayısı azsa ve seyrek olarak değişiyorsa, şartlı kullanımda yanlış bir şey yoktur.

Gelecekte yeni bir alt sınıfa destek ekleme koşulunu genişletmek, kesinlikle açık / kapalı prensibinin ihlali anlamına gelecektir. "Doğru" çözüm, aynı arayüze sahip yeni bir fabrika oluşturmak olacaktır. Bununla birlikte, O / C prensibine bağlılık her zaman KISS ve YAGNI gibi diğer tasarım prensiplerine karşı tartılmalıdır.

Bununla birlikte, görüntülenen kod açıkça bir fabrika kavramını göstermek için tasarlanmış örnek kod ve başka bir şey değildir. Örneğin, örnekte olduğu gibi null değerini döndürmek gerçekten kötü bir stil olmakla birlikte, daha ayrıntılı hata işleme sadece noktayı gizleyecektir. Örnek kod, üretim kalite kodu değildir, olmasını beklememelisiniz.


Bir haritanın / yapılandırmanın / kayıt defterinin nasıl çalıştığını açıklayabilir misiniz?
Armon Safai


Kendi kendine kayıt yapan fabrikalar, AFAIK, kullanılmayan (yani odr kullanılan) global değişkenler takım zincirleri tarafından atıldığı için statik kütüphaneler içinde C ++ 'da imkansızdır.
void.pointer

@ArmonSafai bunu daha iyi anlamak için okudu goo.gl/RYuNSM
AZ_

2

Desenin kendisi Açık / Kapalı Prensibi'ni (OCP) ihlal etmez. Ancak deseni yanlış kullandığımızda OCP'yi ihlal ediyoruz.

Bu sorunun basit cevabı şöyledir:

  1. Fabrika Yöntemi Düzeni'ni kullanarak temel işlevlerinizi oluşturun .
  2. EXTEND kullanarak işlevselliğini Özet Fabrika Desen

Verilen örnekte, temel işlevleriniz üç şekli destekler: Daire, Dikdörtgen ve Kare. Gelecekte Üçgen, Pentagon ve Altıgen'i desteklemeniz gerektiğini varsayalım. Bunu yapmak için, OCP'yi ihlal etmeden, yeni şekillerinizi desteklemek için ek bir fabrika oluşturmalı (diyelim AdvancedShapeFactory) ve daha sonra ihtiyacınız olan şekilleri oluşturmak için hangi fabrikayı oluşturmanız gerektiğine karar vermek için AbstractFactory'yi kullanmalısınız .


Kendinden kayıtlı fabrikalar çözümünü çok tercih ediyorum (en iyi olan gerçek yapılandırılabilir bir IoC konteynerinin yokluğunda), aksi takdirde teklifinizden elde ettiğimiz şey temelde fabrika fabrikalarıdır ve o zaman işler çok karmaşık hale gelir.
Nom1fan

1

Soyut Fabrika modelinden bahsediyorsanız, karar verme işlemi genellikle Fabrikanın kendisinde değil, uygulama kodundadır. Bu somut fabrikayı örneklemek ve Fabrika tarafından üretilen nesneleri kullanacak olan müşteri koduna iletmek için hangi beton fabrikasını seçen koddur. Java örneğinin sonuna bakınız: https://en.wikipedia.org/wiki/Abstract_factory_pattern

Karar verme, ille de ifade anlamına gelmez if. Beton Fabrika tipini bir yapılandırma dosyasından okuyabilir, bir harita yapısından türetebilir vb.



Arayan ben, hangi somut sınıfı somutlaştırmak için karar verirsem, o zaman neden bir Soyut Fabrika ile uğraşıyorum?
Robert Harvey

Lütfen "arayanı" tanımlayın. Cevabımda açıkladığım gibi, global uygulama kodu var ve bir Fabrika kullanarak nesneleri ortaya çıkarmak için gereken kod var. İkincisi gerçekten örneğini beton sınıfının habersiz olması gerekir iken, diğer bazı bağlamsal kod vardır ... o ve yukarı yeni hakkında bilmek
guillaume31

0

Bu fabrika ile sınıf düzeyinde Aç-Kapat düşünürseniz, sisteminizde başka bir sınıf açıyorsunuz, örneğin bir Şekil alan ve alanı hesaplayan başka bir sınıfınız varsa (tipik örnek) bu sınıf OpenClose çünkü değişiklik yapmadan yeni şekil türleri için alanı hesaplayabilir. Daha sonra şekli çizen başka bir sınıfınız, N şeklini alan ve daha büyük olanı döndüren başka bir sınıfınız var ve genel olarak sisteminizdeki şekillerle ilgilenen diğer sınıfların Open-Close (en azından şekiller hakkında) olduğunu düşünebilirsiniz. Tasarıma bakıldığında, fabrika sistemin geri kalanının Open-Close olmasını ve fabrikanın kendisinin Open-Close DEĞİLDİR.

Elbette bu fabrikayı da bir tür dinamik yükleme yoluyla açıp kapatabilirsiniz ve tüm sisteminiz Aç-Kapat olabilir (örneğin, sınıf yolunda bir miktar kavanoz bırakarak yeni şekiller ekleyebilirsiniz). Bu ekstra karmaşıklığın, inşa ettiğiniz sisteme bağlı olarak değdiğini değerlendirmeniz gerekir, tüm sistemler takılabilir özelliklere ihtiyaç duymaz ve tüm sistemin tamamen Aç-Kapat olması gerekmez.


0

Açık-kapalı prensibi, Liskov ikame prensibi olarak, sınıf ağaçlarına, kalıtım hiyerarşilerine uygulanır. Örneğinizde fabrika sınıfı, başlattığı sınıfların soy ağacında değildir, bu nedenle bu kuralları ihlal edemez. GetShape (veya daha uygun bir şekilde adlandırılmış CreateShape) Shape base sınıfına uygulanmışsa bir ihlal olacaktır.


-2

Her şey onu nasıl uyguladığınıza bağlıdır. std::mapNesne oluşturan işlevlerde işlev işaretçileri tutmak için kullanabilirsiniz . O zaman açma / kapama prensibi ihlal edilmez. Veya anahtar / kasa.

Her neyse, fabrika desenini beğenmezseniz, her zaman bağımlılık enjeksiyonunu kullanabilirsiniz.


6
Anahtar / kasa şartlı koşullardan nasıl daha iyi? Örneğin, bazı DI kap uygulamalarında farklı uygulamaların kayıt defterine ihtiyacınız varsa, kodu veri olarak göstermek için bir harita / dict / tablo kullanmak iyidir. Ancak çoğu fabrika için aynı türden farklı geri aramalara sahip olmak gerekli değildir! Bunu neden önerdiğini pek anlamıyorum. Ayrıca, fabrika nesneleri açısından birçok DI konteyneri uygulanmaktadır, bu yüzden fabrikalar yerine DI'nin kullanılmasını önermek biraz dairesel görünmektedir.
amon

1
@ amon Fabrikada değil, diğer DI türlerini kullanmak istedim.
BЈови


1
Fabrikanız hangi işaretçiyi kullanacağınıza nasıl karar verecek? Sonunda bir karar vermelisin.
whatsisname

@ArmonSafai ???
15:15, BЈовић
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.