您的位置:首页 > 编程语言 > C语言/C++

简单工厂模式的C++实现——设计模式学习(1)

2016-11-22 14:56 441 查看
编程目的:使用任意一种面向对象语言实现一个计算器的控制台程序,要求输入两个数和运算符号得到结果。

 

(1)使用面向过程的思想实现计算器的控制台程序

#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;
}
 

 

(2)上述代码看似考虑完备,实则,尚未考虑用户输入错误的运算符时的异常处理。下面用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;
}
 

(3)上述代码的扩展性、维护性、复用性、灵活性都很不好,而且没有用面向对象的思想。面向对象的三大特性:“封装”“继承”“多态”,可以降低程序的耦合度。

 

使用面向对象的封装特性,将程序的业务逻辑和界面逻辑分开,降低业务和界面的耦合度,

#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;
}
 

 

 

(4)使用面向对象的继承和多态特性,将程序的业务逻辑分离成互不影响的独立模块。

在实例化对象时,使用“简单工厂模式”:用一个单独的类来完成实例的创造过程(工厂),

#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,分别为面向过程思想实现的计算器简单例子(对应于上面的(2)),和面向对象思想实现的计算器简单例子(对应于上面的(4)),其中calculatorConsole2.zip不仅运用的面向对象的封装继承多态三大特性将业务逻辑和界面逻辑加以分离,还增加了异常处理,以及运用了“简单工厂设计模式”,代码的灵活性、扩展性、复用性、维护性都很好,可以很方便的移植到需要GUI的计算器实现中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息