Paralel hiyerarşiler - kısmen aynı, kısmen farklı


12

Orada benzer birkaç soru var 1 ,2 ,3 ,4 , ama olmayan bu soru tam olarak böyle görünüyor, ne de çözümler optimal görünüyor.

Bu, polimorfizm, jenerikler ve karışımların mevcut olduğu varsayılarak genel bir OOP sorusudur. Kullanılacak gerçek dil OOP Javascript'tir (Typescript), ancak Java veya C ++ ile aynı sorun.

Bazen aynı davranışı (arabirim ve uygulama) paylaşan paralel sınıf hiyerarşileri var, ancak bazen her birinin kendi 'korumalı' davranışı var. Resimli:

3 paralel sınıf hiyerarşisi, orta sütun ortak bölümleri gösterir, sol sütun tuval hiyerarşisidir ve sağ sütun SVG hiyerarşisini gösterir

Bu yalnızca açıklama amaçlıdır ; gerçek sınıf diyagramı değil. Okumak için:

  • Ortak hiyerarşideki (ortadaki) her şey Kanvas (sol) ve SVG (sağ) hiyerarşileri arasında paylaşılır. Paylaşımla hem arayüz hem de uygulama demek istiyorum.
  • Yalnızca sol veya sağ sütunlardaki herhangi bir şey, o hiyerarşiye özgü bir davranış (yöntemler ve üyeler) anlamına gelir. Örneğin:
    • Hem sol hem de sağ hiyerarşiler Viewee.validate(), ortak hiyerarşide tek bir yöntem ( ) olarak gösterilenle aynı doğrulama mekanizmalarını kullanır .
    • Yalnızca tuval hiyerarşisinin bir yöntemi vardır paint(). Bu yöntem tüm çocuklarda boya yöntemini çağırır.
    • SVG hiyerarşisinin addChild()yöntemini geçersiz kılması gerekir Composite, ancak tuval hiyerarşisinde durum böyle değildir.
  • İki yan hiyerarşiden gelen yapılar karıştırılamaz. Bir fabrika bunu sağlar.

Çözüm I - Ayrı Miras Tease

Fowler'ın Tease Apart Mirası burada işi yapmıyor gibi görünüyor, çünkü iki paralellik arasında bir tutarsızlık var.

Çözelti II - Karışımlar

Şu anda düşünebildiğim tek kişi bu. İki hiyerarşi ayrı ayrı gelişir, ancak her düzeyde sınıflar, sınıf hiyerarşisinin bir parçası olmayan ortak sınıfı karıştırır. structuralÇatalı atlamak, şöyle görünecektir:

Yine üç sütun, sol ve sağ sütunlar paralel hiyerarşilerdir, burada her sınıf aynı zamanda ortak bir sınıftan içseldir.  Ortak sınıflar bir hiyerarşinin parçası değildir

Her sütunun kendi ad alanında olacağını, bu nedenle sınıf adlarının çakışmayacağını unutmayın.

Soru

Bu yaklaşımla ilgili hataları görebilen var mı? Herkes daha iyi bir çözüm düşünebilir mi?


ek

İşte bunun nasıl kullanılacağı ile ilgili bazı örnek kod. Ad alanı svgaşağıdakilerle değiştirilebilir canvas:

var iView        = document.getElementById( 'view' ),
    iKandinsky   = new svg.Kandinsky(),
    iEpigone     = new svg.Epigone(),
    iTonyBlair   = new svg.TonyBlair( iView, iKandinsky ),
    iLayer       = new svg.Layer(),
    iZoomer      = new svg.Zoomer(),
    iFace        = new svg.Rectangle( new Rect( 20, 20, 100, 60) ),
    iEyeL        = new svg.Rectangle( new Rect( 20, 20, 20, 20) ),
    iEyeR        = new svg.Rectangle( new Rect( 60, 20, 20, 20) );

iKandinsky.setContext( iTonyBlair.canvas.getContext( '2d' ) );
iEpigone.setContext( iTonyBlair.canvas.getContext( '2d' ) );

iFace.addChildren( iEyeL, iEyeR );
iZoomer.setZoom( new Point( 2, 2 ) );
iZoomer.addChild( iFace );
iLayer.addChild( iZoomer );
iTonyBlair.setContent( iLayer );

Esasen, çalışma zamanı istemcilerinde Viewee alt sınıflarının örnek hiyerarşisini oluşturur; şöyle:

Katman, doğrultma, kaydırma çubuğu gibi nesnelerin hiyerarşisini gösteren bir resim.

Tüm bu görüntüleyicilerin tuval hiyerarşisinden olduğunu, paint()her bir görüntüleyicinin çağırabileceği hiyerarşiyi geçerek oluşturulduğunu varsayalım. Svg hiyerarşisinden geldiyse, görüntüleyenler kendilerini DOM'a nasıl ekleyeceklerini bilirler, ancak paint()geçiş yoktur.



Belki de tam özellikli Dekoratör tasarım desenini (Erich Gamma ve diğerleri, Tasarım Desenleri) deneyebilirsiniz?
Zon

Görüntüleyen nedir? "Paralel" bir isim olarak ne anlama gelir (sıfat yerine)?
Tulains Córdova

Birden fazla mirasınız var mı?
Tulains Córdova

Canvas veya SVG sınıfları, Ortak olmayan ek durum veya veriler içeriyor mu? Sınıfları nasıl kullanıyorsunuz? Bu aramaların nasıl kullanılabileceğini gösteren bazı örnek kodlar gösterebilir misiniz?
Euphoric

Yanıtlar:


5

İkinci yaklaşım, arayüz ayırma prensibini takip ederek arayüzleri daha iyi ayırır.

Ancak, bir Boyanabilir arayüz ekleyeceğim.

Bazı isimleri de değiştirirdim. Karışıklık yaratmaya gerek yok:

// common

public interface IComposite {
    public void addChild(Composite e);
}

public interface IViewee extends IComposite{
    public void validate();
    public List<IBound> getAbsoluteBouns();
}

public interface IVisual {
    public List<IBound> getBounds();
}

public interface IRec {
}

public interface IPaintable {
    public void paint();
}

// canvas

public interface ICanvasViewee extends IViewee, IPaintable {
}

public interface ICanvasVisual extends IViewee, IVisual {
}

public interface ICanvasRect extends ICanvasVisual, IRec {
}


// SVG

public interface ISVGViewee extends IViewee {
    public void element();
}

public interface ISVGVisual extends IVisual, ISVGViewee {
}

public interface ISVGRect extends ISVGVisual, IRect {
}

Bence Arayüzler bu duruma yardımcı olabilir. Cevabınızın neden reddedildiğini bilmek istiyorum.
umlcat

değil ama IMHO üstel arayüzler iyi bir model değil
dagnelies

@arnaud "üstel arayüzler" ile ne demek istiyorsun?
Tulains Córdova

@ user61852 ... diyelim ki çok fazla arayüz var. "üstel" aslında yanlış bir terimdi, daha çok "çarpımsal" gibi. Daha fazla "faset" (kompozit, görsel, boyanabilir ...) ve daha fazla "element" (tuval, svg ...) olsaydı, çok fazla arayüze sahip olursun.
dagnelies

@arnaud Bir noktanız var ama en azından önceden esnek bir tasarım var ve OP'nin miras kabusu, uzatmaya zorlanmadığınızda çözülecekti. Eğer bir hiyerarşi zorlamak istemiyorsanız ve istemiyorsanız bir sınıfı genişletirsiniz.
Tulains Córdova

3

Bu, polimorfizm, jenerikler ve karışımların mevcut olduğu varsayılarak genel bir OOP sorusudur. Kullanılacak gerçek dil OOP Javascript'tir (Typescript), ancak Java veya C ++ ile aynı sorun.

Aslında bu hiç de doğru değil. Daktilo yazımının Java, yapısal yazımlara göre önemli bir avantajı vardır. Ördekle yazılmış şablonlarla C ++ 'da benzer bir şey yapabilirsiniz, ancak çok daha fazla çaba.

Temel olarak, sınıflarınızı tanımlayın, ancak herhangi bir arabirimi genişletme veya tanımlama zahmetine girmeyin. Daha sonra ihtiyacınız olan arayüzü tanımlayın ve bir parametre olarak alın. Ardından, nesneler bu arayüzle eşleşebilir - önceden genişletmek için bilmeleri gerekmez. Her işlev tam olarak ve sadece bir bok verdikleri bitleri bildirebilir ve sınıflar bu arabirimleri açıkça genişletmese bile, derleyici son türle karşılaşırsa size bir geçiş verir.

Bu, bir arayüz hiyerarşisini gerçekten tanımlama ve hangi sınıfların hangi arayüzleri genişletmesi gerektiğini tanımlama ihtiyacından kurtarır.

Her sınıfı tanımlayın ve arayüzleri unutun - yapısal yazım onunla ilgilenecektir.

Örneğin:

class SVGViewee {
    validate() { /* stuff */ }
    addChild(svg: SVG) { /* stuff */ }
}
class CanvasViewee {
    validate() { /* stuff */ }
    paint() { /* stuff */ }
}
interface SVG {
    addChild: { (svg: SVG): void };
}
f(viewee: { validate: { (): boolean }; }) {
    viewee.validate();
}
g(svg: SVG) {
    svg.addChild(svg);
}
h(canvas: { paint: { (): void }; }) {
    canvas.paint();
}
f(SVGViewee());
f(CanvasViewee());
g(SVGViewee());
h(CanvasViewee());

Bu tamamen meşru Daktilodur. Tüketici fonksiyonlarının sınıfların tanımında kullanılan temel sınıflar veya arayüzler hakkında tek bir bok bilmediğine veya tek bir bok vermediğine dikkat edin.

Sınıfların kalıtımla ilgili olup olmadığı önemli değildir. Arayüzünüzü genişletip genişletmedikleri önemli değil. Arayüzü parametre olarak tanımlamanız yeterlidir ve işiniz bitti - onu karşılayan tüm sınıflar kabul edilir.


Kulağa umut verici geliyor, ancak teklifi gerçekten anlamıyorum (üzgünüm, muhtemelen çok fazla OOP önyargısı). Belki bazı kod örneklerini paylaşabilirsiniz? Örneğin, her iki svg.Viewee ve canvas.Viewee bir ihtiyaç validate()(her ikisi için de aynıdır uygulaması olan) yöntemi; Sonra sadece svg.Viewee geçersiz kılmak gerekir addChild () sadece iken, canvas.Viewee ihtiyacı boya () (aramalar hangi boya () tüm çocuklar üzerinde - baz üyesisiniz Kompozit sınıfın). Bu yüzden bunu yapısal yazımla gerçekten görselleştiremiyorum.
Izhaki

Bu durumda tamamen önemli olmayan bir sürü şeyi düşünüyorsunuz.
DeadMG

Bu yüzden muhtemelen cevabı alamadım. Eğer detaylandırırsanız iyi olur.
Izhaki

Bir düzenleme yaptım. Sonuç olarak, temel sınıflar kesinlikle alakasızdır ve kimse onları umursamaz. Bunlar yalnızca bir uygulama detayıdır.
DeadMG

1
TAMAM. Bu anlamlı olmaya başlıyor. A) Ördek yazmanın ne olduğunu biliyorum. B) Bu cevapta arayüzlerin neden bu kadar merkezi olduğundan emin değilim - sınıf dökümü ortak davranışları paylaşmak içindir, şimdilik arayüzleri güvenle göz ardı edebilirsiniz. C) Örneğinizde sahip olduğunuzu söyleyin SVGViewee.addChild(), ancak CanvasVieweeaynı özelliğe de ihtiyacınız var. Öyleyse bana her ikisi de Kompozit'in doğasında olan mantıklı geliyor?
Izhaki

3

Hızlı Genel Bakış

Çözüm 3: "Paralel Sınıf Hiyerarşisi" Yazılım Tasarım Düzeni arkadaşın.

Uzun Genişletilmiş Cevap

Tasarımınız DOĞRU BAŞLADI. Optimize edilebilir, bazı sınıflar veya üyeler kaldırılabilir, ancak bir sorunu çözmek için uyguladığınız "paralel hiyerarşi" fikri SAĞDIR.

Aynı kavramla, genellikle kontrol hiyerarşilerinde birçok kez ilgilenin.

Bir süre sonra, bazen "Paralel Hiyerarşi" Tasarım Deseni veya "İkili Hiyerarşi" Tasarım Deseni olarak adlandırılan AYNI ÇÖZÜMÜ DİĞER GELİŞTİRİCİLERDEN YAPIYORUM.

(1) Hiç tek bir sınıfı tek bir sınıf hiyerarşisine böldünüz mü?

(2) Tek bir sınıfı hiyerarşi olmadan birkaç sınıfa ayırdınız mı?

Bu önceki çözümleri ayrı olarak uyguladıysanız, bazı sorunları çözmenin bir yoludur.

Ancak, bu iki çözümü aynı anda birleştirirsek ne olur?

Onları birleştirin, ve bu "Tasarım Deseni" alacak.

uygulama

Şimdi, "Paralel Sınıf Hiyerarşisi" Yazılım Tasarım Desenini kendi durumunuza uygulayalım.

Şu anda çok benzer, benzer ilişkilendirmelere veya amaçlara sahip, benzer özelliklere veya yöntemlere sahip 2 veya daha fazla bağımsız sınıf hiyerarşisine sahipsiniz.

Yinelenen kod veya üyelere ("tutarlılık") sahip olmaktan kaçınmak istersiniz, ancak aralarındaki farklar nedeniyle bu sınıfları doğrudan tek bir sınıfta birleştiremezsiniz.

Yani, hiyerarşileriniz bu rakama çok benziyor, ancak yine de birden fazla var:

................................................
...............+----------------+...............
...............|     Common::   |...............
...............|    Composite   |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
...............+-------+--------+...............
...............|     Common::   |...............
...............|     Viewee     |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Common::   |........|     Common::   |..
..|     Visual     |........|   Structural   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 1

Bu, henüz belgelendirilmemiş, Tasarım Deseni, AŞIRI BENZER HİZMETLER, BİRLEŞTİRİLMİŞTİR, TEK BİR HEDEFE GİRİLİR ve her bir ortak veya ortak sınıf alt sınıflandırma ile genişletilir.

Bu çözümün karmaşık olduğunu unutmayın, çünkü zaten birkaç hiyerarşiyle uğraşıyorsunuz, bu nedenle karmaşık bir senaryodur.

1 Kök Sınıfı

Her hiyerarşide paylaşılan bir "kök" sınıfı vardır.

Sizin durumunuzda, her bir hiyerarşi için bazı benzer özelliklere ve bazı benzer yöntemlere sahip olabilen bağımsız bir "Kompozit" sınıfı vardır.

Bu üyelerden bazıları birleştirilebilir, bu üyelerin bazıları birleştirilemez.

Yani, bir geliştiricinin yapabileceği şey, bir temel kök sınıfı yapmak ve her hiyerarşi için eşdeğer durumu alt sınıf yapmaktır.

Şekil 2'de, sadece bu sınıf için, her sınıfın ad alanını koruduğu bir diyagram görebilirsiniz.

Üyeler şimdiye kadar çıkarıldı.

................................................
...............+-------+--------+...............
...............|     Common::   |...............
...............|    Composite   |...............
...............+----------------+...............
...............|      ...       |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|    Composite   |........|    Composite   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 2

Dikkat edeceğiniz gibi, her "Kompozit" sınıf artık ayrı bir hiyerarşide değil, tek bir paylaşılan veya ortak hiyerarşide birleştiriliyor.

Sonra, aynı olan üyeleri, üst sınıfa ve farklı olanları her temel sınıfa ekleyelim.

Ve bildiğiniz gibi, temel sınıfta "sanal" veya "aşırı yüklenmiş" yöntemler tanımlanır, ancak alt sınıflarda değiştirilir. Şekil 3 gibi.

................................................
.............+--------------------+.............
.............|       Common::     |.............
.............|      Composite     |.............
.............+--------------------+.............
.............| [+] void AddChild()|.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|    Composite   |........|    Composite   |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 3

Bazı üyeleri olmayan bazı sınıflar olduğunu ve bu sınıfları kaldırmak için cazip olabilir DONT unutmayın. Bunlara "İçi Boş Sınıflar", "Sayısal Sınıflar" ve diğer isimler denir.

2 Alt Sınıflar

İlk şemaya geri dönelim. Her "Kompozit" sınıf, her hiyerarşide bir "Viewee" alt sınıfına sahipti.

İşlem her sınıf için tekrarlanır. Şekil 4'ten ziyade, "Common :: Viewee" sınıfı "Common :: Composite" ten aşağı iner, ancak basitlik için "Common :: Composite" sınıfı diyagramdan çıkarılır.

................................................
.............+--------------------+.............
.............|       Common::     |.............
.............|       Viewee       |.............
.............+--------------------+.............
.............|        ...         |.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..|     Canvas::   |........|      SVG::     |..
..|     Viewee     |........|     Viewee     |..
..+----------------+........+----------------+..
..|      ...       |........|      ...       |..
..+----------------+........+----------------+..
................................................

Figure 4

"Canvas :: Viewee" ve "SVG :: Viewee" ifadelerinin, daha uzun olan ilgili "Kompozit" tan değil, ortak "Common :: Viewee" den indiğini göreceksiniz.

Şimdi üyeleri ekleyebilirsiniz.

......................................................
.........+------------------------------+.............
.........|            Common::          |.............
.........|            Viewee            |.............
.........+------------------------------+.............
.........| [+] bool Validate()          |.............
.........| [+] Rect GetAbsoluteBounds() |.............
.........+-------------+----------------+.............
.......................|..............................
.......................^..............................
....................../.\.............................
.....................+-+-+............................
.......................|..............................
..........+------------+----------------+.............
..........|.............................|.............
..+-------+---------+........+----------+----------+..
..|      Canvas::   |........|         SVG::       |..
..|      Viewee     |........|        Viewee       |..
..+-----------------+........+---------------------+..
..|                 |........| [+] Viewee Element  |..
..+-----------------+........+---------------------+..
..| [+] void Paint()|........| [+] void addChild() |..
..+-----------------+........+---------------------+..
......................................................

Figure 5

3 İşlemi Tekrarlayın

Süreç devam edecek, her sınıf için "Canvas :: Visual" "Canvas :: Viewee" den aşağı inmeyecek, "Commons :: Visual" dan, "Canvas :: Structural" dan aşağı inmeyecektir "Canvas :: Viewee "," Commons :: Structural "dan buit.

4 3D Hiyerarşi Şeması

Birkaç katman, üst katman, "Ortak" hiyerarşisi ve alt katmanlar, her ek hiyerarşiye sahip bir 3D diyagramı almayı bitireceksiniz.

Buna benzer bir şeyin olduğu orijinal bağımsız sınıf hiyerarşileriniz (Şekil 6):

.................................................
..+-----------------+.......+-----------------+..
..|      Common::   |.......|       SVG::     |..
..|     Composite   |.......|     Composite   |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|      Viewee     |.......|      Viewee     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|      Visual     |.......|      Visual     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..|      Common::   |.......|       SVG::     |..
..|       Rect      |.......|       Rect      |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+-----------------+.......+-----------------+..
.................................................

Figure 6

Bazı sınıfların atlandığını ve tüm "Canvas" hiyerarşisinin basit bir şekilde atlandığını unutmayın.

Son entegre sınıf hiyerarşisi buna benzer bir şey olabilir:

.................................................
..+-----------------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|     Composite   |...\+..|     Composite   |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|      Viewee     |...\+..|      Viewee     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|      Visual     |...\+..|      Visual     |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..|      Common::   +--<.+--+       SVG::     |..
..|       Rect      |...\+..|       Rect      |..
..+-----------------+.......+-----------------+..
..|       ...       |.......|       ...       |..
..+-----------------+.......+-----------------+..
.................................................
Figure 7

Bazı sınıfların atlandığını ve tüm "Canvas" sınıflarının basit bir şekilde atlandığını, ancak "SVG" sınıflarına benzer olacağını unutmayın.

"Ortak" sınıflar, 3B diyagramın tek bir katmanı, başka bir katmandaki "SVG" sınıfları ve üçüncü bir katmandaki "Canvas" sınıfları olarak temsil edilebilir.

Her katmanın, her sınıfın "Ortak" hiyerarşisinin üst sınıfına sahip olduğu ilk katmanla ilişkili olup olmadığını kontrol edin.

Kod uygulaması, Programlama Dilinizin desteklediğine bağlı olarak, arabirim devralma, sınıf devralma veya "mixins" öğelerinin kullanılmasını gerektirebilir.

özet

Herhangi bir programlama çözümü olarak, optimizasyona acele etmeyin, optimizasyon çok önemlidir, ancak kötü bir optimizasyon, orijinal problemden daha büyük bir sorun haline gelebilir.

"Çözüm 1" veya "Çözüm 2" nin uygulanmasını önermiyorum.

"Çözüm 1" de geçerli değildir, çünkü her durumda kalıtım gereklidir.

"Çözüm 2", "Mixins" uygulanabilir, ancak sınıflar ve hiyerarşiler tasarlandıktan sonra uygulanabilir.

Mixins, arayüz tabanlı miras veya sınıf tabanlı çoklu miras için bir alternatiftir.

Benim önerdiğim Çözüm 3, bazen "Paralel Hiyerarşi" Tasarım Deseni veya "Çift Hiyerarşi" Tasarım Deseni olarak adlandırılır.

Birçok geliştirici / tasarımcı buna katılmayacak ve var olmaması gerektiğine inanacak. Ancak, miself ve diğer geliştiriciler tarafından, sorunuz gibi sorunlara ortak bir çözüm olarak kullandım.

Başka bir eksik şey. Önceki çözümlerinizde ana sorun, "mixins" veya "arayüzler" kullanmak için daha uygun değil, ilk olarak sınıflarınızın modelini düzeltmek ve daha sonra mevcut bir Programlama Dili özelliğini kullanmaktı.


Çok kapsamlı cevap için teşekkürler. Sanırım bunu iyi anladım, bu yüzden şunu sormama izin verin: canvas.vieweeve tüm torunları denilen bir yönteme ihtiyaç duyuyor paint(). Ne sınıfların commonne de svgsınıfların buna ihtiyacı yoktur. Ama sizin çözümünüzde, hiyerarşi benim çözümüm 2'de common, değil canvasveya svgbenim gibi. Peki , orada kalıtım yoksa paint()tüm alt sınıflarda tam olarak nasıl sonuçlanır canvas.viewee?
Izhaki

@Izhaki Cevabımda birkaç hata varsa özür dilerim. Daha sonra paint()"canvas :: viewee" de taşınmalı veya bildirilmelidir. Genel kalıp fikri kalır, ancak bazı üyelerin taşınması veya değiştirilmesi gerekebilir.
umlcat

Tamam, öyleyse alt sınıflar bunu nasıl elde eder canvas::viewee?
Izhaki

ASCII sanatınızı oluşturmak için bir araç kullandınız mı? (Noktaların gerçekten değdiğine yardımcı olduğundan emin değilim.)
Aaron Hall

1

C ++ 'da İkili Kalıtım Hiyerarşileri ile Mücadele için Tasarım Desenleri başlıklı bir makalede Bob Amca, Stairway to Heaven adlı bir çözüm sunuyor . Niyet belirtildi:

Bu model, belirli bir hiyerarşinin bütünüyle başka bir sınıfa uyarlanması gerektiğinde gereken miras ilişkileri ağını açıklar.

Ve şema sağladı:

Sağdaki her sınıfın da soldaki ikiz sınıfından neredeyse içsel olduğu iki paralel miras yapısına sahip bir sınıf diyagramı.  Sol hiyerarşi de tamamen sanal kalıtım üzerine kuruludur

Çözüm 2'de sanal kalıtım olmasa da, Stairway to Heaven desenine çok uygundur. Böylece çözüm 2 bu sorun için makul görünmektedir.

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.