• 【设计模式】设计模式基础


    设计模式基础

    一、七大设计原则

    1.1 概述

    设计模式是为了让程序(软件),具有更好代码重用性,可读性,可扩展性,可靠性。使程序呈现高内聚,低耦合的特性。

    设计模式原则,其实就是程序员在编程时,应当遵守的原则,也是各种设计模式的基础(即: 设计模式为什么这样设计的依据)

    1. 单一职责原则
    2. 接口隔离原则
    3. 依赖倒转(倒置)原则
    4. 里氏替换原则
    5. 开闭原则
    6. 迪米特法则
    7. 合成复用原则

    1.2 单一职责原则

    一个类应该只负责一项职责,如实体类,实体类中不应进行其他业务操作。

    举例,比如在一个绘图系统中,定义一个矩形类,类中包含了长、宽,同时定义了一个绘制矩形的方法,在这个方法中难免要使用到GUI库的引用,这会导致程序在加载矩形类的时候也消耗链接、编译时间、内存空间和存储空间等。其次在绘制矩阵方法中,绘制方法中可能用到自定义的绘制方法,当有需求要更改自定义的绘制方法时,就强制要求将矩形类也要重新编译,测试及部署。

    职责的统一需要根据业务和需求来判断,识别出同一种类型的职责,这也是比较难的一点。

    1.3 接口隔离原则

    一个类对另一个类的依赖应该建立在最小的接口

    当一个类依赖于某个接口的部分方法,而不是全部方法时,应考虑将接口拆分,而不是增加多余的空实现

    1.4 依赖倒转原则

    依赖倒转(倒置)的中心思想是:面向接口编程,比如接收信息,只依赖于接收信息接口,在后续增加接收信息的方式时,调用方无需修改代码即可无缝衔接

    1. 高层模块都不应依赖底层模块的实现,而应只依赖于抽象
    2. 抽象也不应该依赖于细节,细节应该依赖于抽象
    3. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

    依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在 java 中,抽象指的是接口或抽象类,细节就是具体的实现类

    1.5 里氏替换原则

    问题提出:在编程中,如何正确的使用继承? => 里氏替换原则

    继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏。

    继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。

    1. 如果对每个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。换句话说,所有引用基类的地方必须能透明地使用其子类的对象
    2. 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
    3. 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过 聚合,组合,依赖 来解决问题

    1.6 开闭原则

    开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

    1. 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节即创建多个实现类实现不同细节。
    2. 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
    3. 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。

    1.7 迪米特法则

    迪米特法有个简单的定义:只与直接的朋友通信

    直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

    1. 一个对象应该对其他对象保持最少的了解
    2. 类与类关系越密切,耦合度越大
    3. 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息

    1.8 合成复用原则

    原则是尽量使用组合/聚合的方式,而不是使用继承

    二、UML类图

    2.1 概述

    Uml图种类:

    1. 用例图
    2. 静态结构图:类图、对象图、包图、组件图、部署图
    3. 动态行为图:交互图(时序图与协作图)、状态图、活动图

    针对于设计模式,必须先弄懂类图

    1. 用于描述系统中的类(对象)本身的组成和类(对象)之间的各种静态关系
    2. 类之间的关系:依赖、泛化(继承)、实现、关联、聚合与组合

    2.2 依赖关系(Dependence)

    只要是在类中用到了对方,那么他们之间就存在依赖关系。如果没有对方,连编绎都通过不了

    public class PersonServiceBean {
    	private PersonDao personDao;
    	public void save(Person person){}
    	public IDCard getIDCard(Integer personid){}
    	public void modify(){
    		Department department = new Department();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对应关系:虚线普通箭头

    在这里插入图片描述

    2.3 泛化关系(generalization)

    泛化关系实际上就是继承关系,它是依赖关系的特例

    public class PersonServiceBean extends Daosupport{
    }
    
    • 1
    • 2

    对应关系:实线空心箭头指向类

    在这里插入图片描述

    2.4 实现关系(Implementation)

    实现关系实际上就是 A 类实现 B 接口,它是依赖关系的特例

    public class PersonServiceBean implements PersonService {
    	public void delete(Interger id){}
    }
    
    • 1
    • 2
    • 3

    对应关系:虚线空心箭头指向接口

    在这里插入图片描述

    2.5 关联关系(Association)

    类与类之间的联系,它是依赖关系的特例

    关联具有导航性:即双向关系或单向关系

    关联具有多重性:如“1”对“多”,“多”对“多”

    单向 1 对 1 关联关系:

    public class Person {
    	private IDCard card;
    }
    
    • 1
    • 2
    • 3

    双向 1 对 1 关联关系:

    public class Person {
    	private IDCard card;
    }
    // 另一个文件
    public class IDCard{
    	private Person person;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对应图:

    • 单向:实线普通箭头加数字
    • 双向:实线直线加数字

    在这里插入图片描述

    2.6 聚合关系(Aggregation)

    聚合关系(Aggregation)表示的是整体和部分的关系,整体与部分可以分开聚合关系是关联关系的特例,所以他具有关联的导航性与多重性

    如:一台电脑由键盘(keyboard)、显示器(monitor),鼠标等组成;组成电脑的各个配件是可以从电脑上分离出来的,使用带空心菱形的实线来表示:

    public class Computer{
    	private Mouse mouse;
    	private Monitor monitor;
    
    	public void setMouse(Mouse mouse) {
    		this.mouse = mouse;
    	}
    
    	public void setMonitor(Monitor monitor) {
    		this.monitor = monitor;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.7 组合关系(Aggregation)

    组合关系:也是整体与部分的关系,但是整体与部分不可以分开。用实心菱形表示。

    如果我们认为上面Mouse,Monitor和Computer是不可分离的,则升级为组合关系

    public class Computer{
    	private Mouse mouse = new Mouse();
    	private Monitor monitor = new Monitor();
    }
    
    • 1
    • 2
    • 3
    • 4

    再看一个案例:在程序中我们定义实体:Person 与 IDCard、Head, 那么 Head 和 Person 就是 组合,IDCard 和Person 就是聚合。

    但是如果在程序中 Person 实体中定义了对 IDCard 进行级联删除,即删除 Person 时连同 IDCard 一起删除,那么 IDCard 和 Person 就是组合了。

    public class Person{
    	private IDCard card;
    	private Head head = new Head();
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    三、设计模式

    可以分为三大类:

    创建型模式(Creational Patterns):这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

    1. 单例模式(Singleton Pattern)
    2. 工厂模式(Factory Pattern)
    3. 抽象工厂模式(Abstract Factory Pattern)
    4. 原型模式(Prototype Pattern)
    5. 建造者模式(Builder Pattern)

    结构型模式(Structural Patterns):这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

    1. 适配器模式(Adapter Pattern)
    2. 桥接模式(Bridge Pattern)
    3. 过滤器模式(Filter、Criteria Pattern)
    4. 组合模式(Composite Pattern)
    5. 装饰器模式(Decorator Pattern)
    6. 外观模式(Facade Pattern)
    7. 享元模式(Flyweight Pattern)
    8. 代理模式(Proxy Pattern)
    9. 数据映射模式 *(Data Mapper)
    10. 依赖注入模式 *(Dependency Injection)
    11. 门面模式 *(Facade)
    12. 流接口模式 *(Fluent Interface)
    13. 注册模式 *(Registry)

    行为型模式(Behavioral Patterns):这些设计模式特别关注对象之间的通信

    1. 责任链模式(Chain of Responsibility Pattern)
    2. 命令模式(Command Pattern)
    3. 解释器模式(Interpreter Pattern)
    4. 迭代器模式(Iterator Pattern)
    5. 中介者模式(Mediator Pattern)
    6. 备忘录模式(Memento Pattern)
    7. 观察者模式(Observer Pattern)
    8. 状态模式(State Pattern)
    9. 空对象模式(Null Object Pattern)
    10. 策略模式(Strategy Pattern)
    11. 模板模式(Template Pattern)
    12. 访问者模式(Visitor Pattern)
    13. 规格模式 *(Specification)
    14. 访问者模式 *(Visitor)

    设计模式之间的关系
    在这里插入图片描述

    参考链接

    https://baijiahao.baidu.com/s?id=1757590341900686107&wfr=spider&for=pc

  • 相关阅读:
    MFQE 2.0: A New Approach for Multi-FrameQuality Enhancement on Compressed Video
    2022.11.8每日刷题打卡
    分析悬链线中心的横坐标位置
    Spring Boot和MongoDB全栈开发教程
    lammps教程:原子平动和振动的设置方法
    11在SpringMVC中响应到浏览器的数据格式,@ResponseBody注解和@RestController复合注解的功能详解
    Mac使用brew搭建kafka集群
    SAP 标准产品里使用 OData 服务的一些细节分享
    vsftp新建用户及目录时遇到的坑
    大模型日报 2024-06-28
  • 原文地址:https://blog.csdn.net/xxx1276063856/article/details/134487627