定义:
动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,装饰模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)
特点:即继承基类 又组合基类
class Stream{
public:
virtual char Read(int number)=0;
virtual void Seek(int position)=0;
virtual void Write(byte data)=0;
virtual ~Stream();
};
class FileStram:public Stream{
public:
virtual char Read(int number){}//静态特质
virtual void Seek(int position){}
virtual void Write(byte data){}
}//文件流
class MemoryStram:public Stream{
public:
virtual char Read(int number){}
virtual void Seek(int position){}
virtual void Write(byte data){}
}//内存流
class NetworkStram:public Stream{
public:
virtual char Read(int number){}
virtual void Seek(int position){}
virtual void Write(byte data){}
}//网络流
//以上每个对象流都有自己的扩展操作:加密 缓存
class Decoreter:public Stream{
protected:
Stream* stream;//核心 组合的方式实现多态
Decoreter(Stream* stream):Stream(stream){}
};//装饰器 即继承基类 又组合基类
class CryptoStream: public Decoreter{
//Stream* stream;//...装饰器保存该字段
public:
CryptoStream(Stream* stream):Decoreter(stream){}//调用基类(装饰器)构造器
virtual char Read(int number){
//额外的加密操作
stream->Read(number);//读文件流 动态特质
//额外的加密操作
}
virtual void Seek(int position){
//额外的加密操作
stream::Seek(position);//定位文件流
//额外的加密操作
}
virtual void Write(byte data){
//额外的加密操作
stream::Write(data);//写文件流
//额外的加密操作
}
};
class BufferedStream:public Decoreter{
//Stream* stream;//...装饰器保存该字段
public:
BufferedStream(Stream* stream):Decoreter(stream){}//构造器
//....
};
void process(){
//运行时装配
Filestream* s1=new Filestream();
CryptoStream* s2=new CryptoStream(s1);//加密 Stream* stream=s1;
BufferedStream* s3=new BufferedStream(s1);//缓存
BufferedStream* s3=new BufferedStream(s2);//即加密又缓存 Stream* stream=s2;
}
Go语言
// 饮料接口
type Beverage interface {
getDescription() string
cost() int
}
// 实现咖啡的过程
type Coffee struct {
description string
}
func(this Coffee) getDescription() string {
return this.description
}
func(this Coffee) cost() int {
return 1
}
// Mocha 实现
type Mocha struct {
beverage Beverage
description string
}
func(this Mocha) getDescription() string {
return fmt.Sprintf("%s, %s", this.beverage.getDescription(), this.description)
}
func(this Mocha) cost() int {
return this.beverage.cost() + 1
}
// Whip 实现
type Whip struct {
beverage Beverage
description string
}
func(this Whip) getDescription() string {
return fmt.Sprintf("%s, %s", this.beverage.getDescription(), this.description)
}
func(this Whip) cost() int {
return this.beverage.cost() + 1
}
func main() {
var beverage Beverage
// 买了一杯咖啡
beverage = Coffee{description:"houseBlend"}
// 给咖啡加上 Mocha
beverage = Mocha{beverage:beverage, description:"Mocha"}
// 给咖啡加上 Whip
beverage = Whip{beverage:beverage, description:"whip"}
// 最后计算 Coffee 的价格
fmt.Println(beverage.getDescription(), ", cost is ", beverage.cost())
}