此次作业,我选择以与“工厂”相关的三个设计模式,即简单工厂模式、工厂方法模式和抽象工厂模式为案例,进行分析。所有代码通过一个单独的C++文件来展现。
1.简单工厂模式
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。事实上,它并不属于23种设计模式。
简而言之,简单工厂模式就是就是有一个专门生产某个产品的类。
简单工厂模式的代码案例如下:
const int adidas = 1; const int nike = 2; //shirt抽象类 class Shirt { public: virtual void Show() = 0; }; //adidas牌shirt class AdiShirt : public Shirt { public: void Show() { cout << "AdiShirt" << endl; } }; //Nike牌shirt class NikeShirt : public Shirt { public: void Show() { cout << "NikeShirt" << endl; } }; //唯一的工厂,可以生产两种品牌的shirt class Factory { public: Shirt* CreateShirt(int brand) { if (brand == adidas) //工厂内部判断 return new AdiShirt(); //生产adidas else if (brand == nike) return new NikeShirt(); //生产nike else return NULL; } };
分析封装、继承和多态:
AdiShirt和NikeShirt都继承了抽象基类Shirt,并覆盖了show方法,实现了多态。Factory类的CreateShirt方法可根据输入的brand参数来确定生产Adidas牌shirt或是Nike牌Shirt
带来的好处:这个简单工厂利用了面向对象语言中“继承”这一特性,将决定工厂的生产什么产品的决定权直接交到了客户手中,可以根据客户自己的需求,得到他们想要的最终的结果。
2.工厂方法模式
简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。假如增加其他品牌的shirt,工厂类需要修改,如何解决?
工厂方法模式在此时应运而生,创建一个工厂接口和创建多个工厂实现类,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
工厂方法模式的代码案例如下:
const int adidas = 1; const int nike = 2; //shirt抽象类 class Shirt { public: virtual void Show() = 0; }; //adidas牌shirt class AdiShirt : public Shirt { public: void Show() { cout << "AdiShirt" << endl; } }; //Nike牌shirt class NikeShirt : public Shirt { public: void Show() { cout << "NikeShirt" << endl; } }; //工厂的抽象基类 class Factory { public: virtual Shirt* CreateShirt(int brand) = 0; }; //专门生产adidas的工厂 class AdiFactory:public Factory { public: virtual Shirt* CreateShirt(int brand) { return new AdiShirt(); } }; //专门生产Nike的工厂 class NikeFactory:public Factory { public: virtual Shirt* CreateShirt(int brand) { return new NikeShirt(); } };
分析封装、继承和多态:
Shirt、AdiShirt和NikeShirt类和简单工厂模式中保持一致,Factory抽象成抽象基类,且分别派生出了AdiFactory和NikeFactory。CreateShirt(int brand)为虚函数,且在两个子类中得到覆盖,即实现了多态。这种模式下,若需要扩展,只需添加新的工厂子类
并且继承Factory这一抽象基类即可。
带来的好处:克服了简单工厂违背开放-封闭原则的缺点,又保留了封装对象创建过程的优点,降低客户端和工厂的耦合性,“工厂方法模式”是“简单工厂模式”的进一步抽象和推广。
3.抽象工厂模式
不仅可以生产Shirt,还能生产Pants。现在简单工厂模式和工厂方法模式都无法更好地完成工作。抽象工厂模式应运而生。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。具体为,存在两个工厂(该案例中)一个专门用来生产Adidas品牌的Shirt和Pants,而另一个工厂专门用来生产Nike的Shirt和Pants。
工厂方法模式的代码案例如下:
const int adidas = 1; const int nike = 2; //shirt抽象类 class Shirt { public: virtual void Show() = 0; }; //adidas牌shirt class AdiShirt : public Shirt { public: void Show() { cout << "AdiShirt" << endl; } }; //Nike牌shirt class NikeShirt : public Shirt { public: void Show() { cout << "NikeShirt" << endl; } }; //Pants抽象类 class Pants { public: virtual void Show() = 0; }; //adidas牌pants class AdiPants : public Pants { public: void Show() { cout << "AdiPants" << endl; } }; //Nike牌pants class NikePants : public Pants { public: void Show() { cout << "NikePants" << endl; } }; //工厂的抽象基类 class Factory { public: virtual Shirt* CreateShirt(int brand) = 0; virtual Pants* CreatePants(int brand) = 0; }; //专门生产adidas的工厂 class AdiFactory :public Factory { public: virtual Shirt* CreateShirt(int brand) { return new AdiShirt(); } virtual Pants* CreatePants(int brand) { return new AdiPants(); } }; //专门生产nike的工厂 class NikeFactory :public Factory { public: virtual Shirt* CreateShirt(int brand) { return new NikeShirt(); } virtual Pants* CreatePants(int brand) { return new NikePants(); } };
分析封装、继承和多态:
相比上面两种模式,抽象工厂模式又定义了Pants基类和AdiPants、NikePants两个子类。此外对于抽象基类Factory,新增了虚函数CreatePants,并且新派生出了子类NikeFactory。在两个工厂子类——AdiFactory和NikeFactory中继承并覆盖了虚函数
CreateShirt和CreatePants,实现了多态。每个工厂子类只负责生产自己品牌的服装——shirt或pants
带来的好处:抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。这样模块更加清晰,每个部分都各司其职,分工明确,可维护性更好。