设计模式学习
设计模式的目的:
高内聚,低耦合的程序。
设计模式的七大原则:
- 单一职责原则
- 接口隔离原则
- 迪米特原则
- 开闭原则
- 依赖倒转原则
- 里氏替换原则
- 合成复用原则
1.单一职责原则
单一原则注意事项和细节:
1.降低类的复杂度,一个类只负责一项职责。
2.提高类的可读性,可维护性。
3.降低变更引起的风险。
2.接口隔离原则
客户端不应该依赖他不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
3.依赖倒转原则
1.高层模块不应该依赖底层模块,二者都应该依赖其抽象。
2.抽象不应该依赖细节,细节应该依赖抽象。
3.中心思想是面向接口编程。
依赖倒转原则注意事项和细节:
- 低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好。
- 变量的声明类型尽量是抽象类或接口,利于程序扩展和优化。
- 继承时遵循里氏替换原则。
4.里氏替换原则
基本介绍:所有引用基类的地方必须能透明的使用其子类的对象
使用继承时,遵循里氏代换原则,尽量不要重写父类的方法。
在适当情况下,可以通过聚合,组合,依赖来解决问题。
5.开闭原则
编程中最基础最重要的设计原则。
一个软件实体如类,模块和函数应该对扩展开放,对修改关闭,用抽象构建框架。用实现扩展细节
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是修改已有的代码来实现变化。
编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则。
6.迪米特法则
1.一个对象应该对其他对象保持最少的了解
2.类与类关系越密切,耦合度越大。
3.迪米特法则又称最少知道原则,即一个类对自己依赖的类知道的越少越好。
4.核心是降低类之间的耦合
5.迪米特法则只是要求降低耦合关系,并不是要求完全没有依赖关系。
7.合成复用原则
1.尽量使用合成/聚合的方式,而不是使用继承。
设计原则核心思想:1.找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
2.针对接口编程,而不是针对实现编程 。
3. 为了交互对象之间的松耦合设计而努力。
类图:依赖关系
- 类中用到了对方
- 如果是类的成员属性
- 如果是方法的返回类型
- 是方法接收的参数类型
- 方法中使用到
泛化:继承关系,是依赖关系的特例
实现关系:实现接口
关联关系:类与类之间的关系,关联具有导航性,即双向关系或单向关系。
关系具有多重性
单向一对一,双向一对一
聚合关系:表示的是整体和部分的关系,整体和部分可以分开,聚合关系是关联关系的特例,所以具有导航性和多重性。person和id Card
组合关系:也是整体与部分的关系,但是整体和部分不能分开。person和head
设计模式概述和分类:
1.创建型设计模式:单例模式,工厂模式,原型模式,抽象工厂模式,建造者模式。
2.结构型模式:适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式。
3.行为型模式:模板方法模式,命令模式,访问者模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式(责任链模式)。
//1.单例模式,对某个类只能存在一个对象实例,并且该类只提供一个获取对象实例的方法,(静态方法)
饿汉式(静态常量)
1.构造器私有化
2.类的内部创建对象
3.向外暴露一个静态的公共方法
代码实现:
/**
* 饿汉式第一种写法
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class HungryA {
private final static HungryA instance = new HungryA();
private HungryA() {
}
public static HungryA getInstance() {
return instance;
}
}
/**
* 饿汉式第二种写法
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class HungryB {
private static HungryB instance;
private HungryB() {
instance = new HungryB();
}
public static HungryB getInstance() {
return instance;
}
}
这两种写法都可用,但可能造成内存浪费。
懒汉式
/**
懒汉式
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class LazyA {
private static LazyA instance;
private LazyA() {
}
public static LazyA getInstance() {
if (instance == null) {
instance = new LazyA();
}
return instance;
}
}
起到了lazy loading的效果,但是线程不安全,在实际开发中不能使用。
/**
添加了线程同步,但是效率不高
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class LazyB {
private static LazyB instance;
private LazyB() {
}
public static synchronized LazyB getInstance() {
if (instance == null) {
instance = new LazyB();
}
return instance;
}
}
可以使用,但是不推荐。
/**双重检查
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class LazyC {
private static volatile LazyC instance;
private LazyC() {
}
public static LazyC getInstance() {
if (instance == null) {
synchronized (LazyC.class) {
if (instance == null) {
instance = new LazyC();
}
}
instance = new LazyC();
}
return instance;
}
}
双重检查,线程安全,lazy loading,效率较高。
实际开发中推荐这种单例模式。
/**静态内部类
* Author: zhangbicheng
* Date: 2022/7/27
*/
public class StaticInnerClass {
private StaticInnerClass() {
}
private static class Inner {
private static final StaticInnerClass instance = new StaticInnerClass();
}
public StaticInnerClass getInstance() {
return Inner.instance;
}
}
推荐使用
/**
* 枚举
*/
public enum Singleton {
INSTANCE;
public void say() {
System.out.println("ok");
}
}
jdk源码:com.lang.Runtime是饿汉式
简单工厂模式
属于创建型设计模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例,简单工厂模式是工厂模式家族中最简单实用的模式。
简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为
在软件开发中,当我们会用到大量的创建某种,某类,或某批对象时,就会使用到工厂模式。
工厂方法模式:
抽象工厂模式:
原型模式:实现clone able接口,继承clone方法。
bean的创建用到了原型模式。
clone默认是浅拷贝,指向同一个对象。数值类型会值传递,引用类型会引用传递。浅拷贝使用的是默认的clone方法来实现的。
深拷贝
基本介绍:
- 复制对象的所有基本类型的成员变量值。
- 为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象。也就是说,对象进行深拷贝要对整个对象进行拷贝。
- 深拷贝实现方式1:重写clone方法。
- 深拷贝实现方法2:通过对象序列化实现深拷贝。
方式1:对引用数据类型的成员变量单独进行clone操作。
方式2:通过对象的序列化实现(推荐)。
建造者模式:builder
建造者模式基本介绍:
建造者模式又叫生成器模式,是一种对象构建模式,他可以将复杂对象 的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现的对象。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体构建细节。
建造者模式的四个角色:
- Product(产品角色):一个具体的角色对象
- Builder(抽象建造者):
- ConcreteBuilder(具体建造者)
- Director(指挥者)
源码,StringBuilder,Appendable定义了多个append方法,即Appendable为抽象建造者,定义了抽象方法
AbstractStringBuilder实现了Appendable接口方法,这里的AbstractStringBuilder 已经是建造者,只是不能实例化,
StringBuilder既充当了指挥者角色,同时充当了具体的建造者,建造方法的实现是AbstractStringBuilder完成。
适配器模式:
例子:插座,有国标,欧标,南非标等等等等
基本介绍:
- 适配器模式,将某个类的接口转换成客户端期望的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能在一起工作的两个类可以协同工作,其别名为包装器
- 适配器模式属于结构型模式
- 主要分为三类:类适配器模式,对象适配器模式,接口适配器模式。
工作原理:
- 适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容
- 从用户的角度是看不到被适配器,是解耦的。
- 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。
- 用户接收到反馈结果,感受只是和目标接口交互
类适配器模式注意事项和细节
Java是单继承模式,所以类适配器要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性。
src类方法在adapter中都会暴露出来,也增加了使用的成本,
由于继承了src类,所以可以根据需求重写src类的方法,使得Adapter 的灵活性增强了。
对象适配器模式
与类适配器思路类似,只是将Adapter类作修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。即持有src类,实现dst类接口,完成src-》dst的适配。
根据合成复用原则,在系统中尽量使用关联关系来替代继承关系。
对象适配器模式是适配器模式常用的一种。
对象适配器模式注意事项和细节
1.对象适配器和类适配器是同一思想,只不过实现方式不同。根据合成复用原则,使用组合替代继承,所以他解决了必须继承src的局限性问题,也不要再要求dst必须是接口。
2.使用成本更低,更灵活
接口适配器模式
适用于一个接口不想使用其所有的方法的情况
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口的所有方法提供一个默认实现(空方法),那么该抽象类的子类可有选择的覆盖父类的某些方法来实现需求。
桥接模式:
基本介绍
- 将实现和抽象放在两个不同 的类层次中,使得两个层次可以独立改变。
- 是一种结构型设计模式。
- 桥接模式基于类的最小设计模式,通过使用封装,聚合及集成等行为让不同的类承担不同的职责,他的主要特点是吧抽象和实现分离开来,从而可以保持各部分的独立性以及应对他们的功能拓展。
桥接模式在jdbc上的源码解析
装饰者模式:
装饰者模式定义:
- 动态的将新功能附加到对象上,在对象功能扩展方面,他比继承更有弹性,装饰者模式也体现了开闭原则。
装饰者模式原理:
- 装饰者模式就像打包一个快递
主体:陶瓷 component
包装:塑料泡沫 decorator
2.
组合模式:
基本介绍
又叫部分整体模式,它创建了对象组的树形结构,将对象组合成
组合模式在jdk集合的源码分析
Java的集合类hashmap就使用了组合模式
外观模式
也叫过程模式,外观模式为子系统中的一组接口提供了一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个借口发生调用,而无需关心这个子系统的内部细节。
策略模式
一个抽象接口
一个实现类
享元模式
模版方法模式
命令模式
定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分开,这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储,传递,调用,增加与管理。
结构:
抽象命令类角色:定义命令的接口,声明执行的方法
具体命令角色:具体的命令,实现命令接口,通常会持有接收者,并调用接收者的
实现者/接收者:
调用者/请求者:
案例:
优缺点:
优点:
缺点:
jdk源码实现:runnable
责任链模式:
定义:又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有的请求处理者通过前一对象记住其下一个对象的引用而连成一条链,当有请求发生时,可将请求沿着这条链传递,直到有对象处理他为止。
结构:
抽象处理者
具体处理者
客户类角色
案例:
请假,一天以下的假只需要小组长同意即可,1到3天的假还需要部门经理同意,请3到7天的假还需要总经理同意
优点
缺点
状态模式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律