简单工厂模式的最大长处在于工厂类中包括了必要的逻辑推断,依据client的选择条件动态实例化相关的类,对于client来说,去除了与详细产品的依赖。工厂方法模式的UML图例如以下:
比如在简单工厂模式中出现的工厂函数:
Operation* FactoryFunction(double left, double right, char op) { switch (op) { case '+': return new Add(left, right); break; case '-': return new Sub(left, right); break; case '*': return new Mul(left, right); break; case '/': return new Div(left, right); break; default: throw runtime_error("Operation invalid!"); break; } }
用户选择一个须要的运算符并传给工厂函数,工厂函数依据选择实例化一个相应的运算符并返回给客户程序。这里的优点是将细节处理都交给了工厂函数,这些操作对用户程序猿来说是透明的。
可是也有缺点:当我们须要加入新的运算操作时,都须要在工厂函数内加入case分支语句,这违反了开放封闭原则。开放封闭原则是指软件实体应该能够扩展。可是不可改动。
为了不违反开放封闭原则。能够使用工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。以下是用C++编写的运用了工厂方法模式的计算器类。
#include <iostream> using namespace std; // 运算基类 class Operation { public: Operation(const double left, const double right) { lhs = left; rhs = right; } virtual double Calculate() = 0; // 纯虚函数 protected: double lhs; double rhs; }; // 加法运算 class Add : public Operation { public: Add(double left, double right) : Operation(left, right) {} double Calculate() { return lhs + rhs; } }; // 减法运算 class Sub : public Operation { public: Sub(double left, double right) : Operation(left, right) {} double Calculate() { return lhs - rhs; } }; // 乘法运算 class Mul : public Operation { public: Mul(double left, double right) : Operation(left, right) {} double Calculate() { return lhs * rhs; } }; // 除法运算 class Div : public Operation { public: Div(double left, double right) : Operation(left, right) { try { if (right == 0) throw runtime_error("The divisor cannot be 0\n"); } catch (const runtime_error &e) { cout << e.what() << endl; throw; } } double Calculate() { return lhs / rhs; } }; // 抽象工厂 class AbstractFactory { public: virtual Operation* CreateOperation(const int left, const int right) = 0; }; // 依据运算实现出各自的工厂类 class AddFactory : public AbstractFactory { public: Operation* CreateOperation(const int left, const int right) { return new Add(left, right); } }; class SubFactory : public AbstractFactory { public: Operation* CreateOperation(const int left, const int right) { return new Sub(left, right); } }; class MulFactory : public AbstractFactory { public: Operation* CreateOperation(const int left, const int right) { return new Mul(left, right); } }; class DivFactory : public AbstractFactory { public: Operation* CreateOperation(const int left, const int right) { return new Div(left, right); } }; int main() { AbstractFactory *creator = new AddFactory(); Operation *add = creator->CreateOperation(11, 22); cout << add->Calculate() << endl; delete creator; creator = new SubFactory(); Operation *sub = creator->CreateOperation(25, 32); cout << sub->Calculate() << endl; delete creator; creator = new MulFactory(); Operation *mul = creator->CreateOperation(11, 11); cout << mul->Calculate() << endl; delete creator; creator = new DivFactory(); Operation *div = creator->CreateOperation(50, 8); cout << div->Calculate() << endl; delete creator; // 别忘记销毁指针 delete add; delete sub; delete mul; delete div; system("pause"); return 0; }
执行结果:
上面的样例中,定义了一个AbstractFactory抽象工厂类,创建实际对象的工厂类都要继承这个抽象基类并重写详细产生对象的方法CreateOperation。
当加入新的运算操作时,不须要改动原有的工厂类,仅仅须要继承AbstractFactory定义一个新的工厂类就可以。这就符合了封闭开放原则。
參考:
《大话设计模式》第8章