简单工厂模式(simple-factory-pattern)

Posted 白龙码~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单工厂模式(simple-factory-pattern)相关的知识,希望对你有一定的参考价值。

简单工厂模式(simple-factory-pattern)

文章目录

一、简单计算器的设计

假如让你写一份简单计算器的代码,我想大部分有一定基础的人都能在五分钟之内完成以下的代码:

#include <iostream>
// simple calculator

int main() 
  double x = 0, y = 0;
  std::cout << "please enter two operands" << std::endl;
  std::cin >> x >> y;

  char opt = '+';
  std::cout << "please enter the operator(+-*/)" << std::endl;
  std::cin >> opt;

  double res = 0;
  switch (opt) 
    case '+':
      res = x + y;
      break;
    case '-':
      res = x - y;
      break;
    case '*':
      res = x * y;
      break;
    case '/':
      if (y == 0) 
        std::cout << "invalid dividend!" << std::endl;
       else 
        res = x / y;
      
      break;
    default:
      std::cout << "invalid operator!" << std::endl;
      break;
  
  std::cout << "res = " << res << std::endl;

这样的代码有哪些问题呢?

  • 其一:可复用性太差。假设公司业务新增了GUI页面的计算器,那么就需要把这部分代码逻辑ctrl cv过去,从而造成代码的重复。然而编程的一大原则就是用尽可能的办法去避免重复,毕竟一旦某部分逻辑出现问题,那么在维护时就要修改所有的重复代码,这将是一场灾难。
  • 其二:这样的代码仅仅是面向过程的。在C++/Java等面向对象(Object Oriented, OO)语言盛行的今天,这样一份代码没有利用封装、继承、多态的特性,这也是它难以复用、维护的根本原因。

二、面向对象介入

如何将上述代码改写成面向对象的样子呢?

class Calculator 
public:
  static double get_result(double x, double y, char opt) 
    double res = 0;
    switch (opt) 
      case '+':
        res = x + y;
        break;
      case '-':
        res = x - y;
        break;
      case '*':
        res = x * y;
        break;
      case '/':
        if (y == 0) 
          std::cout << "invalid dividend!" << std::endl;
         else 
          res = x / y;
        
        break;
      default:
        std::cout << "invalid operator!" << std::endl;
        break;
    
  
;

嗯…很好,用到了封装的特性,那么继承与多态呢?这么好的东西为什么不用呢,是不喜欢么?

ps:笔者在学习甚至在实习做项目期间都没有用到过继承多态,还是吃了学的少的亏呀。

此外,这份代码还有一种隐患:如果业务需要新增一项功能,比如开根号,那么就要在原有的代码基础上直接改,万一改错了老代码呢?当然,这里的逻辑比较简单,一般不会出错,但是在复杂的公司业务中,难免会出现新手程序员新增功能后,整个业务直接跑不起来的情况。一方面,是程序员自身的问题,另一方面,也是这份代码的可维护性不高导致的。

三、计算工厂

"operator.hpp"

#pragma once

class Operator 
public:
  virtual double get_result() ;

  virtual void set_operands(double x, double y) ;
;

class OperatorAdd : public Operator 
public:
  double get_result() override 
    return x_ + y_;
  

  void set_operands(double x, double y) 
    x_ = x;
    y_ = y;
  
private:
  double x_;
  double y_;
;

class OperatorSub : public Operator 
public:
  double get_result() override 
    return x_ - y_;
  

  void set_operands(double x, double y) 
    x_ = x;
    y_ = y;
  
private:
  double x_;
  double y_;
;

class OperatorMul : public Operator 
public:
  double get_result() override 
    return x_ * y_;
  

  void set_operands(double x, double y) 
    x_ = x;
    y_ = y;
  
private:
  double x_;
  double y_;
;

class OperatorDiv : public Operator 
public:
  double get_result() override 
    return x_ / y_;
  

  void set_operands(double x, double y) 
    x_ = x;
    y_ = y;
  
private:
  double x_;
  double y_;
;

operator.hpp中负责实现不同的运算类,它们继承于Operator,用于后面的多态。

"calculator_factor.hpp"

#pragma once
#include "operator.hpp"

class CalculatorFactory 
public:
  static Operator *get_calculator(char opt) 
    switch (opt) 
      case '+':
        return new OperatorAdd;
      case '-':
        return new OperatorSub;
      case '*':
        return new OperatorMul;
      case '/':
        return new OperatorDiv;
    
  
;

计算工厂根据不同的操作符返回不同的运算对象。

"main.cpp"

#include <iostream>
#include <memory>
#include "calculator_factory.hpp"
// main.cpp
int main() 
  double x = 0, y = 0;
  std::cout << "please enter two operands" << std::endl;
  std::cin >> x >> y;

  char opt = '+';
  std::cout << "please enter the operator(+-*/)" << std::endl;
  std::cin >> opt;

  // simple factory pattern
  std::shared_ptr<Operator> opt_obj = std::shared_ptr<Operator>
                                      (CalculatorFactory::get_calculator(opt));
  opt_obj->set_operands(x, y);
  std::cout << opt_obj->get_result() << std::endl;
  
  return 0;

可见,在简单工厂模式的介入下,我们需要新增功能,只需要在"calculator_factor.hpp"中增加一个case,并在"operator.hpp"中新增一个运算类即可。

因此,代码的可维护性较为良好。

四、应用场景

简单工厂模式的核心在于一个根据不同的需要(参数的不同)创建不同的对象实例的工厂,但是由于每增加一个对象都要修改一次工厂类,因此该设计模式的可扩展性一般,适用于工厂生产的对象实例较少的情况

以上是关于简单工厂模式(simple-factory-pattern)的主要内容,如果未能解决你的问题,请参考以下文章

设计模式从青铜到王者第五篇:创建型模式之简单工厂模式( Simple Factory Pattern )

02 简单工厂模式

iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

JAVA设计模式——工厂模式简单工厂模式工厂方法模式抽象工厂模式

设计模式~简单工厂模式

设计模式----简单工厂模式