简单工厂模式是一种常见的创建型设计模式,它提供了一种简单的方式来创建对象,而无需暴露创建逻辑的细节。下面是一个简单工厂模式的C++实现示例:
#include <iostream>
using namespace std;
// 定义一个抽象基类Animal
class Animal {
public:
virtual void speak() = 0;
};
// 定义具体的子类Dog和Cat,它们继承自Animal
class Dog : public Animal {
public:
virtual void speak() {
cout << "I'm a dog." << endl;
}
};
class Cat : public Animal {
public:
virtual void speak() {
cout << "I'm a cat." << endl;
}
};
// 定义一个简单工厂类AnimalFactory,它负责创建Animal的子类对象
class AnimalFactory {
public:
Animal* createAnimal(string type) {
if (type == "dog") {
return new Dog();
} else if (type == "cat") {
return new Cat();
} else {
return NULL;
}
}
};
// 测试代码
int main() {
AnimalFactory* factory = new AnimalFactory();
Animal* dog = factory->createAnimal("dog");
if (dog != NULL) {
dog->speak(); // 输出: I'm a dog.
}
Animal* cat = factory->createAnimal("cat");
if (cat != NULL) {
cat->speak(); // 输出: I'm a cat.
}
delete dog;
delete cat;
delete factory;
return 0;
}
上面的示例中,我们定义了一个抽象基类Animal和两个具体子类Dog和Cat,它们都实现了Animal的纯虚函数speak。然后我们定义了一个AnimalFactory类,它负责根据参数创建Animal的子类对象。在测试代码中,我们通过调用AnimalFactory的createAnimal函数来创建具体的Dog和Cat对象,然后调用它们的speak函数输出它们的声音。最后,我们需要手动释放分配的内存。
总的来说,简单工厂模式可以帮助我们将创建对象的逻辑与具体的对象实现分离开来,使得代码更加简洁和易于维护。
下面再给出另外一个完整示例:
编程目的:使用任意一种面向对象语言实现一个计算器的控制台程序,要求输入两个数和运算符号得到结果。
#include <iostream> #include <exception> using namespace std; int main() { double numberA; double numberB; char operate; cout<<"input number A: "; cin>>numberA; cout<<"input operator(+ - * /): "; cin>>operate; cout<<"input number B: "; cin>>numberB; double result = 0; switch(operate) { case '+': result = numberA + numberB; break; case '-': result = numberA - numberB; break; case '*': result = numberA * numberB; break; case '/': if (-0.00000001 < numberB && numberB < 0.00000001)//numberB!=0 { cout<<"The divisor cannot be zero."; } else { result = numberA / numberB; } break; } cout<<"result:"<<result<<endl; return 0; } |
上述代码看似考虑完备,实则,尚未考虑用户输入错误的运算符时的异常处理。下面用try,throw,catch对异常进行处理。
为程序添加异常处理,
#include <iostream> #include <exception> using namespace std; int main() { double numberA; double numberB; char operate; cout<<"input number A: "; cin>>numberA; cout<<"input operator(+ - * /): "; cin>>operate; cout<<"input number B: "; cin>>numberB; double result = 0; try { switch(operate) { case '+': result = numberA + numberB; break; case '-': result = numberA - numberB; break; case '*': result = numberA * numberB; break; case '/': if (-0.00000001 < numberB && numberB < 0.00000001)//numberB!=0 { throw exception("The divisor cannot be zero.");//cout<<"The divisor cannot be zero."; } else { result = numberA / numberB; } break; default: throw exception("The operator is not correct."); } } catch(exception& e) { cout<<e.what()<<endl; exit(1); } cout<<"result:"<<result<<endl; return 0; } |
上述代码的扩展性、维护性、复用性、灵活性都很不好,而且没有用面向对象的思想。面向对象的三大特性:“封装”“继承”“多态”,可以降低程序的耦合度。
(1)使用面向对象的封装特性,将程序的业务逻辑和界面逻辑分开,降低业务和界面的耦合度。
#include <iostream> #include <exception> using namespace std; class Operation { public: static double getResult(double numberA, double numberB, char operate) { double result = 0; switch(operate) { case '+': result = numberA + numberB; break; case '-': result = numberA - numberB; break; case '*': result = numberA * numberB; break; case '/': if (-0.00000001 < numberB && numberB < 0.00000001)//numberB!=0 { throw exception("The divisor cannot be zero.");//cout<<"The divisor cannot be zero."; } else { result = numberA / numberB; } break; default: throw exception("The operator is not correct."); } return result; } }; int main() { double numberA; double numberB; char operate; cout<<"input number A: "; cin>>numberA; cout<<"input operator(+ - * /): "; cin>>operate; cout<<"input number B: "; cin>>numberB; double result = 0; try { result = Operation::getResult(numberA, numberB, operate); } catch(exception& e) { cout<<e.what()<<endl; exit(1); } cout<<"result:"<<result<<endl; return 0; } |
(2)使用面向对象的继承和多态特性,将程序的业务逻辑分离成互不影响的独立模块。在实例化对象时,使用“简单工厂模式”:用一个单独的类来完成实例的创造过程(工厂)。
#include <iostream> #include <exception> using namespace std; //运算类 class Operation { //public: // static double getResult(double numberA, double numberB, char operate) // { // double result = 0; // switch(operate) // { // case '+': // result = numberA + numberB; // break; // case '-': // result = numberA - numberB; // break; // case '*': // result = numberA * numberB; // break; // case '/': // if (-0.00000001 < numberB && numberB < 0.00000001)//numberB!=0 // { // throw exception("The divisor cannot be zero.");//cout<<"The divisor cannot be zero."; // } // else // { // result = numberA / numberB; // } // break; // default: // throw exception("The operator is not correct."); // } // return result; // } public: void SetNumberA( double a ) { numberA_ = a; } double GetNumberA() { return numberA_; } void SetNumberB( double b ) { numberB_ = b; } double GetNumberB() { return numberB_; } virtual double GetResult() = 0; protected: double numberA_; double numberB_; }; //加减乘除类(都是继承于运算类的子类) class OperationAdd: public Operation { public: virtual double GetResult() { return numberA_ + numberB_; } }; class OperationSub: public Operation { public: virtual double GetResult() { return numberA_ - numberB_; } }; class OperationMul: public Operation { public: virtual double GetResult() { return numberA_ * numberB_; } }; class OperationDiv: public Operation { public: virtual double GetResult() { if (-0.00000001 < numberB_ && numberB_ < 0.00000001)//numberB!=0 { throw exception("The divisor cannot be zero.");//cout<<"The divisor cannot be zero."; } return numberA_ / numberB_; } }; class OperationFactory { public: OperationFactory() { operation_ = NULL; } Operation* CreateOperate( char o ) { switch( o ) { case '+': operation_ = new OperationAdd(); break; case '-': operation_ = new OperationSub(); break; case '*': operation_ = new OperationMul(); break; case '/': operation_ = new OperationDiv(); break; default: throw exception("The operator is not correct."); } return operation_; } ~OperationFactory() { delete operation_; } private: Operation* operation_; }; int main() { double numberA; double numberB; char operate; cout<<"input number A: "; cin>>numberA; cout<<"input operator(+ - * /): "; cin>>operate; cout<<"input number B: "; cin>>numberB; OperationFactory factory; Operation* operation; try { operation = factory.CreateOperate( operate ); } catch(exception& e) { cout<<e.what()<<endl; exit(1); } operation->SetNumberA( numberA ); operation->SetNumberB( numberB ); double result = 0; try { result = operation->GetResult();//Operation::getResult(numberA, numberB, operate); } catch(exception& e) { cout<<e.what()<<endl; exit(1); } cout<<"result:"<<result<<endl; return 0; } |
总结:设计模式——“简单工厂模式”的运用,可以使程序具备可维护、可复用、可扩展、灵活性好等特点。
VS2010开发环境下所建的完整工程链接:http://download.csdn.net/detail/fan0920/9689619
包含两个zip文件夹calculatorConsole.zip和calculatorConsole2.zip,分别为面向过程思想实现的计算器简单例子,和面向对象思想实现的计算机简单例子,其中calculatorConsole2.zip不仅运用的面向对象的封装继承多态三大特性将业务逻辑和界面逻辑加以分离,还增加了异常处理,以及运用了“简单工厂设计模式”,代码的灵活性、扩展性、复用性、维护性都很好,可以很方便的移植到需要GUI的计算器实现中。