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

设计模式笔记(1)简单工厂模式

最近在看程杰的《大话设计模式》,在这里做一点笔记。

书中主要有两个角色:
小菜:初学者,学生;
大鸟:小菜表哥,大佬。
也按图中的对话形式

01 简单工厂模式

要求:使用c++、Java、C#或VB.NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。
小菜的代码:
小菜的代码
大鸟指出部分问题:

  1. A, B, C, D 这样的命名不规范;
  2. if的判断分支,逻辑有误,且未考虑除数输入为0/输入为字符非数字等等。

小菜对代码进行修改:
修改后的代码

修改后的逻辑基本没有问题了,但是并没有面向对象。
如何设计出容易维护,容易扩展,又容易复用的计算器程序呢?
程序要避免重复。
小菜:那就是分类,将计算和显示分开?
大鸟:准确说,是让业务逻辑与界面逻辑分开,让它们之间的耦合度下降。只有分离开,才可以达到容易维护或扩展。

接下来,小菜重新进行了尝试:
运算类:
运算类
main函数:

static void Main(string[] args)
{try{Console.Write("请输入数字A:");string strNumberA = Console.ReadLine();Console.Write("请选择运算符号(+、-、*、/):");string strOperate = Console.ReadLine();Console.Write("请输入数字B:");string strNumberB = Console.ReadLine();string strResult = "";strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA),Convert.ToDouble(strNumberB), strOperate));Console.WriteLine("结果是:" + strResult);Console.ReadLine();}catch (Exception ex){Console.WriteLine("您的输入有错:" + ex.Message);}
}​​

目前,无论在windows,还是在web,手机端都可以在需要运算时使用上面运算类的定义。
这里使用到的是“面向对象”的封装。

提问:如何更灵活的修改和扩展代码呢?比如,现在希望增加一个开根号(sqrt)的运算。
小菜:直接修改Operation类?
大鸟:但问题是,要加一个平方根运算,却需要让加减乘除的运算都得来参与编译。而且还可能让原有的运行良好的功能代码产生了变化,这个风险太大了

因此,需要尽量把加减乘除等运算分离,修改其中一个不影响其他
小菜进行新尝试:

operation运算类:

public class Operation
{private double _numberA = 0;private double _numberB = 0;public double NumberA{get  {  return _numberA;  }set  {  _numberA = value;  }}public double NumberB{get  {  return _numberB;  }set  {  _numberB = value;  }}public virtual double GetResult(){double result = 0;return result;}
}​​

两个Number属性,主要用于计算器的前后数,然后有一个虚方法GetResult(),用于得到结果。

加减乘法类:
加减乘法类
加减乘除都写成了运算类的子类,继承它后,重写了GetResult()方法,这样如果要修改任何一个算法,就不需要提供其他算法的代码了。
但是,如何让计算器知道我是希望用哪一个算法呢?

考虑用一个单独的类来做这个创造实例的过程,这就是“工厂”

进行如下设置:
实例化

此时,只需要输入运算符号,工厂就实例化出合适的对象。

一个实例:

Operation oper;
oper = OperationFactory.createOperate(“+”);
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();​​

此时,例如要修改加法运算,改OperationAdd即可。
如果需要增加各种复杂运算,增加相应的运算子类,并在switch中增加分支。

http://www.lryc.cn/news/594269.html

相关文章:

  • 基于单片机的自动条幅悬挂机
  • Linux文件系统底层原理:从磁盘物理结构到LBA寻址
  • MySQL锁(一) 概述与分类
  • springboot03-一个简单的SSMP框架
  • MySQL详解三
  • 详解Mysql HashJoin加速原理
  • 乐观锁实现原理笔记
  • LINUX入门(二)QT的安装及运行环境搭建
  • 虚拟机动态IP配置
  • HTTP1-HTTP2-HTTP3简要概述
  • Qt的安装和环境配置
  • Slack介绍(一款专注于企业协作的沟通平台,旨在通过整合聊天、文件共享、任务管理及第三方工具集成,提升团队的工作效率)
  • 【智能协同云图库】第一期:用户管理接口设计与功能实现
  • 统计与大数据分析和数字经济:专业选择指南
  • 数位 dp
  • kafka生产端和消费端的僵尸实例以及解决办法
  • NumPy 库的基本运用
  • 服务器上的文件复制到本地 Windows 系统
  • 语音识别技术:从声音到文字的 AI 魔法
  • 【Linux】权限详解 权限本质、权限属性、su、sudo提权、chmod\chown\chgrp、文件类别
  • 【软件测试】使用ADB命令抓取安卓app日志信息(含指定应用)
  • imx6ull-系统移植篇11——U-Boot 移植(下)
  • 第三章-提示词-中级:进阶技巧与实践指南(12/36)
  • #SVA语法滴水穿石# (014)关于链式蕴含的陷阱
  • 【Linux】1. Linux操作系统介绍及环境搭建
  • golang踩坑之url不会decode问题
  • 深度学习图像分类数据集—八种贝类海鲜食物分类
  • 秒赤Haproxy配置算法
  • 【RK3576】【Android14】显示屏MIPI开发调试
  • 2025.7.20总结-实战演讲