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

Java设计模式之设计原则

Java设计模式

Java设计模式主要原则是开闭原则,即对扩展开放,对修改关闭。由此衍生出5大原则:单一职责原则,里式替换原则,迪米特原则,接口隔离职责,依赖倒置原则。

1、开闭原则

开闭原则:对扩展开放,对修改关闭。一个接口,特别是底层接口或者抽象类,
从诞生后起,要尽可能少改动它,因为一旦改动,所有引用它的类或者接口都会收到影响。需要做回归测试,所有软件也需要重新测试。这会带来巨大的代价。如果知识做扩展,除了扩展新增功能需要做测试外,接口原有实现都不用改动。

单一职责原则

接口或者抽象类职责要单一,不要是很多功能的复合体。比如我有一个用户接口UserInfo,它既负责维护用户属性,也负责定义用户行为。这就违背了单一职责原则,接口的实现类那必然实现用户所有功能,后面扩展行为,或者属性势必会影响整个接口,影响面也会更大。

里式替换

简单说就是使用任意子类可以替换父类,程序依然成立,即原有输入和输出类型依然不变。

迪米特

Java class要尽可能暴露少的method,field给外部。即多使用private protected 等关键字约束访问权限。同时在编写程序时 class只和直接接触的对象有耦合,对于不直接接触的对象不要产生耦合。示例如下
场景:老师让那个体育委员清点女生人数

示例一:女生是teacher的参数

public class Teacher {
//老师对学生发布命令,清一下女生
public void commond(GroupLeader groupLeader){
List listGirls = new ArrayList();
//初始化女生
for(int i=0;i<20;i++){
listGirls.add(new Girl());
}
//告诉体育委员开始执行清查任务
groupLeader.countGirls(listGirls);
}
}

示例二:女生作为体育委员的参数

public class Client {
public static void main(String[] args) {
//产生一个女生群体
List<Girl> listGirls = new ArrayList<Girl>();
//初始化女生
for(int i=0;i<20;i++){
listGirls.add(new Girl());
}
Teacher teacher= new Teacher();
//老师发布命令
teacher.commond(new GroupLeader(listGirls));
}
}

通过示例一和二的比较,明显可以发现示例二有更好的扩展性,老师和女生无直接关系,示例二从老师的角度只知道GroupLeader类,而不需要定义Girl,不管Girl有任何变动,只需要对GroupLeader做相应调整,而teacher不用动。降低耦合,增强扩展性。

接口隔离职责

接口隔离可以看作单一性原则的再度细化,比如上面的UserInfo接口,被拆分为用户属性接口和用户行为接口,用户行为接口kennel会定义很多行为,打游戏,开车,打球,逛街。等等,这些都属于用户行为,但是过多的行为可以再次划分,让用户属性和各种独特行为结合变成特定的人,这样就实现接口隔离。示例待添加。

依赖倒置

先说明依赖正置:如下,张三会开车,因为张三有奔驰,所以方法直接传入奔驰车。

public class Client {
public static void main(String[] args) {
Driver zhangSan = new Driver();
Benz benz = new Benz();
//张三开奔驰车
zhangSan.drive(benz);
}
}

后面章三买了辆宝马,但是宝马和奔驰没关系,因此张三必须新写一个方法来实现开宝马。这种直接传入实现类的方法没有扩展性。如果方法参数是car,那么不管张三买几辆车,都能动态传入。即面向接口编程,也就是依赖倒置。
依赖倒置做到极限就是控制反转,如Spring,所有类的创建都是用一套接口,大大降低了耦合性,同时也带来了对象创建的成本开销。但由于是启动创建,因此损耗的是启动性能,而非运行性能。

http://www.xdnf.cn/news/684775.html

相关文章:

  • 莫毅明和钟家庆数学命题证明使用的预期理由和或然推理的错误
  • 使用JAVA 语言中 JNA 和 PDU 的区别
  • 深兰科技陈海波率队考察南京,加速AI医诊大模型区域落地应用
  • Python爬虫(40)基于Selenium与ScrapyRT构建高并发动态网页爬虫架构:原理、实现与性能优化
  • vscode 配置 QtCreat Cmake项目
  • 文件上传绕过方法总结
  • Deep Evidential Regression
  • 【AUTOSAR】时间保护(Timing Protection)概念、应用与实现源代码解析(上篇)
  • 大模型三大缺陷与RAG破解之道
  • vue3基本类型和对象类型的响应式数据
  • Disruptor—核心源码实现分析(三)
  • 解决开机必须联网的问题并关闭windows搜索页面的推荐
  • MES生产管理系统:Java+Vue,含源码与文档,集成生产信息,实现计划、执行与监控高效协同
  • Foupk3systemX5OSNTXPro引擎
  • 一键重装Windows/Linux系统,支持虚拟服务器
  • Java并发编程中的锁分类
  • AD-PCB--AD20软件安装及中英文切换 DAY 2
  • 链表题解——相交链表(力扣160 easy)
  • 树莓派安装中文字体和中文输入法
  • 【Qt开发】容器类控件
  • Python深度挖掘:openpyxl与pandas高效数据处理实战
  • 洛谷P1165—— 日志分析
  • java中的定时期
  • Linux换源yum和安装nginx,mysql
  • 做好测试用例设计工作的关键是什么?
  • 直角坐标方程、参数坐标方程、极坐标方程
  • 【数据结构与算法】模拟
  • C52-二级指针
  • proteus8.4 安装包下载地址与安装教程
  • 开源项目asp本地编译安装教程(ubuntu操作系统)