文章目录
- 设计模型概念
- 单例模式
- 工厂模式
- 策略模式
- 责任链模式
设计模型概念
设计模式是前人总结的软件设计经验和解决问题的最佳方案,它们为我们提供了一套可复用、易维护、可扩展的设计思路。
(1)定义: 设计模式是一套经过验证的解决特定设计问题的模板,这些模板并不是代码,而是对类、对象以及它们之间如何协作的抽象描述。
(2)目的: 降低系统的耦合性、提高代码的复用性和可维护性,以及应对不断变化的需求。
(3)设计模式主要可以分为三大类:创建型、结构型和行为型。以下是一些在 JAVA 开发工程师面试中常见的设计模式:
1. 创建型模式
- 单例模式(Singleton Pattern)
- 定义: 确保一个类只有一个实例,并提供一个全局访问点。
- 使用场景: 当系统中需要唯一一个对象来协调各部分工作,如配置管理、线程池、日志对象等。
- 工厂模式(Factory Pattern)
- 定义: 定义一个用于创建对象的接口,由子类决定实例化哪一个类。
- 使用场景: 当系统中有大量对象创建需求,且对象之间具有共同接口或父类时,可以使用工厂模式封装对象的创建逻辑,降低耦合。
- 建造者模式(Builder Pattern)
- 定义: 将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 使用场景: 当一个对象的构造过程复杂,涉及多个步骤或多个可选参数时,使用建造者模式能让代码更清晰、更易扩展。
2. 结构型模式
- 适配器模式(Adapter Pattern)
- 定义: 将一个类的接口转换成客户期望的另一个接口,使得原本因接口不兼容而不能一起工作的类可以协同工作。
- 使用场景: 当你想要使用一些现有的类,但它们的接口与当前系统不匹配时,可以使用适配器模式。
- 装饰器模式(Decorator Pattern)
- 定义: 动态地给一个对象添加一些额外的职责,而不影响其他对象。
- 使用场景: 当系统需要在不改变原有对象结构的情况下增加功能时,装饰器模式提供了一种灵活的解决方案。
- 外观模式(Facade Pattern)
- 定义: 为复杂的子系统提供一个简单的接口,使得客户端可以更容易地使用子系统。
- 使用场景: 当系统中存在多个相互依赖的类或接口时,通过外观模式可以将复杂性隐藏起来,提供一个统一的接口。
3. 行为型模式
- 观察者模式(Observer Pattern)
- 定义: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,其相关依赖对象会收到通知并自动更新。
- 使用场景: 当一个对象状态的变化需要通知其他对象,且不知道这些对象的数量或具体类型时,可以使用观察者模式,如事件监听机制。
- 策略模式(Strategy Pattern)
- 定义: 定义一系列算法,把它们一个个封装起来,并使它们可以互换。
- 使用场景: 当系统中存在多种算法或行为,并且需要根据具体情况选择不同的算法时,策略模式能使算法切换更为灵活。
- 模板方法模式(Template Method Pattern)
- 定义: 在一个方法中定义一个算法的骨架,将某些步骤延迟到子类中实现,从而使子类可以不改变算法结构的情况下重新定义算法的某些步骤。
- 使用场景: 当多个子类有很多相同的行为,只在细节上略有不同的情况下,模板方法模式可以复用公共代码,同时让子类实现具体差异部分。
- 代理模式(Proxy Pattern)
- 定义: 为其他对象提供一种代理以控制对这个对象的访问。
- 使用场景: 当你需要在访问对象时附加一些额外操作(如懒加载、安全控制、缓存等)时,可以使用代理模式来控制对象的访问。
单例模式
确保一个类只有一个实例,并提供一个全局访问点。
Spring 框架中,默认 bean
的作用域为单例(singleton),即在整个应用上下文中只存在一个实例。
如 Spring 的 ApplicationContext
在加载 bean 时会确保同一个 bean 只被实例化一次(除非配置为其他作用域)。
public class Singleton {// 饿汉式单例private static volatile Singleton instance = null;// 私有构造方法,防止外部实例化private Singleton() {}public static Singleton getInstance() {if (instance == null) {sychronized(Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
工厂模式
定义一个用于创建对象的接口,由子类决定实例化哪一个类。
Spring 的 BeanFactory
或 ApplicationContext
实际上就是一个工厂,通过配置文件或注解来实例化并管理对象。
FactoryBean
接口允许开发者自定义 bean
的创建逻辑。
// 定义产品接口
public interface Product {void use();
}// 具体产品A
public class ConcreteProductA implements Product {@Overridepublic void use() {System.out.println("使用产品A");}
}// 具体产品B
public class ConcreteProductB implements Product {@Overridepublic void use() {System.out.println("使用产品B");}
}// 工厂类
public class ProductFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}throw new IllegalArgumentException("未知产品类型:" + type);}
}// 测试入口
public class FactoryDemo {public static void main(String[] args) {Product productA = ProductFactory.createProduct("A");productA.use();Product productB = ProductFactory.createProduct("B");productB.use();}
}
策略模式
定义一系列算法,把它们一个个封装起来,并使它们可以互换。
当系统中有多种算法或行为需要在运行时动态切换时,可以使用策略模式。
Spring MVC 中,通过 HandlerAdapter
接口支持多种类型的控制器(如 @Controller
、@RestController
等),根据实际请求选择合适的适配器来处理业务逻辑。
事务管理、缓存策略等也采用了类似思想,通过接口和多种实现来动态选择行为。
// 策略接口
public interface Strategy {void execute();
}// 具体策略A
public class ConcreteStrategyA implements Strategy {@Overridepublic void execute() {System.out.println("执行策略A");}
}// 具体策略B
public class ConcreteStrategyB implements Strategy {@Overridepublic void execute() {System.out.println("执行策略B");}
}// 上下文,使用策略
public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void executeStrategy() {strategy.execute();}
}// 测试入口
public class StrategyDemo {public static void main(String[] args) {Context contextA = new Context(new ConcreteStrategyA());contextA.executeStrategy();Context contextB = new Context(new ConcreteStrategyB());contextB.executeStrategy();}
}
责任链模式
将请求的处理对象连成一条链,每个处理者持有对下一个处理者的引用,按顺序处理请求或将其传递给下一个处理者。
当一个请求可能由多个对象处理,但不清楚到底由哪一个对象处理时,可采用责任链模式进行动态分派。
在 Spring Security 中,FilterChainProxy
维护了一系列过滤器(Filter),每个过滤器依次处理 HTTP
请求,决定是否放行、拒绝或进一步处理。
Spring MVC 中的拦截器链(HandlerInterceptor
)也是一个责任链,每个拦截器按顺序处理请求的预处理和后处理工作。
// 责任链中的抽象处理者
public abstract class Handler {protected Handler next;// 设置下一个处理者public void setNext(Handler next) {this.next = next;}// 处理请求public abstract void handleRequest(String request);
}// 具体处理者A
public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if (request.contains("A")) {System.out.println("ConcreteHandlerA 处理请求: " + request);} else if (next != null) {next.handleRequest(request);}}
}// 具体处理者B
public class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if (request.contains("B")) {System.out.println("ConcreteHandlerB 处理请求: " + request);} else if (next != null) {next.handleRequest(request);}}
}// 测试责任链模式
public class ChainDemo {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();// 设置责任链顺序handlerA.setNext(handlerB);// 测试请求:包含 "B" 的请求由 ConcreteHandlerB 处理handlerA.handleRequest("Request with B");// 测试请求:包含 "A" 的请求由 ConcreteHandlerA 处理handlerA.handleRequest("Request with A");}
}