简介
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一系列装饰器类,这些装饰器类都实现了相同的接口,以透明的方式包装原始类。
在装饰器模式中,通常会涉及到以下几个角色:
Component(组件接口)
定义了具体组件和装饰器类共同实现的接口。
ConcreteComponent(具体组件)
实现了组件接口的具体类,是被装饰的对象。
Decorator(装饰器抽象类)
继承了组件接口,并持有一个对具体组件的引用,它的子类可以通过继承来添加新的功能。
ConcreteDecorator(具体装饰器)
实现了装饰器抽象类的具体子类,负责添加新的功能。
终于买车了,但是一看没有导航,那咋办?加装一个导航。导航就是装饰器,加导航后,车不会有结构性的改变。
Demo
// Car :Component 车接口
type Car interface {
Drive() string // 车基本的结构、功能就是drive
}
// BasicCar :ConcreteComponent 具体车类
type BasicCar struct{}
func (c *BasicCar) Drive() string {
return "BasicCar: Driving"
}
// CarDecorator :Decorator 装饰器抽象类
type CarDecorator interface {
Car
}
// NavigationDecorator 导航系统装饰器
type NavigationDecorator struct {
car Car // 导航装在车里
}
func (nd *NavigationDecorator) Drive() string {
return fmt.Sprintf("NavigationDecorator: %s with Navigation System", nd.car.Drive())
}
test
func TestDecorator(t *testing.T) {
basicCar := &BasicCar{}
navigation := &NavigationDecorator{car: basicCar} // 加装导航系统
fmt.Println(navigation.Drive()) // NavigationDecorator: BasicCar: Driving with Navigation System
}
在这个例子中,Car 是车接口,定义了具体车和装饰器类共同实现的方法。BasicCar 是具体车类,实现了 Car 接口。CarDecorator 是装饰器抽象类,继承了 Car 接口。NavigationDecorator 是具体装饰器,分别实现了装饰器抽象类。
在 main 函数中,我们创建了基本车 basicCar,然后通过装饰器模式,加装了导航系统。通过不同的组合,我们可以在运行时动态地为车添加不同的功能。
作用和场景
动态添加功能
装饰器模式允许在运行时动态地为对象添加新的功能,如给车加装不同的装饰器。
避免子类膨胀
通过装饰器模式,我们可以避免通过大量子类来扩展对象功能。
灵活组合
可以灵活组合不同的装饰器,以获得各种组合效果,如先加装导航系统再加装天窗。
透明性
客户端不需要关心具体的装饰器类,可以透明地使用基本组件和装饰器。
总体而言,装饰器模式适用于需要在运行时动态地为对象添加功能、避免子类膨胀、实现灵活组合以及保持透明性的场景。通过使用装饰器模式,可以更灵活地扩展对象的功能,而不影响其原有的结构和代码。