[GeekBand] 设计模式——工厂模式学习笔记
本文参考文献:GeekBand课堂内容,授课老师:李建忠
:大话设计模式
其余的模式方法请自行查看Geekband相关课程,在此不累述。
这周的课题是:
针对DrawingSystem中的基类Shape和各个子类Line、Rec、Circle。为支持更多的形状子类,请使用某种模式来支持灵活地创建它们。使用松耦合面向对象设计方法和思想,可使用伪码表示设计。
课程中提到了四种模式,“工厂方法”、“抽象工厂”、“原型模式”、“构建器”模式。最后聚焦在了“工厂方法”和“抽象工厂”这两种方法,那么第一个问题就是“工厂方法”、“抽象工厂”区别与联系?
一、工厂方法和抽象工厂区别:
工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类
抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类
这里有更为详细的解释:
http://blog.csdn.net/wyxhd2008/article/details/5597975
总之,关键字在于“相互依赖的对象,多个业务层次”,而本题中,各个子类之间并没有说明之间有相互依赖的关系,故最终决定采用工厂方法模式
二、结构图
三、通过代码和上述结构分析
普通的调用关系为:
在函数中,普通的new 关系,实际上将ashape 与 Circle() 耦合,每次需求改变都要重新修改源代码,这样非常不适合软件的迭代。
Shape * ashape = new Circle();
而在工厂模式中,如下述代码,红色代码,这是松耦合设计的思想。
class MainForm : public Form { ShapeFactory* factory;//工厂 public: MainForm(ShapeFactory* factory) { this->factory = factory; } virtual ~MainForm(); void MainCreate() { //多态new Shape * ashape =factory->CreateShape(); //获取No ashape->GetNo(); } };
那么怎么实现的呢?
对应上图,我们实现了下面四段代码,分别是抽象的Shape 、ShapeFactory、具体的子类 、如Circle、具体的子类工厂如、CircleFactory
class Shape { public: Shape(int no = 0) :no_(){} virtual ~Shape(){} int GetNo(){ return no_; } int SetNo(int no_){} private: int no_; };
class ShapeFactory { public: ShapeFactory(); virtual Shape * CreateShape() = 0; virtual ~ShapeFactory(){} };
//具体类 class Line : public Shape { public: Line(){} virtual ~Line(){} }; class Rec : public Shape { public: Rec(){} virtual ~Rec(){} }; class Circle : public Shape { public: Circle(){} virtual ~Circle(){} };
//具体工厂 class LineFactory : public ShapeFactory { public: LineFactory(); virtual ~LineFactory(); virtual Shape* CreateShape() { return new Line(); } }; class RecFactory : public ShapeFactory { public: RecFactory(); virtual ~RecFactory(); virtual Shape* CreateShape() { return new Rec(); } }; class CircleFactory : public ShapeFactory { public: CircleFactory(); virtual ~CircleFactory(); virtual Shape* CreateShape() { return new Circle(); } };
四、小结
1、工厂模式用于隔离对象的使用者和具体类型之间的耦合关系。(红色字体部分)
2、工厂模式通过面向对象的方法,将所要创建的具体对象延迟到子类,从而实现一种扩展(而非更改)的策略,较好的解决了这种紧耦合的关系
3、工厂模式解决单个对象的需求变化,缺点在于要求创建的方法和参数相同