1.定义
在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
2.理解
通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰模式的目标。
与代理模式相比,代理模式扩展的功能仅限于接口中原有的方法,不会增加新的方法,而装饰模式可以做到。代理模式中,调用方直接调用代理对象,不会关心里面具体的被代理对象。而装饰模式是要先生成对象,再进行包装处理。
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
3.java代码示例
public class DecoratorPattern {
public static void main(String[] args) throws Exception {
ICar car = new Car();
car.run();
//可以通过原接口调用,已经加强了的方法,功能上来说,可以增强原来已有的方法
ICar car2 = new ConcreteCarriage(car);
car2.run();
//可以通过抽象包装来调用,可以增加新的方法,扩展原来的功能
CarCarriage car3 = (CarCarriage)car2;
car3.carryCango();
}
}
//抽象构件
interface ICar {
void run();
}
//具体构件
class Car implements ICar {
@Override
public void run() {
System.out.println("开车。。。");
}
}
//抽象装饰
abstract class CarCarriage implements ICar {
protected ICar car;
public CarCarriage(ICar car) {
this.car = car;
}
//多一个载货的功能
abstract void carryCango();
@Override
public void run() {
this.car.run();
}
}
//具体装饰
class ConcreteCarriage extends CarCarriage {
public ConcreteCarriage(ICar car) {
super(car);
}
@Override
public void run() {
System.out.print("带车厢车 ");
super.run();
}
@Override
void carryCango() {
System.out.println("带车厢的车 载货。。。");
}
}
4.golang 代码示例
func main() {
//生成一个普通的车
car := new(Car)
car.Run()
carriage:= new(ConcreteCarriage)
carriage.car = car
carriage.Run()
carriage.CarryCargo()
}
type ICar interface {
Run()
}
type Car struct {
}
func (car *Car) Run() {
fmt.Println("开车。。。")
}
type ICarCarriage interface {
ICar
CarryCargo()
}
type ConcreteCarriage struct {
car ICar
}
func (c *ConcreteCarriage) CarryCargo() {
fmt.Println("带车厢的车 载货。。。")
}
func (c *ConcreteCarriage) Run() {
//加入自己的逻辑
fmt.Print("带车厢车 ")
//调用原来的方法
c.car.Run()
}