병렬 계층-부분적으로 동일, 부분적으로 다릅니다


12

비슷한 질문이 많이 있습니다. 1 ,2 ,3 ,4 , 그러나이 질문에서는 그렇지 않은 것처럼 보이거나 솔루션이 최적으로 보이지도 않습니다.

다형성, 제네릭 및 믹스 인을 사용할 수 있다고 가정하면 일반적인 OOP 질문입니다. 사용되는 실제 언어는 OOP Javascript (Typescript)이지만 Java 또는 C ++에서 동일한 문제입니다.

나는 때때로 같은 행동 (인터페이스와 구현)을 공유하는 병렬 클래스 계층 구조를 가지고 있지만 때로는 그들 자신의 '보호 된'행동을 가지고있다. 다음과 같이 설명됩니다.

3 개의 병렬 클래스 계층 구조, 가운데 열에는 공통 부분이 표시되고 왼쪽 열에는 캔버스 계층 구조가 표시되고 오른쪽 열에는 SVG 계층 구조가 표시됩니다.

이것은 단지 설명을위한 것입니다 . 실제 클래스 다이어그램이 아닙니다. 그것을 읽으려면 :

  • 공통 계층 (센터)의 모든 것은 캔버스 (왼쪽)와 SVG (오른쪽) 계층 모두에서 공유됩니다. 공유한다는 것은 인터페이스와 구현을 모두 의미합니다.
  • 왼쪽 또는 오른쪽 열에 만있는 것은 해당 계층에 고유 한 동작 (방법 및 멤버)을 의미합니다. 예를 들면 다음과 같습니다.
    • 왼쪽 및 오른쪽 계층 구조 Viewee.validate()는 공통 계층 구조에서 단일 방법 ( )으로 표시되는 것과 동일한 유효성 검사 메커니즘을 정확히 사용합니다 .
    • 캔버스 계층 구조에만 메소드가 paint()있습니다. 이 메서드는 모든 자식에서 paint 메서드를 호출합니다.
    • SVG 계층 구조는의 addChild()메소드 를 재정의해야 Composite하지만 캔버스 계층 구조에서는 그렇지 않습니다.
  • 양면 계층 구조는 구성 할 수 없습니다. 공장은 그것을 보장합니다.

솔루션 I-상속 애타게

Fowler 's Tease Apart Inheritance는 두 가지 유사점 사이에 약간의 불일치가 있기 때문에 여기서 일을하지 않는 것 같습니다.

솔루션 II-믹스 인

이것은 내가 현재 생각할 수있는 유일한 것입니다. 두 계층은 개별적으로 개발되지만 각 수준에서 클래스는 클래스 계층의 일부가 아닌 공통 클래스를 혼합합니다. structural포크를 생략하면 다음과 같습니다.

다시 세 개의 열, 왼쪽 및 오른쪽 열은 병렬 계층 구조이며 각 클래스는 공통 클래스에서 고유합니다.  공통 클래스는 계층의 일부가 아닙니다

각 열은 자체 네임 스페이스에 있으므로 클래스 이름이 충돌하지 않습니다.

질문

이 방법으로 누구나 결함을 볼 수 있습니까? 누구든지 더 나은 솔루션을 생각할 수 있습니까?


추가

이것이 사용되는 샘플 코드는 다음과 같습니다. 네임 스페이스 svg는 다음으로 대체 될 수 있습니다 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 );

기본적으로 런타임 클라이언트는 Viewee 서브 클래스의 인스턴스 계층 구조를 구성합니다. 이렇게 :

레이어, 사각형, 스크롤러 등과 같은 객체의 계층 구조를 보여주는 이미지

이러한 모든 뷰어가 캔버스 계층 구조에서 paint()왔으며 각 뷰어에서 호출 할 수있는 계층 구조를 통과하여 렌더링됩니다 . 이들이 svg 계층에서 온 경우, 조회 대상자는 DOM에 자신을 추가하는 방법을 알고 있지만 paint()순회 는 없습니다 .



아마도 모든 기능을 갖춘 데코레이터 디자인 패턴을 사용해보십시오 (Erich Gamma et als, Design Patterns)?
Zon

조회수 란? "병행"은 명사 (형용사와 반대)로 무엇을 의미합니까?
Tulains Córdova

여러 상속이 있습니까?
Tulains Córdova

Canvas 또는 SVG 클래스에 공통 상태가 아닌 추가 상태 또는 데이터가 포함되어 있습니까? 수업은 어떻게 사용하나요? 이 계층 구조를 어떻게 사용할 수 있는지 보여주는 예제 코드를 보여줄 수 있습니까?
Euphoric

답변:


5

두 번째 방법은 인터페이스 분리 원칙에 따라 인터페이스를 더 잘 분리합니다.

그러나 Paintable 인터페이스를 추가하겠습니다.

나는 또한 일부 이름을 바꿀 것입니다. 혼란을 만들 필요가 없습니다.

// 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 {
}

인터페이스가이 경우 도움이 될 것 같습니다. 귀하의 답변이 다운 이유 인 이유를 알고 싶습니다.
umlcat

하지 downvoter하지만 이럴 지수 인터페이스는 좋은 패턴되지 않습니다
dagnelies

@arnaud "지수 인터페이스"는 무엇을 의미합니까?
Tulains Córdova

@ user61852 ... 음, 인터페이스가 많다고 가정 해 봅시다. "지수"는 실제로 잘못된 용어였으며 "곱하기"와 비슷합니다. 더 많은 "면"(복합, 시각적, 페인트 가능 ...)과 더 많은 "요소"(캔버스, svg ...)가 있다면 많은 인터페이스가 생길 것입니다.
dagnelies

@arnaud 요점은 있지만 최소한 유연한 디자인이 있으며 OP의 상속 악몽은 강제로 확장되지 않을 때 해결됩니다. 당신이 원하는 계층에 의해 강요되지 않으면 클래스를 확장하십시오.
Tulains Córdova

3

다형성, 제네릭 및 믹스 인을 사용할 수 있다고 가정하면 일반적인 OOP 질문입니다. 사용되는 실제 언어는 OOP Javascript (Typescript)이지만 Java 또는 C ++에서 동일한 문제입니다.

사실은 사실이 아닙니다. Typescript는 Java, 즉 구조적 타이핑에 비해 실질적인 이점이 있습니다. C ++에서 오리 형식 템플릿을 사용하여 비슷한 작업을 수행 할 수 있지만 훨씬 더 많은 노력이 필요합니다.

기본적으로 클래스를 정의하되 인터페이스를 확장하거나 정의하지 마십시오. 그런 다음 필요한 인터페이스를 정의하고 매개 변수로 사용하십시오. 그런 다음 객체가 해당 인터페이스와 일치 할 수 있으므로 미리 확장 할 필요가 없습니다. 각 함수는 정확하게 비트를 선언 할 수 있으며 클래스가 실제로 해당 인터페이스를 명시 적으로 확장하지는 않지만 최종 유형이 충족하면 컴파일러에서 패스를 제공합니다.

따라서 실제로 인터페이스 계층을 정의하고 어떤 클래스가 어떤 인터페이스를 확장해야하는지 정의 할 필요가 없습니다.

각 클래스를 정의하고 인터페이스를 잊어라-구조적 타이핑이 처리합니다.

예를 들면 다음과 같습니다.

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());

이것은 완전히 합법적 인 Typescript입니다. 소비 함수는 클래스 정의에 사용되는 기본 클래스 또는 인터페이스에 대해 알지 못하거나 단일 똥을 제공합니다.

클래스가 상속과 관련이 있는지 여부는 중요하지 않습니다. 인터페이스를 확장했는지는 중요하지 않습니다. 인터페이스를 매개 변수로 정의하기 만하면됩니다. 인터페이스를 충족하는 모든 클래스가 승인됩니다.


유망한 것처럼 들리지만 제안을 이해하지 못합니다 (죄송합니다. 아마 OOP 편견이 너무 많을 수 있습니다). 아마도 코드 예제를 공유 할 수 있습니까? 예를 들어, svg.Vieweecanvas.Viewee 는 모두 validate()메소드 가 필요합니다 (구현은 동일합니다). 만 svg.Viewee가 우선 필요 로 addChild () 에만 반면, canvas.Viewee가 필요 페인트를 () (호출되는 페인트 () 모든 아동에 -베이스의 회원 복합 클래스). 따라서 구조적 타이핑으로 이것을 실제로 시각화 할 수는 없습니다.
Izhaki

이 경우 완전히 중요하지 않은 모든 것을 고려하고 있습니다.
DeadMG

그래서 나는 아마 대답을 얻지 못했습니다. 자세히 설명하면 좋을 것입니다.
Izhaki

편집했습니다. 결론은 기본 클래스가 전혀 관련이 없으며 아무도 신경 쓰지 않는다는 것입니다. 그것들은 구현 세부 사항 일뿐입니다.
DeadMG

1
확인. 이것은 이해하기 시작했습니다. A) 오리 타이핑이 무엇인지 알고 있습니다. B) 왜 인터페이스 가이 답변의 중심에 있는지 잘 모르겠습니다. 클래스 고장은 일반적인 동작을 공유하기위한 것이므로 인터페이스를 무시해도 안전합니다. C) 귀하의 예에서 당신이 가지고 SVGViewee.addChild()있지만 CanvasViewee정확히 동일한 기능이 필요 하다고 가정하십시오 . 그래서 Composite에서 내재 된 것은 나에게 의미가있는 것 같습니다.
Izhaki

3

빠른 개요

해결 방법 3 : "병렬 클래스 계층 구조"소프트웨어 디자인 패턴은 친구입니다.

긴 답변

당신의 디자인은 옳았습니다. 최적화, 일부 클래스 또는 멤버가 제거 될 수 있지만 문제점을 해결하기 위해 적용하는 "병렬 계층 구조"아이디어는 옳습니다.

일반적으로 제어 계층에서 동일한 개념을 여러 번 처리했습니다.

잠시 후, 나는 다른 개발자들과 같은 솔루션을 끝냈습니다. 때때로 "병렬 계층"디자인 패턴 또는 "이중 계층"디자인 패턴이라고도합니다.

(1) 단일 클래스를 단일 계층의 클래스로 분할 한 적이 있습니까?

(2) 단일 클래스를 계층 구조없이 여러 클래스로 분할 한 적이 있습니까?

이러한 이전 솔루션을 별도로 적용한 경우 일부 문제를 해결할 수 있습니다.

그러나이 두 가지 솔루션을 동시에 결합하면 어떨까요?

그것들을 결합하면이 "디자인 패턴"을 얻게됩니다.

이행

이제 "Parallel Class Hierarchy"소프트웨어 디자인 패턴을 사례에 적용 해 보겠습니다.

현재 2 개 이상의 독립적 인 계층 구조가 있으며, 매우 유사하고 유사한 연관성 또는 purpouse, 유사한 특성 또는 메소드를 갖습니다.

중복 된 코드 나 멤버 ( "일관성")를 피하고 싶지만이 클래스의 차이점으로 인해이 클래스를 하나의 클래스로 직접 병합 할 수는 없습니다.

따라서 계층 구조는이 수치와 매우 유사하지만 둘 이상이 있습니다.

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

Figure 1

아직 인증되지 않은 디자인 패턴, 여러 유사 계층 구조가 단일 계층 구조로 구성되며 각 공유 또는 공통 클래스는 서브 클래 싱으로 확장됩니다.

이미 여러 계층을 처리하고 있기 때문에이 솔루션은 복잡하므로 복잡한 시나리오입니다.

1 루트 클래스

각 계층에는 공유 "루트"클래스가 있습니다.

귀하의 경우 각 계층마다 유사한 속성 및 유사한 메서드를 가질 수있는 독립적 인 "Composite"클래스가 있습니다.

해당 멤버 중 일부는 병합 할 수 있고 일부 멤버는 병합 할 수 없습니다.

따라서 개발자가 할 수있는 일은 기본 루트 클래스를 만들고 각 계층에 대해 동등한 경우를 하위 클래스로 만드는 것입니다.

그림 2에서 각 클래스가 네임 스페이스를 유지하는이 클래스에 대한 다이어그램을 볼 수 있습니다.

지금까지 멤버는 생략되었습니다.

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

Figure 2

아시다시피, 각 "복합"클래스는 더 이상 별도의 계층 구조가 아니라 단일 공유 또는 공통 계층 구조로 병합됩니다.

그런 다음 멤버, 같은 멤버를 슈퍼 클래스로, 다른 멤버를 각 기본 클래스로 추가 할 수 있습니다.

이미 알고 있듯이 "가상"또는 "오버로드"메소드는 기본 클래스에 정의되어 있지만 서브 클래스로 대체되었습니다. 그림 3처럼.

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

Figure 3

멤버가없는 클래스가있을 수 있으며 DONT 클래스를 제거하려는 유혹이있을 수 있습니다. 그것들은 "중공 클래스", "연산 클래스"및 다른 이름으로 불립니다.

2 서브 클래스

첫 번째 다이어그램으로 돌아 갑시다. 각 "Composite"클래스에는 각 계층 구조에 "Viewee"하위 클래스가 있습니다.

이 과정은 각 수업마다 반복됩니다. 그림 4보다 "Common :: Viewee"클래스는 "Common :: Composite"에서 유래하지만, 간략화를 위해 다이어그램에서 "Common :: Composite"클래스는 생략되었습니다.

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

Figure 4

"Canvas :: Viewee"및 "SVG :: Viewee"는 각각 "Composite"에서 내려 오는 것이 아니라 일반적인 "Common :: Viewee"에서 내려 오는 것입니다.

이제 회원을 추가 할 수 있습니다.

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

Figure 5

3 프로세스 반복

프로세스는 각 클래스에 대해 "Canvas :: Visual"은 "Canvas :: Viewee"에서 하강하지 않고 "Commons :: Visual"에서 buit, "Canvas :: Structural"은 "Canvas :: Viewee"에서 하강하지 않습니다. ", Commons :: Structural"등의 buit.

4 3D 계층 다이어그램

상단 레이어에는 "공통"계층 구조가 있고 하단 레이어에는 각 추가 계층 구조가있는 여러 레이어가 포함 된 3D 다이어그램이 완성됩니다.

이것과 비슷한 원래 독립 클래스 계층 (그림 6) :

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

Figure 6

일부 클래스는 생략하고 전체 "Canvas"계층 구조는 간단하게 생략했습니다.

최종 통합 클래스 계층 구조는 다음과 유사 할 수 있습니다.

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

일부 클래스는 생략하고 전체 "Canvas"클래스는 간략하게 생략하지만 "SVG"클래스와 유사합니다.

"공통"클래스는 3D 다이어그램의 단일 계층, 다른 계층의 "SVG"클래스 및 세 번째 계층의 "캔버스"클래스로 표현 될 수 있습니다.

각 계층이 첫 번째 계층과 관련되어 있는지 확인하십시오. 각 계층에는 "공통"계층 구조의 상위 클래스가 있습니다.

코드 구현은 프로그래밍 언어가 지원하는 것에 따라 인터페이스 상속, 클래스 상속 또는 "mixins"를 사용해야 할 수 있습니다.

요약

어떤 프로그래밍 솔루션이든 최적화를 서두르지 마십시오. 최적화는 매우 중요하지만 최적화가 잘못되면 원래 문제보다 더 큰 문제가 될 수 있습니다.

"솔루션 1"또는 "솔루션 2"를 적용하지 않는 것이 좋습니다.

"솔루션 1"에서는 상속이 각 경우에 필요하기 때문에 적용되지 않습니다.

"솔루션 2", "Mixins"가 적용될 수 있지만 클래스와 계층 구조를 디자인 한 후에 적용 할 수 있습니다.

믹스 인은 인터페이스 기반 상속 또는 클래스 기반 다중 상속의 대안입니다.

내가 제안한 솔루션 3은 때때로 "병렬 계층 구조"디자인 패턴 또는 "이중 계층 구조"디자인 패턴이라고합니다.

많은 개발자 / 디자이너는 이에 동의하지 않으며 존재하지 않아야한다고 생각합니다. 그러나 본인과 다른 개발자는 귀하의 질문 중 하나와 같은 문제에 대한 일반적인 솔루션으로 사용했습니다.

또 다른 누락 된 것. 이전 솔루션에서 주된 문제는 "mixins"또는 "interfaces"를 사용하는 것이 아니라 클래스 모델을 세분화하고 나중에 기존 프로그래밍 언어 기능을 사용하는 것이 었습니다.


매우 철저한 답변에 감사드립니다. 나는 그것을 잘 이해했다고 생각하므로 이것을 물어 보자. canvas.viewee모든 자손은이라는 메소드가 필요하다 paint(). 어느 쪽도 아니 commonsvg클래스를 필요가 없습니다. 그러나 솔루션에서 계층 구조에 common없는, canvas또는 svg내 솔루션 2에이 정확히 어떻게 같은 paint()모든 서브 클래스에서 끝 canvas.viewee이 상속 재산이없는 경우?
Izhaki

@Izhaki 답변에 몇 가지 버그가 있으면 죄송합니다. 그런 다음 paint()"canvas :: viewee"로 이동하거나 선언해야합니다. 일반적인 패턴 아이디어는 유지되지만 일부 멤버는 이동하거나 변경해야 할 수도 있습니다.
umlcat

자, 서브 클래스에서 파생되는 것이 없다면 어떻게 서브 클래스가 그것을 얻 canvas::viewee습니까?
Izhaki

도구를 사용하여 아스키 아트를 만들었습니까? (가치가 실제로 가치가 있는지 점이 실제로 도움이 될지 확실하지 않습니다.)
Aaron Hall

1

C ++의 이중 상속 계층 처리를위한 디자인 패턴 이라는 제목의 기사 에서 , Uncle Bob은 Stairway to Heaven 이라는 솔루션을 제시합니다 . 의도가 명시되어 있습니다.

이 패턴은 주어진 계층 구조를 전체적으로 다른 클래스에 적용해야 할 때 필요한 상속 관계 네트워크를 설명합니다.

그리고 다이어그램은 다음을 제공했습니다.

두 개의 병렬 상속 구조를 가진 클래스 다이어그램. 오른쪽의 각 클래스는 왼쪽의 트윈 클래스에서 사실상 고유합니다.  왼쪽 계층도 가상 상속을 기반으로합니다.

솔루션 2에는 가상 상속이 없지만 계단과 천국 패턴이 일치합니다 . 따라서 솔루션 2는이 문제에 합리적으로 보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.