//单一原则: 一个类而言,应该仅有一个引起它变化的原因。
//开放-封闭原则: 类/模块/函数等等,应该可以扩展,但是不可修改。
//依赖倒装原则: 抽象不应该依赖细节,洗劫应该依赖于抽象。换句话说是,要针对接口编程,不要对实现编程。
//A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
//B.抽象不应该依赖细节。细节应该依赖抽象。
//里氏代换原则: 子类型必须能够替换掉它们的父类型。
//3.装饰模式
//ver1
class Person
{
private:
string _name;
public:
Person(string name)
{
_name = name;
}
void Show()
{
//...
}
};
//服饰抽象类
class Finery
{
public:
virtual void Show() = 0;
};
//T恤类
class TShirts : public Finery
{
public:
virtual void Show()
{
//..
}
};
//垮裤类
class BigTrouser : public Finery
{
public:
virtual void Show()
{
//..
}
};
//领带类
class Tie : public Finery
{
public:
virtual void Show()
{
//..
}
};
void main11()
{
Person *ppc = new Person("fun");
TShirts *pd1 = new TShirts();
BigTrouser *pd2 = new BigTrouser();
Tie *pd3 = new Tie();
//装扮1
pd1->Show();
pd2->Show();
ppc->Show();
//装扮2
pd1->Show();
pd3->Show();
ppc->Show();
//缺点: 一个一个显示出来; 组装应该在内部进行;
}
//装饰模式: 动态地给一个对象添加一些额外的职责,就增加功能类说,装饰模式比生成子类更为灵活;
//3.装饰模式
//ver2
//Component是定义一个对象接口,可以给这些对象动态地添加职责。
//ConcreteComponent是定义一个具体的对象,也可以给这个对象添加一些职责。
//Decorator抽象装饰类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,无需知道Decorator的存在;
//ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
class Component
{
public:
virtual void Operation() = 0; //接口
};
class ConcreteComponent : public Component
{
virtual void Operation()
{
//...
}
};
class Decorator : public Component
{
protected:
Component *pcomponent;
public:
void SetComponent(Component *pcom)
{
pcomponent = pcom;
}
virtual void Operation()
{
if (pcomponent != NULL)
{
pcomponent->Operation();
}
}
};
class ConcreteDecoratorA : public Decorator
{
private:
string addState;
public:
virtual void Operation()
{
Decorator::Operation(); //先运行Component的Operation,再执行本类的操作。
addState = "New State";
//...
}
};
class ConcreteDecoratorB : public Decorator
{
private:
void AddBehavior() //本类独有的操作;
{
//...
}
public:
virtual void Operation()
{
Decorator::Operation();
AddBehavior();
}
};
void main12()
{
ConcreteComponent * pc = new ConcreteComponent();
ConcreteDecoratorA * d1 = new ConcreteDecoratorA();
ConcreteDecoratorB * d2 = new ConcreteDecoratorB();
d1->SetComponent(pc); //先用 ConcreteDecoratorA 来包装 ConcreteComponent; 会执行 ConcreteComponent::Operation()
d2->SetComponent(d1); //再用 ConcreteDecoratorB 来包装 ConcreteDecoratorA
d2->Operation(); //最终执行 d2->Operation()
//装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了。
//每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
}
//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
//如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合成一个类.
//3.装饰模式
//ver3
class Person
{
private:
string _name;
public:
Person(){} //用于 TShirts 等派生类构造默认的构造函数;
Person(string name)
{
_name = name;
}
virtual void Show()
{
}
};
//服饰类
class Finery : public Person
{
protected:
Person component;
public:
void Decorate(Person comp)
{
component = comp;
}
virtual void Show()
{
component.Show();
}
};
//具体服饰类
class TShirts : public Finery
{
public:
virtual void Show()
{
//do something
Finery::Show();
}
};
class BigTrouser : public Finery
{
public:
virtual void Show()
{
//do something.
Finery::Show();
}
};
void main31()
{
Person * ppc = new Person("fun");
TShirts * pd1 = new TShirts();
BigTrouser * pd2 = new BigTrouser();
pd1->Decorate(*ppc);
pd2->Decorate(*pd1);
pd2->Show();
}
//装饰模式是为已有功能动态地添加更多功能的一种方式。
//装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。
//优点: 把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
// 有效地把类的核心职能和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。