设计模式
单例模式singleton

.懒汉模式:延迟加载, 只有在真正使用的时候,才开始实例化。
1)线程安全问题
2)double check 加锁优化
3)编译器(JIT),CPU 有可能对指令进行重排序,导致使用到尚未初始化
的实例,可以通过添加volatile 关键字进行修饰,
对于volatile 修饰的字段,可以防止指令重排。
饿汉
类加载的 初始化阶段就完成了 实例的初始化 。本质上就是借助于jvm类加载机制,保证实例的唯一性(初始化过程只会执行一次)及线程安全(JVM以同步的形式来完成类加载的整个过程)。
类加载过程:
1,加载二进制数据到内存中, 生成对应的Class数据结构,
2,连接: a. 验证, b.准备(给类的静态成员变量赋默认值),c.解析
3,初始化: 给类的静态变量赋初值
只有在真正使用对应的类时,才会触发初始化 如( 当前类是启动类即main函数所在类,直接进行new 操作,访问静态属性、访问静态方法,用反射访问类,初始化一个类的子类等.)
package com.junziln.study.maintest.design.singleton;
public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
抽象工厂模式 (Abstract Factory)
提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
package com.tuling.designpattern.abstractfactory;
public class AbstractFactoryTest {
public static void main(String[] args) {
IDatabaseUtils iDatabaseUtils = new OracleDataBaseUtils();
IConnection connection = iDatabaseUtils.getConnection();
connection.connect();
ICommand command = iDatabaseUtils.getCommand();
command.command();
}
}
// 变化: mysql, oracle...
// connection, command
interface IConnection {
void connect();
}
interface ICommand {
void command();
}
interface IDatabaseUtils {
IConnection getConnection();
ICommand getCommand();
}
class MysqlConnection implements IConnection {
@Override
public void connect() {
System.out.println("mysql connected.");
}
}
class OracleConnection implements IConnection {
@Override
public void connect() {
System.out.println("oracle connected.");
}
}
class MysqlCommand implements ICommand {
@Override
public void command() {
System.out.println("mysql command.");
}
}
class OracleCommand implements ICommand {
@Override
public void command() {
System.out.println("oracle command.");
}
}
class MysqlDataBaseUtils implements IDatabaseUtils {
@Override
public IConnection getConnection() {
return new MysqlConnection();
}
@Override
public ICommand getCommand() {
return new MysqlCommand();
}
}
class OracleDataBaseUtils implements IDatabaseUtils {
@Override
public IConnection getConnection() {
return new OracleConnection();
}
@Override
public ICommand getCommand() {
return new OracleCommand();
}
}
应用场景
程序需要处理不同系列的相关产品,但是不希望它依赖于这些产品的具体类时,可以使用抽象工厂。
优点
- 可以确信你从工厂得到的产品彼此是兼容的
- 可以避免具体产品和客户端代码之间的紧密耦合
- 符合单一职责原则
- 符合开闭原则
JDK源码中的应用
java.sql.Connection
java.sql.Driver
策略模式 (Strategy Pattern)
模式定义
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于算法的使用者。
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardStrategy implements PaymentStrategy {
public void pay(int amount) {
System.out.println("信用卡支付: " + amount);
}
}
class AlipayStrategy implements PaymentStrategy {
public void pay(int amount) {
System.out.println("支付宝支付: " + amount);
}
}
class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePay(int amount) {
strategy.pay(amount);
}
}
应用场景
- 当你有很多类似的类,但它们执行某些行为的方式不同时
- 需要将业务逻辑与算法实现细节隔离时
- 当类具有大量条件运算符,需要在不同算法变体间切换时
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户端。以下是策略模式的典型应用场景:
优点
- 可以将算法的实现细节与使用代码隔离
- 符合开闭原则
Spring & JDK源码中的应用
java.util.Comparator
观察者模式
应用场景:
当更改一个对象的状态可能需要更改其他对象,并且实际的对象集事先未知或动态更改时,请使用观察者模式。
观察者模式定义了对象之间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新。
import java.util.ArrayList;
import java.util.List;
// 主题接口(被观察者)
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
// 观察者接口
interface Observer {
void update(String message);
}
// 具体主题实现
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
public void setState(String newState) {
this.state = newState;
notifyObservers();
}
}
// 具体观察者实现
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到更新: " + message);
}
}
// 测试类
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("观察者1");
Observer observer2 = new ConcreteObserver("观察者2");
Observer observer3 = new ConcreteObserver("观察者3");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.registerObserver(observer3);
subject.setState("状态1");
subject.setState("状态2");
subject.removeObserver(observer2);
subject.setState("状态3");
}
}

模板方法
模板方法模式定义了一个算法的骨架,将某些步骤延迟到子类中实现,使得子类可以不改变算法结构的情况下重新定义某些特定步骤。
// 抽象类定义模板方法和基本方法
abstract class AbstractClass {
// 模板方法,定义算法骨架(通常声明为final防止子类重写)
public final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
concreteOperation();
hook();
}
// 抽象方法,必须由子类实现
protected abstract void primitiveOperation1();
// 抽象方法,必须由子类实现
protected abstract void primitiveOperation2();
// 具体方法,已经实现
protected void concreteOperation() {
System.out.println("AbstractClass提供的默认实现");
}
// 钩子方法,子类可以选择性覆盖
protected void hook() {}
}
// 具体子类实现
class ConcreteClassA extends AbstractClass {
@Override
protected void primitiveOperation1() {
System.out.println("ConcreteClassA实现的primitiveOperation1()");
}
@Override
protected void primitiveOperation2() {
System.out.println("ConcreteClassA实现的primitiveOperation2()");
}
@Override
protected void hook() {
System.out.println("ConcreteClassA选择覆盖了hook()方法");
}
}
class ConcreteClassB extends AbstractClass {
@Override
protected void primitiveOperation1() {
System.out.println("ConcreteClassB实现的primitiveOperation1()");
}
@Override
protected void primitiveOperation2() {
System.out.println("ConcreteClassB实现的primitiveOperation2()");
}
// 不覆盖hook()方法,使用默认实现(空方法)
}
// 使用示例
public class TemplateMethodDemo {
public static void main(String[] args) {
AbstractClass classA = new ConcreteClassA();
classA.templateMethod();
System.out.println("---------------------");
AbstractClass classB = new ConcreteClassB();
classB.templateMethod();
}
}
java
复制
abstract class AbstractTemplate {
// 模板方法(final防止子类覆盖)
public final void templateMethod() {
step1();
step2();
step3();
}
protected abstract void step1();
protected abstract void step2();
protected void step3() { // 可选默认实现
System.out.println("默认步骤3");
}
}
class ConcreteTemplate extends AbstractTemplate {
protected void step1() {
System.out.println("具体步骤1");
}
protected void step2() {
System.out.println("具体步骤2");
}
}
- 核心角色:
- AbstractClass(抽象类):定义模板方法和基本方法
- ConcreteClass(具体子类):实现抽象类中的抽象方法
- 方法分类:
- 模板方法:定义算法骨架(通常声明为final)
- 抽象方法:必须由子类实现
- 具体方法:父类已实现,子类可直接继承
- 钩子方法:子类可以选择性覆盖(非必须)
- 优势:
- 代码复用:将公共代码提取到父类
- 扩展性好:子类只需关注特定步骤的实现
- 符合开闭原则:不修改父类即可扩展新行为
- 适用场景:
- 多个类有相同的方法,但实现细节不同
- 需要控制子类扩展点(通过钩子方法)
- 重要、复杂的算法需要固定流程,但允许某些步骤自定义
- 与策略模式的区别:
- 模板方法:通过继承实现,控制算法流程
- 策略模式:通过组合实现,完全替换算法
- JDK中的实际应用:
java.util.AbstractList
(如get()
是抽象方法,indexOf()
是具体方法)java.io.InputStream
(read()
是抽象方法,其他方法基于它实现)javax.servlet.http.HttpServlet
(doGet()
,doPost()
等由子类实现)
类名 | 是否是模板方法模式 | 主要作用 | 设计特点 |
---|---|---|---|
JdbcTemplate | ✅ 是 | 数据库操作模板 | 固定流程+回调接口 |
RedisTemplate | ❌ 不是(是模板类) | Redis操作封装 | 提供简化API,内部用回调 |
RestTemplate | ❌ 不是(是模板类) | HTTP客户端封装 | 提供简化API,内部用回调 |
TransactionTemplate | ✅ 是 | 声明式事务模板 | 固定事务流程+业务代码回调 |
适配器
将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
// 目标接口:充电器需要的电源(5V)
interface Power5V {
int provide5V();
}
// 适配者:现有220V电源(需要被适配的对象)
class Power220V {
public int provide220V() {
System.out.println("提供220V电源");
return 220;
}
}
// 适配器:将220V转换为5V
class PowerAdapter implements Power5V {
private Power220V power220V;
public PowerAdapter(Power220V power220V) {
this.power220V = power220V;
}
@Override
public int provide5V() {
int voltage = power220V.provide220V();
// 模拟电压转换:220V → 5V
System.out.println("将" + voltage + "V转换为5V");
return 5;
}
}
// 客户端:手机充电器
class PhoneCharger {
private Power5V power5V;
public PhoneCharger(Power5V power5V) {
this.power5V = power5V;
}
public void charge() {
if (power5V.provide5V() == 5) {
System.out.println("电压正常,开始充电...");
} else {
System.out.println("电压异常,无法充电!");
}
}
}
// 测试类
public class Main {
public static void main(String[] args) {
// 创建220V电源
Power220V homePower = new Power220V();
// 使用适配器将220V转换为5V
Power5V adapter = new PowerAdapter(homePower);
// 手机充电器使用适配后的5V电源
PhoneCharger charger = new PhoneCharger(adapter);
// 开始充电
charger.charge();
}
}
Spring:
org.springframework.context.event.GenericApplicationListenerAdapter
责任链
责任链模式将请求的发送者和接收者解耦,让多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止
带中断的过滤器链
package com.junziln.study.maintest.design.chain;
import java.util.ArrayList;
import java.util.List;
// 过滤器接口
interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
// 过滤器链
class FilterChain {
private List<Filter> filters = new ArrayList<>();
private int index = 0;
public FilterChain addFilter(Filter filter) {
filters.add(filter);
return this;
}
public void doFilter(Request request, Response response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
}
}
}
// 具体过滤器 - 认证
class AuthenticationFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
if (!"admin".equals(request.getUsername())) {
System.out.println("认证失败: 用户名不正确");
return; // 中断链
}
System.out.println("认证通过");
chain.doFilter(request, response);
}
}
// 具体过滤器 - 日志记录
class LoggingFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("记录请求日志: " + request);
chain.doFilter(request, response);
System.out.println("记录响应日志: " + response);
}
}
// 具体过滤器 - 权限检查
class AuthorizationFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
if (!"admin".equals(request.getRole())) {
System.out.println("权限不足");
return; // 中断链
}
System.out.println("权限检查通过");
chain.doFilter(request, response);
}
}
// 请求和响应类
class Request {
private String username;
private String role;
public Request(String username, String role) {
this.username = username;
this.role = role;
}
public String getUsername() { return username; }
public String getRole() { return role; }
@Override
public String toString() {
return "Request{username='" + username + "', role='" + role + "'}";
}
}
class Response {
private String data;
public void setData(String data) { this.data = data; }
@Override
public String toString() {
return "Response{data='" + data + "'}";
}
}
// 使用示例
public class FilterChainDemo {
public static void main(String[] args) {
// 创建过滤器链
FilterChain chain = new FilterChain()
.addFilter(new AuthenticationFilter())
.addFilter(new LoggingFilter())
.addFilter(new AuthorizationFilter());
// 处理请求
Request request = new Request("admin", "admin");
Response response = new Response();
/* System.out.println("===== 处理admin请求 =====");
chain.doFilter(request, response);
response.setData("敏感数据");*/
System.out.println("\n===== 处理guest请求 =====");
request = new Request("guest", "user");
response = new Response();
chain.doFilter(request, response);
/* 输出:
* ===== 处理admin请求 =====
* 认证通过
* 记录请求日志: Request{username='admin', role='admin'}
* 权限检查通过
* 记录响应日志: Response{data='null'}
*
* ===== 处理guest请求 =====
* 认证失败: 用户名不正确
*/
}
}
当某个过滤器中执行return
时:
- 立即终止当前过滤器的执行
- 控制权返回到
FilterChain.doFilter()
- 因为
index
已经递增,但没有新的递归调用发生
Spring MVC中的责任链模式(简化版)
import java.util.Arrays;
import java.util.List;
// 处理器接口
interface Handler {
boolean handle(Object request);
}
// 处理器链
class HandlerExecutionChain {
private List<Handler> handlers;
private int currentPosition = 0;
public HandlerExecutionChain(Handler... handlers) {
this.handlers = Arrays.asList(handlers);
}
public boolean applyPreHandle(Object request) {
for (Handler handler : handlers) {
if (!handler.handle(request)) {
return false; // 中断处理
}
}
return true;
}
}
// 具体处理器 - 跨域处理
class CorsHandler implements Handler {
@Override
public boolean handle(Object request) {
System.out.println("处理跨域请求");
return true;
}
}
// 具体处理器 - 日志处理
class LogHandler implements Handler {
@Override
public boolean handle(Object request) {
System.out.println("记录请求日志");
return true;
}
}
// 具体处理器 - 权限验证
class AuthHandler implements Handler {
@Override
public boolean handle(Object request) {
System.out.println("验证权限");
// 模拟权限验证失败
return false;
}
}
// 使用示例
public class SpringMvcChainDemo {
public static void main(String[] args) {
// 创建处理器链
HandlerExecutionChain chain = new HandlerExecutionChain(
new CorsHandler(),
new LogHandler(),
new AuthHandler()
);
// 处理请求
boolean result = chain.applyPreHandle(new Object());
System.out.println("请求处理结果: " + result);
/* 输出:
* 处理跨域请求
* 记录请求日志
* 验证权限
* 请求处理结果: false
*/
}
}
核心角色:
- Handler(抽象处理者):定义处理请求的接口
- ConcreteHandler(具体处理者):实现处理逻辑,能处理则处理,否则转给下家
- Client(客户端):创建责任链并提交请求
优势:
- 解耦:请求发送者无需知道具体处理者
- 动态组合:可以动态增减处理者或改变顺序
- 灵活性:可以灵活分配责任
应用场景:
- 多级审批流程
- 过滤器链(如Servlet Filter)
- 异常处理
- 事件处理
变体:
- 纯的责任链:请求必须被某个处理者处理
- 不纯的责任链:请求可能不被任何处理者处理
与装饰器模式的区别:
- 责任链:多个处理者都可能处理请求
- 装饰器:所有装饰者都会参与处理,增强功能
责任链模式在Java生态中广泛应用,例如:
- Servlet Filter
- Spring Interceptor
- Netty ChannelHandler
装饰器
装饰者模式动态地给一个对象添加额外的职责,就增加功能来说,装饰者模式比生成子类更灵活。
interface Component {
void operation();
}
class ConcreteComponent implements Component {
public void operation() {
System.out.println("基础操作");
}
}
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("新增行为");
}
}