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