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

简单工厂设计模式(计算器实例优化)

简单工厂设计模式(计算器实例优化)

  • 介绍
  • 为什么采用面向对象编程而不是面向过程呢?
  • 实例讲解
    • 业务层划分出来
    • 逻辑层
    • 继承
    • 简单工厂:(多态)
    • 业务层:(解耦合)
    • 主控制台
  • 总结

介绍

本文内容引用自《大话这设计模式》这本书第一章节简单工厂设计模式,供自己提高代码水平使用。
案例也同样采用计算器功能实现方式展开
实现功能---->封装---->继承---->多态---->面向对象

为什么采用面向对象编程而不是面向过程呢?

在当今互联网开发的大型企业中你会发现,当你接到一个功能模块的时候不会给你完整的项目源码,特别是核心的东西,为什么呢?

仔细想一下,如果公司把员工薪资分发系统让你修改,这时你动了一下坏心思,做了一层 If 判断,如果名字是自己的话薪资*2,是不是公司就赔了?况且公司也不会这么傻,把这种核心的功能让新手做修改,这就引入代码的面向对象,将代码分为逻辑层和业务层分开处理,这样不仅逻辑清晰方便后期的修改,也方便了公司为自身的保护。

实例讲解

我们创建一个主控制台,先用一个面向过程的编程方式去写一个计算器功能,代码如下

while (true){try{Console.WriteLine("请输入第一个数字一");double number1 = double.Parse(Console.ReadLine());Console.WriteLine("请输入运算符");string symbol = Console.ReadLine();Console.WriteLine("请输入第一个数字二");double number2 = double.Parse(Console.ReadLine());switch (symbol){case "+":Console.WriteLine(number1 + number2);break;case "-":Console.WriteLine(number1 - number2);break;case "*":Console.WriteLine(number1 * number2);break;case "/":if (number2 == 0d){Console.WriteLine("被除数不能为0");break;}Console.WriteLine(number1 / number2);break;default:break;}}catch (Exception ex){Console.WriteLine(ex);}}

这时候我们分析一下

  1. 首先逻辑是没有问题的,如果后期修改怎么办?是否需要将完整的代码拿出来修改?
  2. 如果我们后期需要增加一个开平方根,时候会影响了其他运算的逻辑?
  3. 如果我们现在需要开发另外一个平台的计算器功能,我们能都将这个代码拿过去直接复用?

先回答第一个问题,这个代码比较简单,修改起来也比较方便,但是如果项目需求比较大,我们可能会话费很长时间去找当时写的代码,这时候会非常话费时间,那么我们可以将逻辑层和业务层分开,代码如下

业务层划分出来

public class Operation{public static double GetResult(double number1,double number2,string symbol) {double result = 0;switch (symbol){case "+":result = number1 + number2;break;case "-":result = number1 - number2;break;case "*":result = number1 * number2;break;case "/":if (number2 == 0d){Console.WriteLine("被除数不能为0");break;}result = number1 / number2;break;default:break;}return result;}}

逻辑层

while (true){try{Console.WriteLine("请输入第一个数字一");double number1 = double.Parse(Console.ReadLine());Console.WriteLine("请输入运算符");string symbol = Console.ReadLine();Console.WriteLine("请输入第一个数字二");double number2 = double.Parse(Console.ReadLine());double result = Operation.GetResult(number1,number2,symbol);Console.WriteLine("结果为"+result);}catch (Exception ex){Console.WriteLine(ex);}}

这时候是否显得比较整洁,之后修改的时候我们直接使用Operation这个脚本修改即可

回答第二个问题

如果这时候我们需要增加一个需求,当我们做➕法运算的时候,我们得到的值始终是要多➕2的,这时候我们如果按照当前的方法修改的话,我们需要改动Operation这个类中的GetResult方法即可,但是这个方法里面包含了4个逻辑算式,如果这时候不小心动了其他的怎么办?所以这时候我们就要引入面向对象知识,封装,继承,多态的方式去修改当前代码。代码如下

public class Operation{private double m_number1;private double m_number2;public double Number1 { get { return m_number1; } set { m_number1 = value; } }public double Number2 { get { return m_number2; } set { m_number2 = value; } }public virtual double GetResult() {double result = 0;return result;}}public class Add : Operation {public override double GetResult(){double result = Number1 + Number2;return result;}}public class Subtract : Operation{public override double GetResult(){double result = Number1 - Number2;return result;}}public class Multiply : Operation{public override double GetResult(){double result = Number1 * Number2;return result;}}public class Divide : Operation{public override double GetResult(){if(Number2 == 0)throw new Exception("除数不能为0");double result = Number1 / Number2;return result;}}

继承

修改业务层层,增加两个属性,并且重写一个方法,在定义四个不同的运算符类,分别继承业务层Operation,根据不同的方式重写基类方法

这里回答第三个问题

如何复用我们当前写的东西呢?这里可能对于刚开始编程的人来说不会区分对象,这里我们将每一个运算式分别定义一个对象,然后这里的每一个对象分别有两个属性,数字一和数字二,这样理解就比较清晰,既然明白了对象,我们就将面向对象的多态简单工厂设计模式引入到里面,从而达到我们所写代码的复用性,代码如下:

简单工厂:(多态)

public static Operation CreateOperation(string symbol) {Operation oper = null;switch (symbol){case "+":oper = new Add();break;case "-":oper = new Subtract();break;case "*":oper = new Multiply();break;case "/":oper = new Divide();break;default:break;}return oper;}

业务层:(解耦合)

public class Operation{private double m_number1;private double m_number2;public double Number1 { get { return m_number1; } set { m_number1 = value; } }public double Number2 { get { return m_number2; } set { m_number2 = value; } }public virtual double GetResult() {double result = 0;return result;}}public class Add : Operation {public override double GetResult(){double result = Number1 + Number2;return result;}}public class Subtract : Operation{public override double GetResult(){double result = Number1 - Number2;return result;}}public class Multiply : Operation{public override double GetResult(){double result = Number1 * Number2;return result;}}public class Divide : Operation{public override double GetResult(){if(Number2 == 0)throw new Exception("除数不能为0");double result = Number1 / Number2;return result;}}

主控制台

class Program{static void Main(string[] args){while (true){try{Console.WriteLine("请输入第一个数字一");double number1 = double.Parse(Console.ReadLine());Console.WriteLine("请输入运算符");string symbol = Console.ReadLine();Console.WriteLine("请输入第一个数字二");double number2 = double.Parse(Console.ReadLine());Operation oper;oper = OperationFactory.CreateOperation(symbol);oper.Number1 = number1;oper.Number2 = number2;Console.WriteLine("结果为"+oper.GetResult());}catch (Exception ex){Console.WriteLine(ex);}}}}

总结

巧妙的使用面向对象的封装继承和多态会让我们后期的维护节约不少时间,提高了开发的效率,当我们将代码移植到别的平台的时候,我们只需要将业务层Operation 和 OperationFactory移植即可方便调用。

相关文章:

简单工厂设计模式(计算器实例优化)

简单工厂设计模式(计算器实例优化) 介绍为什么采用面向对象编程而不是面向过程呢?实例讲解业务层划分出来逻辑层继承简单工厂:(多态)业务层:(解耦合)主控制台 总结 介绍 …...

iconify图标集离线使用方案简介

1.需求描述 前端项目,技术栈使用Vue3Element Plus,参考了ruoyi-vue-pro项目与vue-element-plus-admin项目,封装了一个Icon组件,图标使用的是iconify,项目部署在内网环境,不能连接互联网,需要部署一套iconi…...

java基础之理解多态

目录 简单理解 满足多态的三个条件 有类继承或者接口实现 子类要重写父类的方法 父类的引用指向子类的对象。 代码示例 动态多态 静态多态 个人观点 简单理解 简单理解就是,同一操作作用于不同的对象,可以有不同的解释,产生不同的执…...

第二证券:A股市场放量反弹 跨年行情或启动

沪指日线等级放量反弹,周四收中阳线成功站上20日均线,底部结构或可树立。创业板指大涨近4%,日线MACD出现底违反,多方动能较强,中等级反弹行情或在酝酿。月线来看,12月创业板指探底上升出现较长下影&#xf…...

web漏洞与修复

一、web漏洞 检测到目标X-Content-Type-Options响应头缺失 详细描述X-Content-Type-Options HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIM…...

基于Java+SpringBoot+vue实现图书借阅管理系统

基于JavaSpringBootvue实现图书借阅和销售商城一体化系统 🍅 作者主页 程序设计 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 文章目录 基于JavaSpringBootvue实现图书借阅和销售商城一体化…...

xml文件学习(xml格式)可扩展标记语言(Extensible Markup Language)

XML 教程 文章目录 XML 文件学习1. XML 概述1.1 什么是 XML?1.2 XML 有什么作用? 2. XML 基本结构1. 声明2. 元素3. 属性4. 文本5. 注释 3. XML 高级知识3.1 XML 命名空间3.2 XML 架构3.3 XML 工具3.4 XML 技术 4. XML 应用实例 XML 文件学习 XML&#…...

nodejs+vue+ElementUi家政服务系统c90g5

项目中登录模块用到token家政服务平台有管理员,雇主,雇员三个角色。管理员功能有个人中心,雇主管理,雇员管理,资料认证管理,项目类型管理,服务项目管理,需求信息管理,服务…...

数据库(Database)基础知识

什么是数据库 数据库是按照数据结构来组织、存储和管理数据的仓库,用户可以通过数据库管理系统对存储的数据进行增删改查操作。 数据库实际上是一个文件集合,本质就是一个文件系统,以文件的方式,将数据保存在电脑上。 什么是数据…...

QT应用篇 二、QML用Image组件实现Progress Bar 的效果

QT应用篇 一、QT上位机串口编程 二、QML用Image组件实现Progress Bar 的效果 三、QML自定义显示SpinBox的加减按键图片及显示值效果 文章目录 QT应用篇前言一、qml需求二、使用组件1.Image组件2.Image中fillMode的使用例子 总结 前言 记录自己学习QML的一些小技巧方便日后查找…...

SElinux工作原理简介并演示chcon、semanage、restorecon的使用方法

目录 一.SElinux工作原理简介 1.system_u 2.object_r 3.httpd_sys_content_t 4.s0 二.SElinux策略的具体使用详情 1.restorecon 2.semanage 3.chcon 一.SElinux工作原理简介 通过mac方式管理进程,管理的目标是进程是否具有读取权限的文件(文件…...

表情串转换

前言 NWAFU 2021阶段二 D 一、题目描述 题目描述 在一个字符串中,设置了由‘/’前导字符和某些特定字母构成的转义子字符串,如“/s”、“/f”、“/c”等用于表示特殊表情符号。现要求编写一个函数,将给定字符串中的转义字符串转换为表情字…...

【娱乐小技巧】网页旋转90° 3步搞定

一、按F12,打开控制台; 二、点击号; 插入新body; 三、粘贴代码 -webkit-transform: rotate(90deg);小结,角度值可以自选; 代码的效果:...

移动管理系统软件哪家好?它是如何帮助企业降本增效的?

现在很多管理系统都可以用移动设备接入,最常见的就是手机。只要给管理系统创建一个微信小程序接口,那么要使用系统功能的时候直接打开微信小程序就可以了。例如我们小区的物业巡检就是通过微信扫码打开巡检工单记录信息的,直接用巡检保安自己…...

电脑表格文件丢失如何找回?3个方法拯救丢失的文件!

“太难了!我辛辛苦苦在电脑上做的表格,不知道什么原因突然就没有了,有什么方法可以找回丢失的表格文件吗?快帮帮我吧!” 在日常工作中,很多电脑用户可能都会用到表格文件,这往往记载了大量的重要…...

VSCode 如何安装插件的历史版本

背景 在日常开发过程中,我们可能会遇到新版VSCode插件存在问题,无法正常工作的情况。这种情况下,一种可行的解决方案就是安装插件的历史版本。VSCode 插件默认安装的都是插件最新的版本,例如下面 vscode-styled-compoents 插件 本…...

关于edge浏览器以及插件推荐

目录 广告拦截和隐私工具 密码管理器 生产力和组织工具 写作和语法工具 购物助手 娱乐和个性化 安全性和VPN 开发者工具 其他实用工具 Microsoft Edge 是一款基于Chromium开源项目的现代网络浏览器,由微软开发。它是Internet Explorer的继任者,…...

Vue Tinymce富文本组件自定义操作按钮

想实现如下效果 首先在init方法中的增加一插件 增加一个setup方法 代码 setup: function(editor) { editor.ui.registry.addButton(testButton, {text: 日记日期,tooltip: 插入日记日期,onAction: () > editor.insertContent("123456")});}, 操作效果&#xff0…...

论文阅读:Blind Super-Resolution Kernel Estimation using an Internal-GAN

这是发表在 2019 年 NIPS 上的一篇文章,那个时候还叫 NIPS,现在已经改名为 NeurIPS 了。文章中的其中一个作者 Michal Irani 是以色 Weizmann Institute of Science (魏茨曼科学研究学院) 的一名教授,对图像纹理的内在统计规律有着很深入的研…...

韩国Neowine车规认证加密芯片ALPU-CV

由工采网代理的ALPU-CV是韩国Neowine(纽文微)推出的一款高性能车规级加密芯片;也是ALPU系列中的高端IC,该芯片通过《AEC-Q100》认证,目前已经在国产前装车辆配件量产使用,主要用于版权license保护、设备防伪…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

ESP32读取DHT11温湿度数据

芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂&#xff…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...