/*为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类*/
简单工厂模式就是把实例化的工作封装到一个类中
工厂方法和简单工厂的不同在于,用一个抽象类封装工厂类
通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
---------------------------------------------------------------
所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。
引入产品结构和产品族:
下面是一个例子,Monkey想要吃香蕉和苹果,香蕉苹果有中国产的,还有印度产的。Monkey跟住需求去找来自中国或者印度的农民,然后农民就会收获他们国家的香蕉和苹果给猴子。Kind of silly.
抽象工厂的代码:
#include <iostream> using namespace std; ////////////////////// class Apple{ public: virtual void AppleSayHi() = 0; }; class ChinaApple:public Apple{ public: void AppleSayHi(){ cout<<"Hi~ I'm an Apple from China. "; } }; class IndiaApple:public Apple{ public: void AppleSayHi(){ cout<<"Hi~ I'm an Apple from India. "; } }; class Banana{ public: virtual void BananaSayHi() = 0; }; class ChinaBanana:public Banana{ public: void BananaSayHi(){ cout<<"Hi~ I'm a Banana from China. "; } }; class IndiaBanana:public Banana{ public: void BananaSayHi(){ cout<<"Hi~ I'm a Banana from India. "; } }; ////////////////////// class Farmer{ public: virtual Apple* harvestApple() = 0; virtual Banana* harvestBanana() = 0; }; class ChinaFarmer:public Farmer{ public: Apple* harvestApple(){ return new ChinaApple();} Banana* harvestBanana(){return new ChinaBanana();} }; class IndiaFarmer:public Farmer{ public: Apple* harvestApple(){return new IndiaApple();} Banana* harvestBanana(){return new IndiaBanana();} }; ////////////////////// class Monkey{//又要买苹果又要买香蕉的客户 public: Apple *apple; Banana *banana; void SayHi(){ cout<<"Some fruits in my stomach: "; apple->AppleSayHi(); banana->BananaSayHi(); } Monkey(string Country){ Farmer *farmer; if (0 == Country.compare("China")) { farmer = new ChinaFarmer(); } else if (0 == Country.compare("India")) { farmer = new IndiaFarmer(); } apple = farmer->harvestApple(); banana = farmer->harvestBanana(); } }; int main(){ //测试 Monkey monkey1("China"); monkey1.SayHi(); Monkey monkey2("India"); monkey2.SayHi(); getchar(); return 0; }
抽象工厂模式的优点
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式的缺点
抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
适用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
- 这个系统有多于一个的产品族,而系统只消费其中某一产品族。
- 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
Abstract Factory模式在实际系统中的实现
Herbivore:草食动物
Carnivore:食肉动物
Bison:['baisn],美洲或欧洲的野牛
下面实际代码演示了一个电脑游戏中创建不同动物的抽象工厂。尽管在不同大陆下动物物种是不一样的,但动物间的关系仍然保留了下来。
1 // Abstract Factory pattern -- Structural example 2 using System; 3 4 // "AbstractFactory" 5 abstract class AbstractFactory 6 { 7 // Methods 8 abstract public AbstractProductA CreateProductA(); 9 abstract public AbstractProductB CreateProductB(); 10 } 11 12 // "ConcreteFactory1" 13 class ConcreteFactory1 : AbstractFactory 14 { 15 // Methods 16 override public AbstractProductA CreateProductA() 17 { 18 return new ProductA1(); 19 } 20 override public AbstractProductB CreateProductB() 21 { 22 return new ProductB1(); 23 } 24 } 25 26 // "ConcreteFactory2" 27 class ConcreteFactory2 : AbstractFactory 28 { 29 // Methods 30 override public AbstractProductA CreateProductA() 31 { 32 return new ProductA2(); 33 } 34 35 override public AbstractProductB CreateProductB() 36 { 37 return new ProductB2(); 38 } 39 } 40 41 // "AbstractProductA" 42 abstract class AbstractProductA 43 { 44 } 45 46 // "AbstractProductB" 47 abstract class AbstractProductB 48 { 49 // Methods 50 abstract public void Interact( AbstractProductA a ); 51 } 52 53 // "ProductA1" 54 class ProductA1 : AbstractProductA 55 { 56 } 57 58 // "ProductB1" 59 class ProductB1 : AbstractProductB 60 { 61 // Methods 62 override public void Interact( AbstractProductA a ) 63 { 64 Console.WriteLine( this + " interacts with " + a ); 65 } 66 } 67 68 // "ProductA2" 69 class ProductA2 : AbstractProductA 70 { 71 } 72 73 // "ProductB2" 74 class ProductB2 : AbstractProductB 75 { 76 // Methods 77 override public void Interact( AbstractProductA a ) 78 { 79 Console.WriteLine( this + " interacts with " + a ); 80 } 81 } 82 83 // "Client" - the interaction environment of the products 84 class Environment 85 { 86 // Fields 87 private AbstractProductA AbstractProductA; 88 private AbstractProductB AbstractProductB; 89 90 // Constructors 91 public Environment( AbstractFactory factory ) 92 { 93 AbstractProductB = factory.CreateProductB(); 94 AbstractProductA = factory.CreateProductA(); 95 } 96 97 // Methods 98 public void Run() 99 { 100 AbstractProductB.Interact( AbstractProductA ); 101 } 102 } 103 104 /// <summary> 105 /// ClientApp test environment 106 /// </summary> 107 class ClientApp 108 { 109 public static void Main(string[] args) 110 { 111 AbstractFactory factory1 = new ConcreteFactory1(); 112 Environment e1 = new Environment( factory1 ); 113 e1.Run(); 114 115 AbstractFactory factory2 = new ConcreteFactory2(); 116 Environment e2 = new Environment( factory2 ); 117 e2.Run(); 118 } 119 }
原文更妙: http://blog.csdn.net/ipqxiang/article/details/1955677