2

Head First 设计模式 - 装饰模式

 1 year ago
source link: https://tuncle.blog/Ch%2003%20the%20Decorator%20Pattern/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Head First 设计模式 - 装饰模式

发表于 2023-05-13
字数总计:694|阅读时长:2 分钟 | 阅读量:

装饰模式(Decorator Pattern) 提供了一个动态增加一个类功能的方法,主要实现思想是通过一个作为装饰者的类(Decorators)包裹被装饰类(Component)(装饰类以及被装饰类都有共同的基类),Decorators 会在 Component 类的某一个函数执行前或后进行一些操作,进而达到增加功能的作用。

装饰模式主要实现了 “代码应该对扩展功能开放而对于修改关闭” 的面向对象原则,它在增加新功能的前提下,不需要改动既有的代码,只需要增加新的 Decorators 并且包含既有的 Component 即可。

例如我们要计算一杯咖啡的价格,而这杯咖啡的价格还会受到额外的配料的影响,比如要加抹茶需要额外支付 0.2 元,加奶泡需要额外支付 0.3 元等。如果对各种配料都各自使用一个类来表示,则会存在较多的类需要维护,而且一旦配料发生变化等,还需要进行代码修改。而使用装饰模式则可以将原始的咖啡作为被装饰类,而所有的配料都是装饰类,则配料的更改仅需要增加或删除外部的装饰类即可。

装饰类及被装饰类基类

public abstract class Beverage
{
protected string description = "UnKnown Beverage";

public virtual string getDescription()
{
return description;
}

public abstract double Cost();
}
public abstract class CondimentDecorator : Beverage
{
protected Beverage beverage;

public CondimentDecorator(Beverage beverage)
{
this.beverage = beverage;
}
}
注意装饰类基类继承自被装饰类,并存有一个被装饰类的变量,因为装饰类需要在被装饰类操作的基础上进行一定额外的操作,所以它需要存有对被装饰类的引用,同时对外部而言调用者而言,它与被装饰类相同。

被装饰类实现

public class Espresso : Beverage
{
public Espresso()
{
description = "Espresson";
}

public override double Cost()
{
return 1.99;
}
}

装饰类实现

public class Soy : CondimentDecorator
{
public Soy(Beverage beverage) : base(beverage) { }

public override string getDescription()
{
return beverage.getDescription() + ", Soy";
}

public override double Cost()
{
return 0.30 + beverage.Cost();
}
}
public class Whip : CondimentDecorator
{
public Whip(Beverage beverage) : base(beverage) { }

public override string getDescription()
{
return beverage.getDescription() + ", Whip";
}

public override double Cost()
{
return 0.30 + beverage.Cost();
}
}
public class Mocha : CondimentDecorator
{
public Mocha(Beverage beverage) : base(beverage) { }

public override string getDescription()
{
return beverage.getDescription() + ", Mocha";
}

public override double Cost()
{
return 0.20 + beverage.Cost();
}
}

测试及结果

Espresso espresso = new Espresso();
Console.WriteLine(espresso.getDescription() + " Cost: " + espresso.Cost());

Beverage doubleMochaWhipEspresso = new Mocha(new Mocha(new Whip(espresso)));
Console.WriteLine(doubleMochaWhipEspresso.getDescription() + " Cost: " + doubleMochaWhipEspresso.Cost());

运行结果:

装饰模式运行结果

装饰模式运行结果

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK