2016-07-29 4 views
0

저는 처음으로 디자인 패턴을 고수하려고합니다.하지만 C# 대신 Java 대신 예제를 코딩하고 있습니다. 데코레이터 패턴을 코딩했는데 수정 방법을 알 수없는 이상한 버그가 있습니다. 줄 1은 예상대로 실행되고 설명은 "Dark Roast"이지만 줄 2는 "Dark Roast, Mocha"대신 "unknown beverage"로 설명을 변경합니다. 이 동작을 어떻게 수정합니까?C# 상속이 예상대로 동작하지 않습니다.

메인 프로그램 :

beverage = new DarkRoast(); 
beverage = new Mocha(beverage); 
beverage = new Mocha(beverage); 
Console.WriteLine(beverage.Description + " $" + beverage.Cost); 

데코레이터 코드 :

namespace DecoratorPattern 
{ 
    public abstract class Beverage 
    { 
     public abstract double Cost { get; } 

     public string Description { get; set; } = "unknown beverage"; 
    } 

    public class DarkRoast : Beverage 
    { 
     public DarkRoast() 
     { 
      Description = "Dark Roast"; 
     } 

     public override double Cost => .99; 
    } 

    public abstract class CondimentDecorator : Beverage 
    { 
     public abstract string Description { get; } 
    } 

    public class Mocha : CondimentDecorator 
    { 
     Beverage beverage; 

     public Mocha(Beverage beverage) 
     { 
      this.beverage = beverage; 
     } 

     public override string Description 
     { 
      get { return beverage.Description + ", Mocha"; } 
     } 

     public override double Cost => .20 + beverage.Cost; 
    } 
} 
+0

메인 프로그램 d 컴파일 할 필요가 없습니다. – Ian

답변

3

당신은 Beverage 클래스 virtualDescription 속성을 표시하지 않았습니다. 따라서 변수 beverageBeverage 인 경우 Description 속성은 항상 거기에서 읽습니다. 값은 항상 알 수없는 기본 값입니다.

CondimentDecorator 클래스에서 abstract 선언을 제거하고 virtual을 기본 클래스에 추가하면 무시가 작동합니다.

+0

완벽한, 고마워요! 아이디어를 구현하기 위해 클래스를 구현하는 클래스를 강제로 만드는 것이기 때문에 나는 그것을 추상적으로 유지했다. 문제를 지적하고 설명해 주셔서 감사합니다. – haosmark

+0

그런 다음'Abstract' 속성을 제거하면'CondimentDecorator' 클래스의 요점은 무엇입니까? 그렇다면'CondimentDecorator'를 완전히 제거하고'Beverage'에서 직접'Mocha'를 상속받을 수 있으며 여전히 같은 결과를 얻습니다. –

1

당신은 당신이 예상 된 결과를 얻을 것이다 CondimentDecorator에 유형을 변경하는 경우는, 그 위에 새 속성 Description을, CondimentDecorator 원래 Description 속성을 숨기고 있습니다.

이것은 당신이 기대하는 값을 출력한다 :

var result = (CondimentDecorator) beverage; 
Console.WriteLine(result.Description); 

당신은 돈을 추상 또는 가상으로 기준을 변경하고이 시점에서 상속 클래스에 당신을

public abstract class Beverage 
{ 
    public abstract double Cost { get; } 

    public virtual Description { get; set; } = "unknown beverage"; 
} 

을 재정의 할 필요가 추가 데코레이터 클래스가 필요하지 않습니다. 기본 객체의 메소드를 오버라이드합니다.

public class Mocha : Beverage 
{ 
    Beverage beverage; 

    public Mocha(Beverage beverage) 
    { 
     this.beverage = beverage; 
    } 

    public override string Description 
    { 
     get { return beverage.Description + ", Mocha"; } 
     set { throw InvalidOperationException("Cannot Set Value of Decorator"); } 
    } 

    public override double Cost => .20 + beverage.Cost; 
} 
관련 문제