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

【设计模式】软件设计原则——开闭原则里氏替换单一职责

开闭原则内容引出

 

开闭原则

定义:一个软件实体,类,函数,模块;对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。可以提高软件的可复用性和可维护性。

开发新功能时,尽量不修改原有代码,尽量使用扩展来增加新功能。

实现开闭原则的核心思想是:面向抽象编程,而不是面向实现编程。

定义的对象类型是:抽象or接口;调用的是抽象类or接口中的方法。抽象是稳定的,让一个类依赖于抽象,实现对修改关闭。再通过面向对象的继承多态,实现对抽象的继承,通过重写方法or实现新的扩展方法。

开闭原则示例

/*** 商品接口*/
public interface IGood {Integer getId();String getName();Double getPrice();
}
/*** 普通商品*/
public class NormalGood implements IGood {private Integer id;private String name;private Double price;public NormalGood(Integer id, String name, Double price) {this.id = id;this.name = name;this.price = price;}@Overridepublic Integer getId() {return this.id;}@Overridepublic String getName() {return this.name;}@Overridepublic Double getPrice() {return this.price;}@Overridepublic String toString() {return "...普通商品信息"}
}
/**
添加打折功能
根据开闭原则 , 对修改关闭 , 对扩展开放;
定义子类,在继承普通商品的基础上,扩展的新功能;
不用实现接口,而是继承普通类。
站在会员卡角度如下:
card接口;普通用户类;银卡继承普通用户;金卡继承银卡
*/
public class DiscountGood extends NormalGood {public DiscountGood(Integer id, String name, Double price) {super(id, name, price);}@Overridepublic Double getPrice() {return super.getPrice() * 0.8;//折扣位置}
}

里氏替换原则

子类可以扩展父类的功能,但不能改变父类原有的功能。

是开闭原则的重要方式之一,由于使用父类对象的地方都可以使用子类对象,因此在程序中尽量使用父类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

public class FatherClass {public void method(HashMap map) {System.out.println("执行父类 void method(HashMap map) 方法");}
}public class ChildClass extends FatherClass {/*** 重写* 重写 ( 返回值 严格 ) : 当 子类的方法 重写 / 重载 / 实现 父类的方法时*      方法的 后置条件 ( 返回值 ) 要 比父类更严格或相等;*/@Overridepublic void method(HashMap map) {System.out.println("执行子类重写的 void method(HashMap map) 方法");}/*** 重载* 重载 ( 输入参数 宽松 ) : 子类的方法 重载 父类的方法 时*      方法的前置条件 ( 输入参数 ) , 要比 父类方法的输入参数更宽松 ;** 如果在父类中参数类型是 Map*      在子类中重载参数类型是 HashMap*      这样就会出现混乱的问题* 客户端调用时 , 可能不清楚情况 , 加入传入了 HashMap 参数*      此时就有可能出现混乱 , 无法调用到 父类/子类的 正常重写方法*      方法调用被重载方法拦截的情况** 如果 重载的方法 的参数 比父类的方法参数更严格*      那么这就不是重载方法 , 而是重写方法*/public void method(Map map) {System.out.println("执行子类重载的 void method(Map map) 方法");}}

 


 单一职责内容引出

单一职责

定义:不要存在多余一个导致类变更的原因。

假设有一个类,负责“A”和“B”;一旦需求变更,如A功能改变,修改该类A功能时,有可能导致B功能发生故障。对于该情况,应该对于AB各自建立独立的类,保证系统的稳定性。

开发方法:一个类只负责一项职责(类、接口、方法)

优点:可读性高、提高系统可维护性、降低类的复杂度、降低需求变更导致的风险。

模块化的系统中,都适合使用单一职责。

//以下代码均违反了单一职责原则
public class Dog{public void mainDogs(String name) {if ("小狗".equals(name)) {System.out.println("puppy's name is "+name);} else {System.out.println("Dog's name is "+name);}}
}//-----------------------------------------------------------------public class Order {private String orderId;private String userId;private String productId;private double amount;private OrderStatus status;public void createOrder(String userId, String productId, double amount) {// 创建订单  }public void payOrder() {// 支付订单  }public void shipOrder() {// 发货 }public void completeOrder() {// 完成订单 }
}

类的单一

/***本类的职责单一,只负责puppy*/
public class Puppy{public void IsPuppy(String name) {System.out.println("Puppy's name is "+name);}
}
public class Dog{public void IsDog(String name) {System.out.println("Dogs's name is "+name);}
}//--------------------------------------------------
// 订单接口
public interface Order {void create();void pay();void ship();void complete();
}// 创建类
public class OrderCreator implements Order {@Overridepublic void create() {// 创建订单的业务逻辑}
}...其他业务类// 订单完成类
public class OrderCompleter implements Order {@Overridepublic void complete() {
// 完成订单的逻辑}
}

方法单一

如果方法中存在大片的if-else说明是不完善的代码,而我们在开发中其实应该避免如is-else或者switch等条件语句。

//违反单一原则的代码
//如果只针对价格or名字or描述进行修改,会连带修改另外两个,存在一定风险
public class Good {public void updateGoodInfo(String name, double price,String description) {//更新商品信息逻辑}
}//修改后:
public class Good{public void updateGoodName(String Name){//修改名字}public void updateGoodPrice(String Name){//修改价格}public void updateGoodDescription(String Name){//修改商品描述}}

接口单一

public interface IGood {//获取名称String getName();//获取价格double getPrice();//获取商品描述String getDescription();//购买void buyGood();
}//-----------------------拆分------------------------
public interface IGoodInfo{//接口1,商品信息接口String getName();String getDescription();double getPrice();
}public interface IGoodManage{void buyGood();//接口2,商品操作接口//退换等其他逻辑
}//商品实现
publci class IGoodImpl implements IGoodInfo,IGoodManage{@Override//.....
}
http://www.lryc.cn/news/456422.html

相关文章:

  • 项目完整开发的流程
  • 性能测试学习6:jmeter安装与基本配置/元件/线程组介绍
  • 大数据ETL数据提取转换和加载处理
  • 物理与环境安全技术
  • 手把手教你如何配置好VS Code的WEB基础开发环境(保姆级)
  • 高性能、编译器编写语言、编程语言的高低贵贱
  • Python安装库时使用国内源pip install -i
  • Linux 再入门整理:详解 /etc/fstab 文件
  • 2.8 双绞线、同轴电缆、光纤与无线传输介质
  • OBOO鸥柏:布局于为无人机展厅行产业提供LCD液晶显示终端
  • win10状态栏中 “音量” 符号丢失,而在“打开或关闭系统图标”中音量开关无法调节的解决方法
  • Mysql 学习——项目实战
  • Springboot 整合 logback 日志框架
  • Hugging face简要介绍
  • A股知识答题pk小程序怎么做?
  • 单细胞转录组 —— kb-python 原始数据处理
  • 全同态加密算法概览
  • leetcode 刷题day38动态规划Part07 打家劫舍(198.打家劫舍、213.打家劫舍II、337.打家劫舍III)
  • C0010.Qt5.15.2下载及安装方法
  • 制造企业MES管理系统的应用策略与实施路径
  • Halcon 3D应用 - 胶路提取
  • 【Redis】Redis线程模型
  • Electron构建桌面应用程序,服务于项目的自主学习记录(持续更新...
  • linux Load Average 计算
  • pandas常用数据格式IO性能对比
  • 【D3.js in Action 3 精译_031】3.5.2 DIY实战:在 Observable 平台实现带数据标签的 D3 条形图并改造单元测试模块
  • 华为OD机试真题-字符串分割
  • 编程技巧:提高代码健壮性与可维护性的关键方法(以 Shell 为例)
  • 【无标题】ReadableStream is not defined
  • 【JVM】高级篇