#include#include using namespace std; enum type{EWATER,ECREAM}; class SkinProduct{ public: virtual void createProduct()=0; }; class Water:public SkinProduct{ public: void createProduct(){ cout<<"creat water skin product."< 不遵守开放封闭原则,当要增加新的护肤品种类时,需要修改工厂类
工厂方法模式工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。它修正了简单工厂模式中不遵守开放—封闭原则。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
#include抽象工厂模式#include using namespace std; class SkinProduct{ public: virtual void createProduct()=0; }; class Water:public SkinProduct{ public: void createProduct(){ cout<<"creat water skin product."< creatoneProduct(); factory=new CreamFactory(); SkinProduct *skp1=factory->creatoneProduct(); delete factory; delete skp; delete skp1; return 0; } 抽象工厂模式和工厂方法模式很相似。最大的区别就是抽象工厂模式不止一个产品簇,并且每个工厂都不止生产一种产品。比如在工厂方法模式中,不同的工厂可以生产不同的产品。创建洗面奶工厂和面霜工厂,我们能生产洗面奶和面霜,但是只能生产一种洗面奶和面霜。但是在抽象工厂模式中,每个工厂中可以生产洗面奶和面霜。还能生产不同牌子的洗面奶和面霜。
譬如有一个科颜氏的工厂,一个雅诗兰黛的工厂。其中科颜氏的工厂生产科颜氏品牌的水和霜,而雅诗兰黛的工厂生产雅诗兰黛品牌的水和霜。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,我们要添加具体的产品的代码,还要在工厂中添加代码。
原型模式原型模式实际上是从一个对象创建另外一个可定制的对象,且无需知道任何创建的细节。
是用于创建重复的对象,同时又保证了性能。
#include观察者模式#include using namespace std; class Prototype{ private: string name; public: Prototype(){} Prototype(string name):name(name){} virtual Prototype* clone()=0; void printName(){ cout< printName(); return 0; } #include#include using namespace std; class Observer{//观察者 public: virtual void isDangerous()=0; }; class Notifier{//通知者 public: virtual void regListenner(Observer *o)=0; virtual void notify()=0; }; class ConcreteNotifier:public Notifier{ private: vector listenrs; public: void regListenner(Observer *o){ listenrs.push_back(o); } void notify(){ for(auto l:listenrs){ l->isDangerous(); } } }; class WW:public Observer{//具体观察者ww public: void isDangerous(){ touchFish(); } void touchFish(){ cout<<"ww stop touchfish!"< 代理模式 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
小明想给小红表达心意,但是自己不好意思,于是让同学代为转达。
#include模板模式#include using namespace std; class Girl{ private: string name; public: Girl(string name):name(name){} Girl(){} string getName(){ return this->name; } }; //送礼物接口 class GiveGift{ public: virtual void giftFlowers()=0; virtual void giftFood()=0; }; class Prusuit:public GiveGift{ private: Girl *g; public: Prusuit(Girl *g1){g=g1;} void giftFlowers(){cout<<"give flowers to "< getName()< getName()< giftFlowers();} void giftFood(){p->giftFood();} }; int main(){ Girl *b=new Girl("ww"); Proxy *p=new Proxy(b); p->giftFlowers(); p->giftFood(); return 0; } 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。
该模式的主要优点如下。
- 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
- 它在父类中提取了公共的部分代码,便于代码复用。
- 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
该模式的主要缺点如下。
- 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
- 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。
#includeusing namespace std; class Test{ public: //测试流程是一样的,具体的内容不一样 void doTest(){ studentName(); answerOne(); answerTwo(); } void question1(){ cout<<"do you like c++"< 面向对象设计六大原则
- 开放封闭原则
软件对扩展开放,对修改关闭。
- 单一职责原则
对于一个类而言,应该仅有一个能引起它变化的原因。
此原则核心:增强内聚性,降低耦合性
- 依赖倒置原则
1、上层模块不应该依赖底层模块,它们都应该依赖于抽象。
2、抽象不应该依赖于细节,细节应该依赖于抽象。
- 迪米特法则
也叫最少知识原则,强调类之间的松耦合。
- 里氏代换原则
里氏替换原则通俗来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。
- 接口隔离原则
客户端不应依赖于它不需要的接口,一个类对另一个类的依赖应建立在最小的接口上。



