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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

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

文章目录

一、简单计算器的设计

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

#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 model
  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"中新增一个运算类即可。

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

四、应用场景

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6