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?
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?
Yanıtlar:
Geleneksel nesne yönelimli bilgelik, if
ifadelerden 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 if
ifadelerden 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
.
if
s 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.
Ö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.
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:
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 .
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.
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.
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.
Her şey onu nasıl uyguladığınıza bağlıdır. std::map
Nesne 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.