代码之家  ›  专栏  ›  技术社区  ›  Navaneeth K N

装饰图案的替代品

  •  5
  • Navaneeth K N  · 技术社区  · 15 年前

    我觉得装饰图案最让人困惑。请考虑“head first design patterns book”中提供的示例。

    alt text

    所以得到一个 暗烤 用双摩卡和鞭子,你必须写作

    Beverage beverage2 = new DarkRoast();
    beverage2 = new Mocha(beverage2);                                       
    beverage2 = new Mocha(beverage2);                                       
    beverage2 = new Whip(beverage2); 
    

    我觉得这是不必要的。这是我的实现,

    interface Beverage
    {
       int Cost();
    }
    
    class DarkRoast : Beverage
    {
       /* .... */
    }
    
    class Mocha : Beverage
    {
       /* .... */
    }
    
    class Whip : Beverage
    {
       /* .... */
    }
    
    // here is the changed part
    class Order
    {
        List<Beverage> beverages = new List<Beverage> beverages();
        public void AddItem(Beverage b)
        {
            beverages.Add(b);
        }
    
        public int Cost()
        {
            int cost;
            foreach(Beverage b in beverages)
                cost += b.Cost();
        }
    }
    
    // use it like
    Order order = new Order();
    order.AddItem(new DarkRoast());
    order.AddItem(new Mocha());
    order.AddItem(new Mocha());
    order.AddItem(new Whip());
    int cost = order.Cost();
    

    在我看来,两者都是一样的。如果是,在这里使用decorator模式有什么好处?

    有什么想法吗?

    3 回复  |  直到 10 年前
        1
  •  16
  •   shahkalpesh    15 年前

    不,它们不一样。

    头一例有1杯加摩卡,鞭子,烤肉。您的示例有3种饮料。
    见本头一码。它在饮料的同一个实例上工作

    beverage2 = new Mocha(beverage2);                                       
    beverage2 = new DarkRoast(beverage2);                                       
    beverage2 = new Whip(beverage2);
    

    您的代码创建3个饮料(这意味着有人单独订购了3个东西)。
    在现实生活中,我想这不是饮料。这种饮料是加在上面的一种口味。

    装饰师的目的是——装饰。 .NET有textwriter和indentedtextwriter(我猜),它基本上采用了您的普通文本并对其应用了缩进。如果您考虑一下,它在某种程度上类似于Unix管道。

    输入->调整->调整输入->进一步调整->进一步调整输入。
    当前操作的输出成为下一个操作的输入。

    我不知道我是否解释得很好。

        2
  •  8
  •   Karl    15 年前

    装饰器模式的全部要点是通过对象组合而不是继承来添加职责。继承是静态的,obj。构图是动态的,更灵活。装饰的可能性是无限的。也可以在运行时取消装饰对象。

        3
  •  1
  •   Alberto Gutierrez    15 年前

    我认为你实际上代表的是完全不同的东西。

    在您的示例中,有一个接收饮料的对象调用顺序,在头一个示例中,它们只是用配料装饰饮料,这会导致以下主要问题。

    在您的订单代码中,您可以放置多个饮料,如果是,并且放置多个浇头,那么每个饮料的浇头是什么?