当前位置: 首页 > news >正文

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

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

文章目录

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

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

四、应用场景

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

相关文章:

  • 做视频网站怎么对接云盘/商丘网络推广哪家好
  • 做网站外包大学生/站长工具网站排名
  • 网站建设方式/做一个私人网站需要多少钱
  • 网站优化推广公司/免费新闻源发布平台
  • html5电影网站设计论文/交换友情链接吧
  • 那家b2c网站建设报价/近期网络营销的热点事件
  • 图片怎么转jpg?教你两个超简单的图片转jpg格式的方法
  • [C语言]通讯录
  • Python NumPy 数组索引
  • VulnHub2018_DeRPnStiNK靶机总结
  • 聚观早报|春节档新片预售总票房破千万;苹果获可折叠iPhone新专利
  • 一文吃透python面向对象基础+进阶
  • Java 日志框架 JUL
  • Revit问题:降板表面填充图案和构件上色
  • 【html页面引入vue页面】使用httpVueLoader.js让html页面引入vue文件当组件使用,html组件化开发
  • 【Nginx01】Ngnix入门
  • 智能边缘网关
  • Spring REST风格