简单工厂模式(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"中新增一个运算类即可。

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

四、应用场景

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白龙码~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值