当前位置: 首页 > 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保护、设备防伪…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​,覆盖应用全生命周期测试需求,主要提供五大核心能力: ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...