装饰器模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象自身的情况下,动态地向对象添加新功能。它通过将功能附加到对象的方式来增强其行为,提供了一种灵活的替代方案来使用子类扩展功能。
主要组成部分:
-
抽象构件(Component):
- 定义一个接口或抽象类,声明了要装饰的对象的基本功能。
-
具体构件(ConcreteComponent):
- 实现抽象构件的具体类,是被装饰的原始对象。
-
装饰器(Decorator):
- 持有一个抽象构件的引用,并实现抽象构件的接口,用于扩展功能。
-
具体装饰类(ConcreteDecorator):
- 继承自装饰器并添加额外功能。
优点:
- 灵活性:可以在运行时添加功能,而不影响其他对象。
- 单一职责原则:每个装饰类都有自己的职责,可以独立地进行扩展。
- 可替换性:可以在装饰器之间自由组合。
使用场景:
- 需要在运行时添加额外功能或职责。
- 希望通过组合来实现不同的行为,避免使用大量的子类。
JAVA:
例如:制作咖啡(Coffee): 普通咖啡和价格, 那么加牛奶, 加糖都是对普通咖啡的增强
// 1、定义一个咖啡接口 - 抽象构件
public interface Coffee {// 咖啡描述public String getDescription();// 价格public double cost();
}
// 2、具体构件:基本咖啡
public class SimpleCoffee implements Coffee{@Overridepublic String getDescription() {return "普通咖啡:Simple Coffee";}@Overridepublic double cost() {return 1;}
}
// 3、装饰器
public abstract class CoffeeDecorator implements Coffee{public Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String getDescription() {return coffee.getDescription();}@Overridepublic double cost() {return coffee.cost();}
}
// 4、具体装饰类-牛奶装饰
public class MilkDecorator extends CoffeeDecorator{public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", 加牛奶";}@Overridepublic double cost() {return coffee.cost() + 1;}
}
//5、具体装饰类:糖装饰
public class SugarDecorator extends CoffeeDecorator{public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", 加糖";}@Overridepublic double cost() {return super.cost();}
}
@Test(description = "装饰器")public void decoratorTest(){Coffee coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " $" + coffee.cost());// 添加牛奶coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());// 添加糖coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());}
GO:
画画的例子,默认的 Square
只有基础的画画功能, ColorSquare
为他加上了颜色
package decorator// IDraw 画画
type IDraw interface {Draw() string
}// Square 正方形type Square struct{}func (s Square) Draw() string {return "这是一个正方形"
}// ColorSquare 有颜色的正方形
type ColorSquare struct {square IDrawcolor string
}func NewColorSquare(square IDraw, color string) ColorSquare {return ColorSquare{square: square,color: color,}
}func (c ColorSquare) Draw() string {return c.square.Draw() + ", 颜色是 " + c.color
}
package decoratorimport ("fmt""testing"
)func TestDecorator(t *testing.T) {sq := Square{}csq := NewColorSquare(sq, "红色")draw := csq.Draw()fmt.Println(draw)
}