注意区分“简单工厂”、“工厂方法模式”和“抽象工厂模式”
如果你需要动态选择实例化的类型,可以通过条件判断来选择类型。比如餐馆点菜:
- class Restaurant
- {
- public:
- Food* order(string s)
- {
- if (s == "rice")
- return new Rice;
- if (s == "meat")
- return new Meat;
- if (s == "vegetable")
- return new Vegetable;
- return NULL;
- }
- };
这样做的坏处是什么?当然是不容易适应变化。如果你要加一个饮料,那就要加一个条件分支。如果白菜断货了,餐馆就要删除一个条件分支。餐馆不应该根据菜式频繁地变化,所以可以把这些变化提取出来,形成一个简单工厂:
- class FoodFactory
- {
- public:
- Food* createFood(string s)
- {
- if (s == "rice")
- return new Rice;
- if (s == "meat")
- return new Meat;
- if (s == "vegetable")
- return new Vegetable;
- return NULL;
- }
- };
这时餐馆的代码可以简化成:
- class Restaurant
- {
- public:
- Food* order(string s)
- {
- FoodFactory* pFactory = new FoodFactory;
- return pFactory->createFood(s);
- }
- };
这样,所有的变化都局限于那个简单工厂了。你或许有疑问,这样做不就是仅仅把变化从餐馆移到了工厂吗?有什么本质区别?区别在于:这个工厂变得可以被复用了。餐馆,快餐,中餐,西餐都可以从这个工厂进货。
简单工厂并不是一个模式,只不过是常用的一种的习惯。
为了让工厂具有可扩展性,我们可以把工厂抽象成一个抽象类。
- class FoodFactory
- {
- public:
- virtual Food* creatFood(string s) = 0;
- };
各种生产食物的工厂都可以继承这个抽象类,并实现自己的的createFood方法,这样餐馆可以选择不同的菜系,比如它可以扩展成做西餐:
- class Restaurant
- {
- public:
- Food* order(string s)
- {
- FoodFactory* pFactory = new WesternFoodFactory;
- return pFactory->createFood(s);
- }
- };
这种基于同一个抽象工厂类形成的类层次结构被称为工厂方法模式。同样要注意到这个模式依赖于另一个抽象类层次:产品(即上例中的Food)。
设计原则:要依赖抽象,不要依赖具体类。(依赖倒置原则)
另一种工厂模式是抽象工厂模式。它是一个接口,定义了生产各种原料的方法。比如一个创建Car的工厂可以是这样:
- interface ICarFactory
- {
- virtual Wheel* createWheel() = 0;
- virtual Shell* createShell() = 0;
- virtual Engine* createEngine() = 0;
- };
这样的话就可以跟据不同需要组装成一部车出来:
- class RaceCar
- {
- public:
- RaceCar()
- {
- ICarFactory* pFactory = new IRaceCarFactory();
- this->engine = pFactory->createEngine();
- this->shell = pFactory->createShell();
- this->wheel = pFacotry->createWheel();
- }
- };
阅读(781) | 评论(0) | 转发(0) |