关于开闭原则的理解

手把手教你调试eDP接口:Main Link信号异常、AUXCH通信失败怎么办? 本文提供了一份详尽的eDP接口调试实战指南,重点解决Main Link信号异常与AUXCH通信失败两大核心难题。文章系统介绍了从工具准备、信号完整性分析(眼图、抖动测量)到AUXCH协议解码、HPD信号检查的完整排查流程,并分享了链路训练诊断与常见避坑技巧,帮助硬件工程师高效定位并解决显示问题。 阅读详情

开闭原则:设计一个模块的时候,应当使这个模块可以在不修改原有代码的前提下被扩展。

这个原则是保证系统具有扩展性的基本原则。我理解有几个要点:1、要能够复用;2、扩展时只增加新方法、新类;3、不得不修改代码时,修改的范围必须是局部的、隐藏的;

通常变更有三种方式,一种是横向变更,例如售票系统,原来只能售火车票,现在要可以售机票;第二种是纵向变更,例如在某个流程里插入新活动或跳过活动;第三种是局部修改,就是原有功能的业务规则发生了变化。对于前两种变更比较容易处理,只要在设计时注意抽象,通过接口、继承、override或event即可扩充。对于第三种变更,估计要修改代码了。虽然可以这样分类,但实际上以上三种变更通常是同时发生的、相互交织的。

以库存管理业务单据为例,有出库单、入库单、移库单等。通常单据结构都很相似,包含头表,行表,但个别字段有差异。新增一个单据,先在头表插入一条记录,然后在行表插入若干记录。更新单据时,先更新头表记录,然后清空词单据在行表里的原有记录,再插入新的行表记录,删除单据的过程也非常相似。此外,在单据增删改时要记录日志,在单据提交时,还要修改库存。所有这些操作十分相似,可以抽象出来。

现在要设计一个单据处理通用业务类,负责单据暂存、修改、提交、删除几个基本业务,以及相关的日志和库存操作。

1、分析
   单据操作: Save()/Submit()/Delete()/Log()/ChangeStock()
   相关数据: 头表实体、行表实体集;与日志有关的一些属性;与库存有关的一些属性;插入头表时,要有一个接口获取单据编号;因为插入行表时外键值需要用到头表记录的主键值,所以需要有个接口获取头表主键值,并有一个接口给行表实体的外键赋值;
   可能的变更: 1、将来可能增加审批功能,单据提交后审判通过才改变库存;2、增加新的单据类型;3、将来增加订单管理,那么库存操作除了出入库、还会增加在途转入库存、库存转出在途等功能。
  

2、设计
   方案1、抽象类+子类,只关注操作,不关注数据;
         单据处理类 BillProcess (抽象类):
         公有虚方法 Save()/Submit()/Delete()
         私有虚方法 Log()/ChangeStock()
   扩展:增加审批功能,只需在基类增加新的虚方法Audit,子类实现新的虚方法; 增加单据类型时,只需实现新的单据,增加在途功能,只需修改 ChangeStock;
   评价:此方案虽然很容易扩展,除了需要对ChangeStock作修改外,基本符合开闭原则;但过于抽象,子类需要实现全部操作,基类仅仅起到规范方法名称的作用;此方案的复用度太低;

   方案2、抽象类实现部分模板方法,所有方法都没有参数,抽象类没有任何字段,全部给子类实现;
         单据处理类 BillProcess (抽象类):
         公有虚方法 Save(): 调用IsNew()判断是新增还是更新,如果是新增,设置单据编号SetBillNumber,插入头表InsertHeader,设置行表外键SetBillLineHeaderID;若是更新,则更新头表UpdateHeader,删除行表DeleteLines(),设置行表外键SetBillLineHeaderID,插入行表InsertLines(); 调用 Log();
         公有虚方法 Submit(): 调用 Save(),调用 ChangeStock(); 调用 Log();
         公有虚方法 Delete(): 调用 DeleteHeader(),调用 DeleteLines(); 调用 Log();
        
         保护虚方法 IsNew,判断是新增单据还是更新单据;
         保护虚方法 SetBillNumber,设置头表单据编号;
         保护虚方法 SetBillLineHeaderID, 设置行表所属头表的外键值;
         保护虚方法 InsertHeader/UpdateHeader/DeleteHeader, InsertLines/DeleteLines
         保护虚方法 Log,记录操作员、操作时间、操作类型、单据编号;
         保护虚方法 ChangeStock,改变库存
   扩展:增加审批功能,需在基类增加新的虚方法Audit和NeedAudit虚属性,子类实现新的虚方法和虚属性; 增加单据类型时,只需实现新的单据,增加在途功能,需修改 ChangeStock;
   评价:此方案也很容易扩展,并且基类实现了部分操作,但子类要实现的方法过多,数据库访问方法其实只是表名有点差别,子类却要全部重写;另外子类 ChangeStock 仍要修改;此方案有一定的复用度,但也不高,而且每个子类的ChangeStock都要修改,不满足“开闭原则”的封闭性。

   方案3、一些通用的操作尽量放到 BillProcess,库存操作独立出来成为一个类;抽象出头表实体、行表实体接口;BillProcess可以操作相关数据接口。

         单据头实体接口 IBillHeader:
         BillID 获取或设置主键ID, 如果获取的ID为0,表示为新单据;这样就不需要IsNew()方法了
         BillType 获取单据类型
         BillNumber 获取或设置单据编号, 如果是新单据,BillProcess类可以向单据编号生成器BillNumberGenerator.GetBillNumber(BillType)传入BillType参数,获得单据编号,赋值给此属性;  
         DBField[] 获取实体的字段值数组,便于插入和更新到头表;

         单据行实体接口 IBillLine:
         BillID 设置所属单据头ID
         ProductID 商品ID
         SiteID 库位ID
         Count 商品数量
         DBField[] 获取实体的字段值数组,便于插入到头表;
        
        
         单据处理类 BillProcess (抽象类):
         保护虚属性: 头表名HeaderTableName、行表名LineTableName、头表主键名HeaderTablePKName、行表外键名LineTableFKName、单据类型BillType、头表实体接口IBillHeader、行表集合接口List<IBillLine> BillLines;单据编号 BillNumber;

         公有虚方法 Save(): 根据IBillHeader的BillID判断,如果是新增,调用BillNumberGenerator.GetBillNumber(BillType)获取新单据编号,并把单据号设置到头表实体,通过数据库会话类把头表实体DBField[]插入头表,设置行表外键BillID;若是更新,则数据库会话类用DBField[]更新头表,调用DeleteLines()删除行表记录,设置行表外键IBillLine的BillID,通过数据库会话类把行表实体DBField[]插入行表; 调用 Log();
         公有虚方法 Submit(): 调用 Save(),调用 ChangeStock(); 调用 Log();
         公有虚方法 Delete(): 调用数据库会话类删除头表记录,调用 DeleteLines(); 调用 Log();
         保护虚方法 DeleteLines(): 调用数据库会话类根据LineTableName、LineTableFKName删除行表记录
         保护虚方法 Log,记录操作员、操作时间、操作类型、单据编号;
         保护虚方法 ChangeStock,改变库存, 先调用GenerateStockChanges()把 List<IBillLine> 转为 List<StockChange>, 调用 StockProcess 实现库存操作,便于库存操作扩展
         保护虚方法 GenerateStockChanges(), 把 List<IBillLine> 转为 List<StockChange>;

         单据号生成器 BillNumberGenerator:
         生成单据号 GetBillNumber(BillType)

         库存处理类 StockProcess:
         属性 List<StockChange>, 库存操作数组

         库存改变类 StockChange: 商品ID 库位ID 库存量改变个数 (可扩充增加“在途量改变个数”)

    扩展:增加审批功能和新单据时,方法同方案1;增加在途量,需要扩展StockChange实体类和StockProcess业务类,BillProcess修改 GenerateStockChanges,子类不需要修改.
    评价:基类包含了较多实现,代码复用度高; 子类只需要实现 IBillHeader, IBillLine 和 一些属性即可(这些属性还可以配置到XML文件中,由BillProcess根据BillType读取XML配置信息,这样子类就不必关心这些细节,方便开发); 同时又保留了较强的扩展性,ChangeStock 方法被细化了,在扩充时,要修改的部分也只是底层的、局部的。不足之处是,基类过多地关注了细节,限制了扩展能力和变更的自由度;另外因为是要修改基类,影响的子类较多,需要投入较多的回归测试时间。此方案基本满足开闭原则。

      总体评价,方案3 提供了一个非常强大的业务基类BillProcess,但过于特殊化。目前的支持的流程是 暂存->提交->审批->改变库存,如果再增加一些中间环节,比如审批后增加发货环节,那么就又要修改BillProcess类了。还有,如果不同的单据有不同的流程,那么 BillProcess 就要增加大量属性信息来描述流程。有一种比较理想的设计思路是,把BillProcess变为“业务引擎”,把各种单据的流程配置到文件中,流程引擎读取这些配置信息执行对应的操作。这样增加一个单据或修改一个单据的流程,只需修改配置文件。实际上,这样有点像“依赖倒置”了,用框架来解决问题。


   

   

 

《深入浅出多模态》(四):多模态经典模型CLIP 本文为《深入浅出多模态》系列多模态经典模型CLIP,首先从整体介绍多模态模型发展,对其中经典CLIP模型进行详述,从具体论文、数据集、代码、模型结构、结果等角度分析,本专栏适合从事多模态小白及爱好者学习,欢迎大家关注,如有侵权请联系删除! 阅读详情

相关推荐

使用 Unity Sentis 和 Compute Shader,det_10g.onnx 进行高效人脸五官定位

在计算机视觉领域,人脸五官定位是一个重要的任务。本文将介绍如何使用 Unity Sentis 和 Compute Shader,结合模型,实现高效的人脸五官定位。我们将详细讲解每一步骤,并提供完整的代码示例。

m0_55632444的博客 2393

六大原则之开闭原则

1. 开闭原则的介绍 开闭原则(Open Closed Principle)是编程中最基础、最重要设计原则 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。 2. 违反开闭原则示例 package com.study; public class Ocp {

小松de博客 2万+

使用STM输出互补SPWM波(三相各差120°)

使用STM32输出SPWM波形(三相各差120°)

hello011102的博客 7373

七大原则——开闭原则

开闭原则的定义 开闭原则(Open Closed Principle,OCP)由勃兰特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向对象软件构造》(Object Oriented Software Construction)中提出:软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but c...

m0_37654408的博客 6608

FPGA以太网通信实战(一):实现MDIO接口驱动,掌控PHY芯片的钥匙

本文介绍了以太网通信技术及其核心组件。首先概述了以太网的发展历程,从标准以太网(10Mbps)到万兆以太网(10Gbps)的技术演进。重点分析了以太网接口的两大核心部件:MAC控制器负责数据链路层协议处理,PHY芯片负责物理信号转换和连接管理。文章详细解读了MDIO接口规范,包括帧格式和读写时序,并以YT8531 PHY芯片为例,介绍了其寄存器配置方法。最后设计了一个FPGA实现方案,通过MDIO接口完成PHY芯片的软复位和状态监测功能,并利用LED指示灯实时显示网络连接速率。

weixin_64402689的博客 1660

tiktok算法协议研究

经过上述分析,可以确定目标字符串来源于一段 JSON 数据,而这段 JSON 数据来自于一个经过加密的本地文件。对字符串 "sdi_v2" 进行 SHA-1 计算,得到 20 字节的结果;将第一步得到的数据进行MD5计算,生成16字节的结果;将第二步的结果转换为十六进制字符串,从而得到 32 字节的密钥。写这种算法分析的帖子真的是太无聊了,就先分析到这里吧,后续有机会再来谈下被加密的本地文件是怎么来的!!自我感觉TT的算法并不难,就是量太大了,所以我想问问有没有感兴趣的朋友来一起分析,欢迎联系。

2503_90751938的博客 2574

设计模式的六大基本原则(开闭原则、单一职责原则、里氏替换原则、接口隔离原则、依赖倒置原则、迪米特法则)

设计模式的六大基本原则(开闭原则、单一职责原则、历史替换原则、接口隔离原则、依赖倒置原则、迪米特法则)

聂可以的博客 1万+

第一章:信号链的精度之战:深入解决电流采样偏差

摘要:本文深入探讨了FOC控制中电流采样偏差问题及其解决方案。电流采样偏差主要来源于偏移误差、增益误差、非线性误差和温漂四大类,其中偏移误差对FOC性能影响最为严重。硬件方面建议采用高精度采样电阻、低失调运放和独立基准电压等设计;软件层面提出了上电自动零点校准、在线实时补偿和模型闭环补偿三种策略。最后介绍了量产自动化校准系统,通过硬件优化和软件补偿相结合,确保每台产品电流采样精度的一致性,为FOC控制奠定坚实基础。

汽车软件开发 602

开闭原则 (Open/Closed Principle, OCP)

开闭原则是面向对象设计中的基本原则之一,通过确保软件实体对扩展开放,对修改关闭,可以提高系统的稳定性、灵活性和可维护性。在实际开发中,遵循开闭原则有助于我们设计出高质量的代码,使系统更加健壮和易于扩展。希望这个博客对你有所帮助。如果你有任何问题或需要进一步的例子,请随时告诉我!

qq_42798343的博客 3355

智能筛选栏 SmartFilterBar 全面解析与实战指南

SmartFilterBar 把复杂的检索界面“模板化”,让开发者聚焦业务逻辑与后端数据质量,而非 UI 小细节。通过精准运用 CDS 注解与 OData 元数据,它能在几毫秒内拼装出专业级筛选体验;结合事件钩子与控制配置,又足以满足极端个性化需求。拥抱 SmartFilterBar,意味着在 Fiori 生态中以最少代码赢得最快价值交付——这正是现代企业应用开发追求的极致效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 402

一文看懂EMMC原理及工作过程

CMD:用于设备初始化和命令传输的双向通道, CMD信号有2种工作模式:1#:漏极开路--->用于初始化模式2#:推拉--->用于快速命令传输其中命令从eMMC主机控制器发送到eMMC设备,响应从设备发送到主机。DAT [7:0]:双向数据信号,模式包括:1(DAT0);默认情况下,通电或重置后,只有DAT0用于数据传输。DAT信号在推挽模式下工作,eMMC设备包括数据线DAT1-DAT7的内部上拉。进入4位模式后,设备立即断开线路DAT1、DAT2和DAT3的内部上拉;

Airer_00的博客 2029

【设计原则】开闭原则

开闭原则,在面向对象编程领域中,规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。

码农桶子哥的博客 1353

数据挖掘实战-基于KMeans算法对超市客户进行聚类分群

本实验基于KMeans算法对超市客户进行了聚类分群。通过对客户购物数据进行聚类,我们成功将客户分为不同的群体。每个群体代表了具有相似购物行为和偏好的客户群体。通过实验结果,我们发现了客户群体之间的明显差异和共性。不同群体的客户在购买频率、购物金额和购买种类等方面有所区别。这为超市提供了重要的市场细分信息,帮助超市经营者更好地了解不同客户群体的需求和喜好,制定有针对性的营销策略和商品推荐,提高客户满意度和忠诚度。此外,实验还揭示了超市客户的购物行为规律,为超市优化商品陈列和促销策略提供了指导。

m0_64336780的博客 2万+

深入理解设计原则之开闭原则(OCP)【软件架构设计】

开闭原则(Open Closed Principle, OCP),又称为对扩展开放、对修改关闭原则。开闭原则即是SOLID原则中最难理解、最难掌握的,又是最有用的。之所以说开闭原则最难理解,是因为“怎样的代码改动才被定义为扩展?怎样代码的改动才被定义为修改?怎样才算满足或违反开闭原则?修改代码就一定意味着违反开闭原则吗?等问题都比较难理解。之所以说开闭原则最难掌握,是因为如何做到对扩展开放,对修改关闭?如何在项目中灵活应用开闭原则避免在追求高扩展的同时影响代码的可读性等问题都很难掌握。

weixin_30197685的博客 2340

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

设计模式之----开闭原则(Open closed principle OCP)的理解

文章目录1.前言2.概念3.作用4.实现方法3.实例 1.前言 在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。首先介绍下什么是开闭原则? 2.概念 开闭原则(Open closed principle,OCP)由勃兰特·梅耶(Bertrand Meyer)提出,软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,bu

2949

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

我理解的开闭原则 Open-Closed Principle

在开发新的功能时我们常常会提到开闭原则,即一个类对于拓展是开放的,对于修改是关闭的,"open for extension but closed for modification"。有人可能会问拓展一个类的功能不就是要修改这个类吗?那开闭原则怎么会成立呢? 我的理解是当我们需要给一个类添加新的功能的时候,最好的办法不是直接修改这个类的代码,应该考虑用一个新类去实现新的功能。最终的效果是一...

qq_20694641的博客 503

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

理解OCP开闭原则和DIP依赖倒置原则

这样子就可以实现,当我去在调用时,总结使用多态传递相关的子类引用,那么就可以达到后期增加业务时,加代码,总结创建类,实现接口即可,不会去修改原有代码。但上面代码还不是很成功,当用户类型增加,那么工厂类是不是又要继续去switch...case了呢,此时我们只是提出传统写法是违反OCP开闭原则的。首先以一个例子引入,传统方法,不使用遵循OCP开闭原则的弊端。来改进代码,使其符合 OCP。那么如何去解决这个问题呢。通过引入一个抽象接口。

weixin_63855746的博客 313

谈谈开闭原则(OCP)的翻译问题和我的理解

OCP(Open-Close Principle):软件实体应该可以扩展,但不可以修改。 一开始看到开闭原则时,我觉得这个说法非常扯淡,还不是一般的扯淡。不能修改这个可能吗?人的认知和推动软件发展的硬件都是在进步的,你却在说不能修改。 而且从这个理论的提出时间:1988到今天2012-08-11,24年了有哪个软件做到了这个原则?! 但在后续的学习中发现很多文章都在说,而且我想我

blue_morning的专栏 1212

面试被问到如何理解开闭原则

但凡是面试中遇到问设计模式的时候,一定要提想法设法的提设计原则,阐述设计原则在开发中应用的重要性,对代码性能,系统拓展性的重要性,相信按照这篇文章阐述一番,面试官一定能发现你高深设计思想。 开闭原则是SOLID中最难理解、最难掌握,同时也是最有用的一条原则。 之所以说这条原则难理解,那是因为: 怎样的代码改动才被定义为‘扩展’? 怎样的代码改动才被定义为‘修改’? 怎么才算满足或违反‘开闭原则’? 修改代码就一定意味着违反‘开闭原则’吗? 等等这些问题,都比较难理解。 之所以说这条原则难掌握,那是因为:

斯巴达人的博客 279

开闭原则理解

今天看一个教程,里面提到了开闭原则,搜索了好几个网友的帖子,总结经验如下: 定义:一个软件模块如类、模块和函数应该对扩展开放,对修改关闭。 开闭原则强调了用抽象构建框架、用实现扩展细节。通常为了满足开闭原则,我们应该尽可能的面向抽象编程。 优点:提高软件系统的可复用性及可维护性。 具体例子:现在我们有一个课程接口,它有很多具体课程的实现类,我们可以通过具体的实现类来获取具体课程价格。 public...

元曦的博客 1511

开闭原则的理解与实践

开闭原则,简而言之,就是软件中的对象(类、模块、函数等)应该对于扩展是开放的,对于修改是封闭的。这一原则由Bertrand Meyer在1988年提出,它要求我们在设计软件时,应使软件实体能够在不修改其源代码的前提下进行扩展。换句话说,当需求发生变化时,我们应该通过添加新的代码来满足新的需求,而不是修改现有的代码。这一原则的核心思想在于,将软件实体的变化部分与不变部分相分离,通过抽象和封装来实现软件的灵活性和可扩展性。

huaqianzkh的专栏 1464

OCA、OCP、OCM理解

可能大家知道OCA、OCP、OCM的关系是一个比一个难考,一个比一个含金量高,但是你知道具体的考试科目、考试方式、就业形势区别吗?不知道的话这篇通俗易懂的文章会让你一目了然。   区别一:含金量   ■OCA:数据库专业人员踏上Oracle数据库认证之途的第一步   表示具备Oracle数据库管理的基础知识。   ■OCP:数据库专业人员掌握Oracle专项技术的行业认可证明,证明持证者能

wolf09311的专栏 1093

开闭原则-快速理解

定义 一个软件实体入,如类模块和函数应该对扩展开放,对修改关闭。我们应该把注意力集中在扩展开放和修改关闭这两个行为上。 扩展开放:可以扩展实现的细节,增加新的功能。 修改关闭:不修改原先定义的规则,尽量不修改源代码。 同时准寻这两个行为,即为遵循开闭原则。 开闭原则是面向对象设计中最基础的设计原则。 就比如:一个公司的上班时间是8小时,但是去上班的时间可以任意,早去上班早下班,晚去晚下班,只要满8...

BREATH57的博客 661

对开闭原则的一些理解

[size=large] 从开始学习J2EE开始,就一再地被灌输开闭原则多么核心多么重要,编码也两年了,回顾一下众多的设计模式,蓦然发现开闭原则几乎是所有设计模式的抽象总结 :o 。 一、依赖倒置模式(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的...

碧血丹心 270

开闭原则的理解

开闭原则,“软件实体应当对扩展开放,对修改关闭”,是要达到一个状态,而要达到这个状态,就需要在写代码的过程中要想到和做到。。。 提倡开闭原则,其目的是我们在编写代码的时候就要考虑到每个功能模块的潜在的变化的可能性,尽可能的写简短单一功能并且复用性强的模块。 只有在写代码的时候注意到了这些,在重构或者变更的时候,才能做到“对扩展开放,对修改关闭”。 引用一段百度百科中关于开闭原则实现的一段

mezheng的专栏 1283

php 开闭原则,深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP_javascript技巧...

前言本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第2篇,开闭原则OCP(The Open/Closed Principle )。开闭原则的描述是:Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.软...

weixin_32865039的博客 203
上一篇: 模拟星空的MFC源代码_Sky.RAR,下载地址:http://download.youkuaiyun.com/source/332601
下一篇: 基于AxWebBrowser实现完美的标签式浏览器,下载地址:http://download.youkuaiyun.com/source/337096
AppFramework
博客等级 码龄19年 61粉丝 29原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值