设计模式实现C++ --工厂模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
类型:创建型模式
分类:
简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。有点抽象,举个例子就明白了。有一家生产处理器核的厂家,它只有一个工厂,能够生产两种类型的产品。客户需要什么样的产品,一定要显示地告诉生产工厂。下面给出一种实现方案:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class product 6 { 7 public: 8 virtual void show(){} 9 }; 10 11 class productA:public product 12 { 13 public: 14 virtual void show() 15 { 16 cout << "product A" << endl; 17 } 18 }; 19 20 class productB:public product 21 { 22 public: 23 virtual void show() 24 { 25 cout << "product B" << endl; 26 } 27 }; 28 29 class Factory 30 { 31 public: 32 static product* CreateProduct(string pro) 33 { 34 if(pro == "A") 35 return new productA(); 36 else if(pro == "B") 37 return new productB(); 38 return NULL; 39 } 40 }
这样设计的主要缺点之前也提到过,就是要增加新的核类型时,就需要修改工厂类。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。
工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。举个例子,有两个工厂,工厂A只生产PROUCUTA, 工厂B只生产PRODUCTB,现在客户需要做的就是找到对应的工厂,而不需要告诉工厂我需要做什么型号的产品,实现方案如下:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class product 6 { 7 public: 8 virtual void show(){} 9 }; 10 11 class productA:public product 12 { 13 public: 14 virtual void show() 15 { 16 cout << "product A" << endl; 17 } 18 }; 19 20 class productB:public product 21 { 22 public: 23 virtual void show() 24 { 25 cout << "product B" << endl; 26 } 27 }; 28 29 class Factory 30 { 31 public: 32 virtual product* CreateProduct() = 0; 33 }; 34 35 class FactoryA:public Factory 36 { 37 public: 38 product* CreateProduct() { return new productA();} 39 }; 40 41 class FactoryB:public Factory 42 { 43 public: 44 product* CreateProduct() {return new productB();} 45 }; 46 47
工厂方法模式的缺点就是每增加一种产品,就要增加一个工厂, 如果这个公司迅速发展,新增了很多产品,那么就要开设很多相应的工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。
抽象工厂模式, 它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的的类,具体应用,有两个农场,一个家场专门生产北方水果和蔬菜,一个农声只生产热带水果和蔬菜,下面给出实现的代码。
1 #include <iostream> 2 using namespace std; 3 4 class Fruit 5 { 6 public: 7 virtual void show() = 0; 8 }; 9 10 class Veggie 11 { 12 public: 13 virtual void show() = 0; 14 }; 15 16 class NorthernFruit:public Fruit 17 { 18 public: 19 void show() 20 { 21 cout << "NortherFruit" << endl; 22 } 23 }; 24 25 class TropicalFruit:public Fruit 26 { 27 public: 28 void show() 29 { 30 cout << "TropicalFruit" << endl; 31 } 32 }; 33 34 class NorthernVeggie:public Veggie 35 { 36 public: 37 void show() 38 { 39 } 40 }; 41 42 class Gardener 43 { 44 public: 45 virtual Fruit* createFruit() = 0; 46 virtual Veggie* createVeggie() = 0; 47 }; 48 49 class NorthernGardener:public Gardener 50 { 51 public: 52 Fruit* createFruit() 53 { 54 return new NorthernFruit(); 55 } 56 57 Veggie* createVeggie() 58 { 59 return new NorthernVeggie(); 60 } 61 }; 62 63 64 class TropicalGardener:public Gardener 65 { 66 public: 67 Fruit* createFruit() 68 { 69 return new TropicalFruit(); 70 } Veggie* createVeggie() 71 { 72 return new TropicalVeggie(); 73 } 74 }; 75 76 77
优点:
- 可以使代码结构清晰,有效地封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
- 对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
- 降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。
适用场景:
不管是简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有类似的特性,所以他们的适用场景也是类似的。
首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。