Java面试题 - 谈谈你了解的最常见的几种设计模式,说说他们的应用场景

回答重点

工作中常用的就是单例模式、简单工厂、策略、模板等设计模式。

例如,需要确保某个类只有一个实例,并提供一个全局访问点的时候,就能用到单例模式,比如配置管理器或者全局缓存,像常见的数据库连接池等其实都用上了单例模式。

而且很多时候设计模式在工作中都是组合使用的,比如支付场景,需要对接不同的支付渠道:支付宝、微信、易宝支付、连连支付等等。

不同渠道对应不同策略,天然适合策略模式。

public interface PayService {
	void pay(PayDto payDto);
}

public class AliPayService implements PayService {
	public void pay(PayDto payDto) {
      // ....
	}
}
public class WechatPayService implements PayService {
	public void pay(PayDto payDto) {
      // ....
	}
}

并且在不同支付渠道对接过程中会发现大部分流程都是一样的,例如先需要前置的参数检查,然后进行核心的支付逻辑,最后有一些后置的检查等等。这样一致的流程就能抽象成一个模板方法,让不同渠道的实现类都继承它,这就运用了模板方法。

public abstract class AbstractPayService implements PayService {
    
    //模板方法
    @Override
	public void pay(PayDto payDto) {
        paramValidate(payDto);
        doPay(payDto);
        afterProcess()
	}

	private void paramValidate(PayDto payDto) {
        .....
	}

	private void afterProcess() {
        .....
	}

    // 不同支付渠道的具体实现
	public abstract void doPay(PayDto payDto);
}

public class AliPayService extends AbstractPayService {
	public void doPay(PayDto payDto) {
      // ....
	}
}
public class WechatPayService extends AbstractPayService {
	public void doPay(PayDto payDto) {
      // ....
	}
}

还有个简单工厂模式可以用在选择支付渠道的时候,创建一个支付工厂方法,传入了ALIPAY得到支付宝的支付实现类,传入WECHAT得到微信的实现类,这不就是工厂方法吗?

@Component
public class PayServiceFactory {

	@Resource
	private Map<String, PayService> payServiceMap;
    

	public PayService getPayService(String channel) {
        return payServiceMap.get(channel);
	}
}

以上都是一些比较常用的设计模式,还有的话例如适配器模式,可以用在老接口对接的场景,进行接口的适配兼容。


引言

设计模式是软件工程中解决常见问题的可重用方案,它们代表了最佳实践,是软件设计师们多年经验的结晶。本文将介绍几种最常见的设计模式,分析它们的特点和应用场景,并通过流程图帮助理解。

一、单例模式(Singleton Pattern)

概念

单例模式确保一个类只有一个实例,并提供一个全局访问点。

应用场景

  • 数据库连接池
  • 日志系统
  • 配置管理器
  • 线程池
Singleton
-static instance: Singleton
-Singleton()
+static getInstance()

实现流程

是
否
调用getInstance方法
实例是否存在?
返回现有实例
创建新实例
保存实例

二、工厂模式(Factory Pattern)

概念

工厂模式定义了一个创建对象的接口,但让子类决定实例化哪个类。

应用场景

  • 支付系统(不同支付方式)
  • 日志系统(文件日志、数据库日志等)
  • UI组件库(不同主题的按钮)
«interface»
Creator
+factoryMethod() : Product
ConcreteCreatorA
+factoryMethod() : Product
ConcreteCreatorB
+factoryMethod() : Product
«interface»
Product
ConcreteProductA
ConcreteProductB

创建流程

工厂A
工厂B
客户端
调用工厂方法
具体工厂
创建产品A
创建产品B
返回产品A
返回产品B

三、观察者模式(Observer Pattern)

概念

定义对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

应用场景

  • 事件处理系统
  • 消息队列
  • MVC架构中的模型-视图关系
  • 股票价格变动通知
通知
1
0..*
«interface»
Subject
+registerObserver(Observer)
+removeObserver(Observer)
+notifyObservers()
«interface»
Observer
+update()
ConcreteSubject
-state
+getState()
+setState()
ConcreteObserver
-observedState
+update()

工作流程

主题状态改变
调用notifyObservers
遍历所有观察者
调用每个观察者的update方法
观察者获取最新状态并更新

四、策略模式(Strategy Pattern)

概念

定义一系列算法,将每个算法封装起来,并使它们可以互相替换。

应用场景

  • 排序算法选择
  • 支付方式选择
  • 数据压缩算法
  • 导航系统(不同路线策略)
Context
-strategy: Strategy
+setStrategy(Strategy)
+executeStrategy()
«interface»
Strategy
+execute()
ConcreteStrategyA
+execute()
ConcreteStrategyB
+execute()

执行流程

策略A
策略B
客户端
设置策略
调用执行方法
当前策略
执行策略A
执行策略B

五、装饰器模式(Decorator Pattern)

概念

动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。

应用场景

  • Java I/O流
  • Web中间件
  • 权限校验系统
  • 咖啡店订单系统(添加配料)
«interface»
Component
+operation()
ConcreteComponent
+operation()
Decorator
-component: Component
+operation()
ConcreteDecoratorA
+operation()
+addedBehavior()
ConcreteDecoratorB
+operation()
+addedBehavior()

装饰流程

创建基础组件
用装饰器A包装
用装饰器B包装
调用operation
装饰器B的operation
装饰器A的operation
基础组件的operation

总结

设计模式是软件开发中的重要工具,合理使用可以提升代码的可维护性、可扩展性和可重用性。本文介绍了五种最常用的设计模式:

  1. 单例模式:确保全局唯一实例
  2. 工厂模式:封装对象创建过程
  3. 观察者模式:实现松耦合的通知机制
  4. 策略模式:灵活切换算法实现
  5. 装饰器模式:动态扩展对象功能

在实际开发中,应根据具体需求选择合适的设计模式,避免过度设计。理解这些模式的核心理念比死记硬背实现方式更为重要。

更多推荐