常用设计模式

本文详细介绍了设计模式的六大原则,包括开闭原则、依赖倒转原则、里氏代换原则、接口隔离原则、单一职责原则和迪米特法则。接着,阐述了常用的设计模式,如单例模式、工厂模式、代理模式、模板方法模式、观察者模式和策略模式。每个模式都解析了其实现方式、应用场景及优缺点。这些模式在实际开发中有着广泛的应用,如数据库连接池、线程池、支付系统和单元测试等,能有效提高代码的可读性和可维护性。

1. 设计模式六大原则

开闭原则

对扩展开放,对修改关闭。

依赖倒转原则

这个原则是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体

里氏代换原则

使用的基类可以在任何地方使用继承的子类,完美的替换基类(子类可以扩展父类的功能,但不能改变父类原有的功能。子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法,子类中可以增加自己特有的方法)

接口隔离原则

解释:使用多个隔离的接口,比使用单个接口要好。降低类之间的耦合度。

单一职责原则

该原则提出对象不应该承担太多职责,如果一个对象承担了太多的职责,至少存在以下两个缺点:
一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力;
当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费。

迪米特法则,又称最少知道原则

最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
核心是降低类之间的耦合。

2. 设计模式分类

模式可以分为三大类:创建型模式、结构型模式、行为型模式
创建型模式:单例设计模式,工厂设计模式
结构型模式:代理模式
行为型模式: 模板方法模式,观察者模式

3. 单例模式

3.1 特点

单例模式有 3 个特点:
单例类只有一个实例对象;
该单例对象必须由单例类自行创建;
单例类对外提供一个访问该单例的全局访问点。

3.2 实现方式

饿汉式:类加载时实例对象
懒汉式:第一次引用类时才进行实例化

3.3 应用场景

数据库连接池,线程池连接池等;
工具类;

4. 工厂模式

4.1 实现方式&&应用场景

工厂模式有 3 种不同的实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。

4.1.1 简单工厂模式

在这里插入图片描述

简单工厂:是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品:是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
具体产品:是简单工厂模式的创建目标。
在这里插入图片描述
优点:实现简单
缺点:不易扩展,一旦增加新产品不得不修改工厂逻辑。
应用场景:对于产品种类相对较少的情况。只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

4.1.2 工厂方法模式

在这里插入图片描述

工厂方法模式的主要角色如下:
抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 crateProduct() 来创建产品。
具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
在这里插入图片描述
在这里插入图片描述
优点:用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
缺点:类的个数容易过多,增加复杂度
应用场景:客户只知道创建产品的工厂名,而不知道具体的产品名。

5. 代理模式

增强被代理对象。在不改变原始类(被代理类)代码的情况下,通过引入代理类来给原始类附加功能。

5.1 实现方式

静态代理:真实对象与代理对象要实现同一个接口,代理对象代理的是真实对象。
动态代理:JDK动态代理(基于接口的动态代理)。利用拦截器(必须实现invocationHandler)加上反射机制生成一个代理类,在调用具体方法前调用InvokeHandler来处理,从而实现方法增强
动态代理:CGLB动态代理(基于父类的动态代理)。动态生成一个要代理的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,对方法进行增强
在这里插入图片描述

5.2 应用场景

在业务系统中一些非功能性需求,比如:监控、统计、鉴权、事务、日志等。我们将这些附加功能与业务功能解耦,放到代理类中统一处理,这样可以与业务解耦并且做到职责明确划分。

7. 模板方法模式

定义一个操作中的算法骨架(父类),而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构来重定义该算法的。

7.1 什么时候使用模板方法

实现一些操作时,整体步骤很固定,但是呢。就是其中一小部分需要改变,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

7.2 实际开发中应用场景哪里用到了模板方法

数据库访问的封装、Junit单元测试、servlet中关于doGet/doPost方法的调用等等

7.3 Demo

  1. 先定义一个模板。把模板中的点菜和付款,让子类来实现
package com.lijie;
//模板方法
public abstract class RestaurantTemplate {
 // 1.看菜单
public void menu() {
  System.out.println("看菜单");
 }
 // 2.点菜业务
abstract void spotMenu();
 // 3.吃饭业务
public void havingDinner(){ System.out.println("吃饭"); }
 // 3.付款业务
abstract void payment();
 // 3.走人
public void goR() { System.out.println("走人"); }
 //模板通用结构
public void process(){
  menu();
  spotMenu();
  havingDinner();
  payment();
  goR();
 }
}
  1. 具体的模板方法子类 1
package com.lijie;
public class RestaurantGinsengImpl extends RestaurantTemplate {
 void spotMenu() {
   System.out.println("人参");
 }
 void payment() {
   System.out.println("5快");
 }
}
  1. 具体的模板方法子类 2
package com.lijie;
public class RestaurantLobsterImpl extends RestaurantTemplate {
 void spotMenu() {
   System.out.println("龙虾");
 }
 void payment() {
   System.out.println("50块");
 }
}
  1. 客户端测试
public class Client {
 public static void main(String[] args) {
   //调用第一个模板实例
	RestaurantTemplate restaurantTemplate = new RestaurantGinsengImpl();
    restaurantTemplate.process();
 }
}

8. 观察者模式

当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

8.1 优点

降低了目标与观察者之间的耦合关系

8.2 缺点

当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率

8.3 应用场景

spring中的监听器的设计
springboot中的监听器的设计

9. 策略模式

9.1 什么是策略模式

定义了一系列的算法 或 逻辑 或 相同意义的操作,并将每一个算法、逻辑、操作封装起来,而且使它们还可以相互替换。
主要是为了 简化 if…else 所带来的复杂和难以维护

9.2 策略模式应用场景

策略模式的用意是针对一组算法或逻辑,将每一个算法或逻辑封装到具有共同接口的独立的类中,从而使得它们之间可以相互替换
例如:我要做一个不同会员打折力度不同的三种策略,初级会员,中级会员,高级会员(三种不同的计算)
例如:我要一个支付模块,我要有微信支付、支付宝支付、银联支付等

9.3 策略模式的优点和缺点

优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性非常良好
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露

9.4 代码演示

模拟支付模块有微信支付、支付宝支付、银联支付。
1.定义抽象的公共方法

class PayStrategyA extends PayStrategy {
 void algorithmInterface() {
  	System.out.println("微信支付");
 }
}

2.定义实现微信支付

class PayStrategyA extends PayStrategy {
 void algorithmInterface() {
  	System.out.println("微信支付");
 }
}

3.定义实现支付宝支付

class PayStrategyB extends PayStrategy {
 void algorithmInterface() {
  	System.out.println("支付宝支付");
 }
}

4.定义实现银联支付

class PayStrategyC extends PayStrategy {
 void algorithmInterface() {
  System.out.println("银联支付");
 }
}

5.定义下文维护算法策略(环境类)

class Context {
 PayStrategy strategy;
 public Context(PayStrategy strategy) {
  this.strategy = strategy;
 }
 public void algorithmInterface() {
  strategy.algorithmInterface();
 }
}

6.测试

class ClientTestStrategy {
 public static void main(String[] args) {
  Context context;
  //使用支付逻辑A
  context = new Context(new PayStrategyA());
  context.algorithmInterface();
  //使用支付逻辑B
  context = new Context(new PayStrategyB());
  context.algorithmInterface();
  //使用支付逻辑C
  context = new Context(new PayStrategyC());
  context.algorithmInterface();
 }
}

https://www.bilibili.com/video/BV15v4y1T7fz?p=154&vd_source=b901ef0e9ed712b24882863596eab0ca
https://www.runoob.com/design-pattern/observer-pattern.html
工厂模式:https://www.jianshu.com/p/847ccc5d0d5f
模板方法:https://blog.csdn.net/u012440207/article/details/122616465
策略模式:https://blog.csdn.net/qq_45649807/article/details/124593629

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值