Java设计模式中的七大原则详细讲解
作者:非凡的小笨鱼 发布时间:2021-07-23 15:38:14
设计模式要进行共性与可变性的分析,对共性进行抽象,同时对可变性进行封装,没有完美的设计模式,作为一名开发者要懂得取舍,触类旁通,开发出高内聚、低耦合、灵活性更高的软件产品
1.开闭原则(软件设计第一原则)
定义:一个软件实体应该对扩展开放,对修改关闭,即在不修改源代码的基础上扩展软件功能
本质思想:
以抽象来固定不变的东西(把固定不变的抽出来)
使用具体实现对可变性进行封装/隐藏
面向抽象编程
2.依赖倒置原则
开闭原则是目标,依赖倒置是手段
三层含义:
高层模块不应该依赖于低层模块,两者都应该依赖其抽象(例如一个类的成员变量、方法的入参、返回值不应该是一个具体类,而最好是一个抽象类)
抽象不应该依赖细节(业务代码不关心具体类)
细节应该依赖抽象(业务代码只关心抽象类)
依赖倒置原则的核心就是面向抽象(抽象类或者接口)编程
3.里氏替换原则
定义:在一个软件产品中,父类对象可以出现的地方,都可以替换成它的子类对象,且不能发生错误和异常,里氏替换原则为良好的继承定义了规范
四层含义:
子类必须完全实现父类的抽象方法,但不能覆盖(重写)父类的非抽象方法
子类可以增加自己特有的方法
当子类一定要重写父类的方法时,子类方法的形参(前置条件)要比父类更宽松(例如父类使用HashMap,子类使用Map)
当子类实现父类的抽象方法时,方法的返回值(后置条件)要比父类更加严格
总结:子类可以扩展父类的功能,但是不能去改变父类原有的功能(遵循父类原有的基础特性,进行一系列的行为变化)
4.合成复用原则
定义:在软件复用时,要尽量使用组合/聚合(has a)等关联关系来实现,即组合/聚合优先于继承
如果要使用继承关系,则必须严格遵循里氏替换原则
合成复用原则和里氏替换原则是相辅相成的,两者都是开闭原则的具体实现规范
设计模式用继承对行为变化进行分类,而不是使用继承来复用逻辑
继承破坏了类的封装性,父类的实现细节全都暴露给子类了
父类和子类的耦合性太高,父类的修改直接影响子类
继承是静态的,与IOC动态注入相违背
5.接口隔离原则
定义:使用多个专门的接口,而不是使用单一的总接口;客户端调用者代码不应该依赖它不需要的接口
使用原则:
根据接口隔离原则拆分接口时,首先必须满足单一职责原则
提高高内聚(每个接口都只负责相互独立的部分,方法间都是强相关的)
定制服务
接口设计要有限度(不要让类过于膨胀)
目标:在发生代码变更,接口变更的情况下,尽量做到影响程度最低
6.迪米特法则
规则:一个类应该尽量少的对其他类相互作用(依赖/调用)
解释:只与直接朋友(私有成员变量、方法入参、new的对象)进行通信,间接朋友:调用直接朋友的方法获取到的对象
目的:让类之间解耦,提高类的复用性,当其他类发生变更的时候,对这个类的影响才最小
缺点:过于严格的遵守此原则,会导致系统产生大量透明的小方法,需要在朋友数量和小方法之间进行权衡
通过下面的例子加深理解,Person类想调用Stranger类执行一些逻辑
public class Person {
private Friend friend = null;
// 遵循迪米特法则
// 将Stranger类封装/隐藏了,Person类不知道Stranger类的存在
// 但是Friend类产生了callStrangerDoSomething这个透明的小方法
public void right(){
friend.callStrangerDoSomething();
}
// 不遵循迪米特法则
// 与Stranger类耦合了
public void wrong(){
Stranger stranger = friend.getStranger();
stranger.doSomething();
}
}
7.单一职责原则
单一职责原则要求一个接口或类只有一个原因引起变化(职责的范围因人而异)
一个接口或一个类只负责一件明确的事,负责的事情越少越好
如果其他类依赖了一个包含多个职责的类,也会将不需要的职责包含进来,也违反了迪米特法则
来源:https://blog.csdn.net/a347635191/article/details/121960915


猜你喜欢
- 本文首先将会回顾Spring 5之前的SpringMVC异常处理机制,然后主要讲解Spring Boot 2 Webflux的全局异常处理机
- 1、long long 和 __int64在C++ Primer当中提到的64位的int只有long long,但是在实际各种各样的C++编
- #region 监视文件夹的变化
- 加载网络图片Image.network()是Flutter提供的一种从网络上加载图片的方法,它可以从指定的URL加载图片,并在加载完成后将其
- 首先打开 Visual Studio Installer 可以看到vs2022 只支持安装4.6及以上的版本,如图所示。那么该如何安装4.6
- 本文介绍如何在使用C#开发WinForm程序时,获取程序文件的物理路径。这个物理路径可以用于定位程序所在的目录,从而进行日志创建等扩展操作。
- Android 实现记住用户名和密码的功能是通过SharedPreference 存储来实现的。创建一个复选按钮,通过按钮的否选取来进行事件
- 错误信息Exception in thread "main" java.lang.ClassCastException:
- 在上个星期阿里巴巴一面的时候,最后面试官问我如何把一篇文章中重复出现的词或者句子找出来,当时太紧张,答的不是很好。今天有时间再来亲手实现一遍
- 本文实例讲述了WinForm实现自定义右下角提示效果的方法。分享给大家供大家参考。具体实现方法如下:using System;using S
- 在新版的AndroidStudio3.6 中,在项目的包下新建 activity 时,一般会同时生成对应的java和xml文件,例如新建 M
- System.Collections.ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。一.优点1. 支持
- 1.下载JDK查看最新:http://www.oracle.com/technetwork/java/javase/downloads/in
- DSA数字签名,供大家参考,具体内容如下一、实验目的在掌握了ElGamal和Schorr数字签名算法的基础上,进一步地学习和掌握DSA签名算
- 1.object.toString()方法这种方法要注意的是object不能为null,否则会报NullPointException,一般别
- void UpdateContactSign() {&n
- 本文实例为大家分享了java实现Dijkstra算法的具体代码,供大家参考,具体内容如下1 问题描述何为Dijkstra算法?Dijkstr
- Map接口Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;Map中的
- 前言在segmentfault上看到一个问题:java有完善的GC机制,那么在java中是否会出现内存泄漏的问题,以及能否给出一个内存泄漏的
- 目前很多业务使用微服务架构,服务模块划分有这2种方式:服务功能划分业务划分不管哪种方式,一次接口调用都需要多个服务协同完成,其中一个服务出现