一、设计模式全解:
Java 中的设计模式是为了解决在软件开发中常见问题的一些"最佳实践"总结。设计模式分为三大类,共 23 种经典模式:
1. 创建型模式(5 种)
用于对象的创建,解决对象实例化过程中的问题。
模式名 | 作用说明 | 优点 | 缺点 |
---|---|---|---|
单例模式 (Singleton) | 保证一个类只有一个实例,并提供全局访问点 | 节省资源、提供全局访问点 | 多线程下需处理线程安全,难以单元测试 |
工厂方法模式 (Factory Method) | 定义一个用于创建对象的接口,让子类决定实例化哪一个类 | 符合开闭原则,便于扩展 | 类数量增多 |
抽象工厂模式 (Abstract Factory) | 提供一个创建一系列相关或相互依赖对象的接口 | 产品族一致性强,便于切换主题 | 不易扩展新的产品类 |
建造者模式 (Builder) | 将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示 | 将构建过程与表示分离,增加灵活性 | 产品结构不清晰时使用不方便 |
原型模式 (Prototype) | 通过复制现有的实例来创建新对象,而不是通过 new | 避免重复初始化,节省内存 | 深拷贝复杂 |
2. 结构型模式(7 种)
关注类和对象的组合结构。
模式名 | 作用说明 | 优点 | 缺点 |
---|---|---|---|
适配器模式 (Adapter) | 将一个类的接口转换成客户希望的另一个接口 | 兼容性强,解决接口不兼容问题 | 结构复杂 |
桥接模式 (Bridge) | 将抽象部分与实现部分分离,使它们可以独立变化 | 解耦抽象与实现,便于扩展 | 结构复杂,增加代码量 |
装饰器模式 (Decorator) | 动态地给一个对象添加一些额外的职责 | 比继承灵活,功能扩展简便 | 对象层次多,调试复杂 |
组合模式 (Composite) | 将对象组合成树形结构以表示"部分-整体"的层次结构 | 一致性好,便于操作树结构 | 类设计复杂 |
外观模式 (Facade) | 提供一个统一的接口,来访问子系统中的一群接口 | 简化子系统接口的使用,屏蔽复杂性 | 不符合开闭原则,可能造成系统难以扩展 |
享元模式 (Flyweight) | 运用共享技术有效支持大量细粒度对象 | 节省内存,适用于大量对象的共享 | 逻辑复杂,管理困难 |
代理模式 (Proxy) | 为其他对象提供一种代理以控制对这个对象的访问 | 控制对象访问,延迟加载,保护对象隐私 | 增加类数量,性能开销 |
3. 行为型模式(11 种)
关注对象之间的通信与职责分配。
模式名 | 作用说明 | 优点 | 缺点 |
---|---|---|---|
责任链模式 (Chain of Responsibility) | 使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合 | 请求发送者与接收者解耦,增加灵活性 | 调试困难,责任链过长影响性能 |
命令模式 (Command) | 将请求封装成对象,从而可用不同的请求对客户进行参数化 | 请求封装解耦,易扩展 | 类数量增多,可能导致代码繁琐 |
解释器模式 (Interpreter) | 给定一种语言,定义它的文法表示,并定义一个解释器来解释语言中的句子 | 扩展性强,适合规则引擎的实现 | 结构复杂,效率低 |
迭代器模式 (Iterator) | 提供一种方法顺序访问一个聚合对象中各个元素 | 统一遍历接口,简化代码 | 类增多,增加程序复杂度 |
中介者模式 (Mediator) | 用一个中介对象封装一系列对象之间的交互 | 简化对象间的复杂交互关系,减少耦合 | 中介者可能过于复杂,影响维护 |
备忘录模式 (Memento) | 在不破坏封装性的前提下,捕获对象的内部状态,以便恢复 | 状态恢复不破坏封装,便于实现撤销/恢复操作 | 占用内存,可能导致性能问题 |
观察者模式 (Observer) | 对象间的一种一对多依赖关系,一个对象状态改变,所有依赖者都会收到通知 | 解耦数据和显示,通知机制灵活 | 通知链过长,影响性能,难以追踪依赖关系 |
状态模式 (State) | 允许一个对象在其内部状态改变时改变它的行为 | 状态与行为分离,增强代码可读性和扩展性 | 状态类数量多,结构复杂 |
策略模式 (Strategy) | 定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换 | 算法独立,便于扩展和替换 | 客户端需要了解策略,可能造成接口复杂 |
模板方法模式 (Template Method) | 定义算法骨架,而将一些步骤延迟到子类实现 | 代码复用性高,结构清晰 | 不易扩展步骤顺序 |
访问者模式 (Visitor) | 表示一个作用于某对象结构中的各元素的操作,可在不改变类的前提下定义新操作 | 增加操作灵活性,符合开闭原则 | 数据结构频繁修改时使用不方便 |
二.、常用设计模式:
1. 常用创建型模式
模式名 | 说明 | 场景示例 |
---|---|---|
单例模式 (Singleton) | 保证全局唯一实例 | Spring 的 Bean 默认是单例;数据库连接池 |
工厂方法模式 (Factory Method) | 解耦对象创建 | 日志框架(如 SLF4J)、数据库驱动注册 |
建造者模式 (Builder) | 构建复杂对象 | StringBuilder 、Lombok @Builder 注解 |
2. 常用结构型模式
模式名 | 说明 | 场景示例 |
---|---|---|
适配器模式 (Adapter) | 接口适配兼容老系统 | JDBC Driver、SpringMVC 参数适配器 |
装饰器模式 (Decorator) | 动态增强对象功能 | Java IO 流(BufferedInputStream 等) |
代理模式 (Proxy) | 控制访问、添加额外逻辑 | AOP(如事务、权限)、远程代理(RPC) |
3. 常用行为型模式
模式名 | 说明 | 场景示例 |
---|---|---|
观察者模式 (Observer) | 一对多通知 | EventBus、GUI 事件处理、消息订阅 |
策略模式 (Strategy) | 算法可替换 | 支付系统、优惠计算、认证策略 |
模板方法模式 (Template Method) | 统一流程,子类差异化 | Spring 中的JdbcTemplate 、AbstractController |
责任链模式 (Chain of Responsibility) | 顺序处理请求 | Servlet 过滤器链、责任审批流 |
4. 加分项:框架中广泛应用的设计模式
- Spring 框架 :
- 单例模式(Bean 生命周期)
- 工厂模式(BeanFactory)
- 代理模式(AOP)
- 模板方法(JdbcTemplate)
- 策略模式(
BeanPostProcessor
策略扩展)
- MyBatis / Hibernate :
- 建造者模式(构造 SQL)
- 代理模式(Mapper 代理对象)
5. 建议重点掌握(必学)
模式 | 理解深度建议 |
---|---|
单例模式 | 熟练掌握懒汉/饿汉/双检锁写法 |
工厂 & 抽象工厂 | 理解工厂解耦思想 |
建造者模式 | 能用来构建链式配置对象 |
策略模式 | 能识别和封装算法 |
观察者模式 | 掌握事件发布订阅机制 |
代理模式 | 明白静态 vs 动态代理 |
模板方法模式 | 理解钩子方法设计思想 |
三、常用设计模式 - 逐一讲解:
创建型模式:
1. 单例模式(Singleton)
使用场景:配置管理器、数据库连接池、日志类等需要保证全局唯一性的地方。
优点:
- 节省资源(只实例化一次)
- 全局访问点
缺点:
- 懒汉模式线程不安全,需加锁
- 不利于扩展和测试
java
// 懒汉式线程安全单例模式实现
public class Singleton {
// 使用 volatile 保证线程可见性和禁止指令重排序
private static volatile Singleton instance;
// 私有构造函数,防止外部实例化
private Singleton() {}
// 提供全局访问点
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
// main 方法示例
class SingletonDemo {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true
}
}
2. 工厂方法模式(Factory Method)
使用场景:不明确需要实例化哪个类时(如日志框架、数据库驱动)。
优点:
- 解耦创建过程和使用过程
- 新增产品类容易
缺点:
- 增加类数量
- 结构复杂
java
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
public void use() {
System.out.println("使用产品A");
}
}
// 工厂接口
interface Factory {
Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA implements Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
// main 方法示例
class FactoryMethodDemo {
public static void main(String[] args) {
Factory factory = new ConcreteFactoryA();
Product product = factory.createProduct();
product.use();
}
}
3. 建造者模式(Builder)
使用场景:构建复杂对象(如 StringBuilder、HTML 生成器)。
优点:
- 封装复杂构建过程
- 解耦构建代码和表示
缺点:
- 增加类数量
- 构造过程固定
java
// 产品类
class Product {
private String partA;
private String partB;
public void setPartA(String partA) { this.partA = partA; }
public void setPartB(String partB) { this.partB = partB; }
public void show() {
System.out.println(partA + " - " + partB);
}
}
// 建造者类
class Builder {
private Product product = new Product();
public Builder buildPartA(String partA) {
product.setPartA(partA);
return this;
}
public Builder buildPartB(String partB) {
product.setPartB(partB);
return this;
}
public Product getResult() {
return product;
}
}
// main 方法示例
class BuilderDemo {
public static void main(String[] args) {
Builder builder = new Builder();
Product product = builder.buildPartA("引擎").buildPartB("轮子").getResult();
product.show();
}
}
常用结构型模式:
1. 适配器模式(Adapter)
使用场景:接口不兼容但需要协作的系统,比如老系统和新系统的集成。
优点:
- 提高类的复用性
- 解耦系统间依赖
缺点:
- 过多使用会使系统复杂
java
// 目标接口
interface Target {
void request();
}
// 被适配类
class Adaptee {
public void specificRequest() {
System.out.println("适配者的方法");
}
}
// 适配器类
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest();
}
}
// main 方法示例
class AdapterDemo {
public static void main(String[] args) {
Target target = new Adapter(new Adaptee());
target.request();
}
}
2. 装饰器模式(Decorator)
使用场景:在不修改原类的基础上动态增加功能,例如 Java IO 流。
优点:
- 可动态扩展类的功能
- 比继承更加灵活
缺点:
- 多层装饰难以排查问题
java
// 抽象组件
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;
}
}
// 具体装饰器
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
component.operation();
addedFunction();
}
private void addedFunction() {
System.out.println("扩展功能");
}
}
// main 方法示例
class DecoratorDemo {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Component decorator = new ConcreteDecorator(component);
decorator.operation();
}
}
3. 代理模式(Proxy)
使用场景:控制访问权限、增强方法、远程调用等,比如 AOP。
优点:
- 控制对象访问
- 增强目标对象的功能
缺点:
- 增加系统复杂度
java
// 接口
interface Subject {
void request();
}
// 真实对象
class RealSubject implements Subject {
public void request() {
System.out.println("真实请求");
}
}
// 代理对象
class Proxy implements Subject {
private RealSubject realSubject;
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
System.out.println("访问控制和日志记录");
realSubject.request();
}
}
// main 方法示例
class ProxyDemo {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.request();
}
}
常用行为型模式:
1. 观察者模式(Observer)
使用场景:一对多通知机制,适用于事件驱动模型、消息订阅等场景。
优点:
- 降低了主题和观察者之间的耦合
- 支持广播通信,易于扩展
缺点:
- 如果观察者太多,通知开销较大
- 观察者被触发时顺序不确定
java
import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
void update(String message);
}
// 具体观察者
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);
}
}
// 主题接口
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String message);
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// main 方法示例
class ObserverDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("观察者1");
Observer observer2 = new ConcreteObserver("观察者2");
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("事件发生");
}
}
2. 策略模式(Strategy)
使用场景:多个算法可以替换的场景,如支付系统中的支付策略、优惠计算等。
优点:
- 动态切换算法
- 增加新策略非常方便,符合开闭原则
缺点:
- 客户端需要知道策略的差异
- 增加类的数量
java
// 策略接口
interface PaymentStrategy {
void pay(int amount);
}
// 具体支付策略:支付宝
class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("通过支付宝支付 " + amount + " 元");
}
}
// 具体支付策略:微信支付
class WechatStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("通过微信支付 " + amount + " 元");
}
}
// 上下文类
class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(int amount) {
strategy.pay(amount);
}
}
// main 方法示例
class StrategyDemo {
public static void main(String[] args) {
PaymentContext context = new PaymentContext(new AlipayStrategy());
context.executePayment(100);
context = new PaymentContext(new WechatStrategy());
context.executePayment(200);
}
}
3. 模板方法模式(Template Method)
使用场景:统一流程控制,子类差异化实现步骤,适用于一些固定流程的场景,如数据库访问框架中的 JdbcTemplate。
优点:
- 统一了算法的骨架
- 子类实现了不同的步骤,符合开闭原则
缺点:
- 复杂的继承结构可能导致系统过于繁杂
- 可能导致模板方法中的某些步骤不灵活
java
// 抽象类,定义模板方法
abstract class AbstractTemplate {
public void execute() {
step1();
step2();
step3();
}
protected abstract void step1();
protected abstract void step2();
protected void step3() {
System.out.println("步骤3:执行通用操作");
}
}
// 具体实现类
class ConcreteTemplate extends AbstractTemplate {
@Override
protected void step1() {
System.out.println("步骤1:子类实现特定操作");
}
@Override
protected void step2() {
System.out.println("步骤2:子类实现特定操作");
}
}
// main 方法示例
class TemplateMethodDemo {
public static void main(String[] args) {
AbstractTemplate template = new ConcreteTemplate();
template.execute();
}
}
4. 责任链模式(Chain of Responsibility)
使用场景:顺序处理请求,如 Servlet 过滤器链、责任审批流。
优点:
- 请求的处理链可以灵活配置
- 请求的发送者与接收者解耦
缺点:
- 请求处理链过长可能影响性能
- 处理责任链不当可能导致请求不被处理
java
// 处理者接口
interface Handler {
void setNext(Handler handler);
void handleRequest(String request);
}
// 具体处理者A
class ConcreteHandlerA implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handleRequest(String request) {
if (request.equals("请求A")) {
System.out.println("处理请求A");
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 具体处理者B
class ConcreteHandlerB implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handleRequest(String request) {
if (request.equals("请求B")) {
System.out.println("处理请求B");
} else if (next != null) {
next.handleRequest(request);
}
}
}
// main 方法示例
class ChainOfResponsibilityDemo {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB);
handlerA.handleRequest("请求A");
handlerA.handleRequest("请求B");
handlerA.handleRequest("未知请求");
}
}
四、其余设计模式 - 逐一讲解:
创建型模式
1. 抽象工厂模式(Abstract Factory)
使用场景:提供一个接口,用于创建相关或依赖的对象家族,而无需指定具体类。适用于需要创建多个产品系列(例如跨平台UI工具包)。
优点:
- 可以确保产品族的一致性
- 增加新产品族容易
缺点:
- 增加系统的复杂性
- 对于新增产品,必须修改所有具体工厂类
java
// 抽象产品A
interface AbstractProductA {
void use();
}
// 具体产品A1
class ConcreteProductA1 implements AbstractProductA {
@Override
public void use() {
System.out.println("使用具体产品A1");
}
}
// 具体产品A2
class ConcreteProductA2 implements AbstractProductA {
@Override
public void use() {
System.out.println("使用具体产品A2");
}
}
// 抽象产品B
interface AbstractProductB {
void performAction();
}
// 具体产品B1
class ConcreteProductB1 implements AbstractProductB {
@Override
public void performAction() {
System.out.println("执行具体产品B1的操作");
}
}
// 具体产品B2
class ConcreteProductB2 implements AbstractProductB {
@Override
public void performAction() {
System.out.println("执行具体产品B2的操作");
}
}
// 抽象工厂
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB2();
}
}
// main 方法示例
class AbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.use(); // 输出 使用具体产品A1
productB1.performAction(); // 输出 执行具体产品B1的操作
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.use(); // 输出 使用具体产品A2
productB2.performAction(); // 输出 执行具体产品B2的操作
}
}
2. 原型模式(Prototype)
使用场景:当创建一个对象的代价比较大时,可以通过复制一个已经存在的对象来减少系统开销。适用于对象的创建过程复杂且耗时。
优点:
- 可以避免重复创建相似对象,提高效率
- 允许在运行时动态选择需要复制的对象
缺点:
- 可能会对原型对象进行不当的修改
- 实现时需要注意深拷贝和浅拷贝的区别
java
// 原型接口
interface Prototype {
Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public Prototype clone() {
return new ConcretePrototype(this.name);
}
}
// main 方法示例
class PrototypeDemo {
public static void main(String[] args) {
ConcretePrototype prototype1 = new ConcretePrototype("原型1");
// 通过原型对象创建一个新的对象
ConcretePrototype prototype2 = (ConcretePrototype) prototype1.clone();
System.out.println("原型1的名称: " + prototype1.getName()); // 输出 原型1
System.out.println("原型2的名称: " + prototype2.getName()); // 输出 原型1
System.out.println("原型1和原型2是否相同: " + (prototype1 == prototype2)); // 输出 false
}
}
结构型模式:
1. 桥接模式(Bridge)
使用场景:将抽象部分与实现部分分离,允许它们独立变化。适用于类的多层继承导致代码耦合度过高的场景。
java
// 抽象类
abstract class Abstraction {
protected Implementor implementor; // 引用实现部分的对象
// 构造方法,传入实现部分的对象
protected Abstraction(Implementor implementor) {
this.implementor = implementor;
}
// 抽象的操作方法,子类会实现具体的操作
public abstract void operation();
}
// 具体的抽象类,实现了抽象操作
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor); // 通过构造方法将实现部分传入
}
@Override
public void operation() {
System.out.println("调用抽象类方法");
implementor.operationImpl(); // 调用具体实现的操作方法
}
}
// 实现接口,定义具体操作
interface Implementor {
void operationImpl();
}
// 具体的实现类A,实现了接口定义的操作
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("具体实现A");
}
}
// 具体的实现类B,实现了接口定义的操作
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("具体实现B");
}
}
// main 方法示例
class BridgeDemo {
public static void main(String[] args) {
Implementor implementorA = new ConcreteImplementorA();
Abstraction abstractionA = new RefinedAbstraction(implementorA);
abstractionA.operation(); // 输出: 调用抽象类方法 具体实现A
Implementor implementorB = new ConcreteImplementorB();
Abstraction abstractionB = new RefinedAbstraction(implementorB);
abstractionB.operation(); // 输出: 调用抽象类方法 具体实现B
}
}
2. 组合模式(Composite)
使用场景:允许您将对象组合成树形结构来表示"部分-整体"层次结构。适用于需要表现对象树形结构的场景。
java
import java.util.ArrayList;
import java.util.List;
// 组件接口,所有叶子节点和容器节点都实现此接口
interface Component {
void operation(); // 所有组件必须实现的操作
}
// 叶子节点类,表示树形结构的最底层元素
class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void operation() {
System.out.println("叶子节点 " + name); // 输出叶子节点名称
}
}
// 容器节点类,表示树形结构中的父节点
class Composite implements Component {
private List<Component> children = new ArrayList<>(); // 存储子节点
@Override
public void operation() {
System.out.println("容器节点"); // 输出容器节点
for (Component child : children) {
child.operation(); // 遍历所有子节点,调用它们的操作
}
}
// 添加子节点
public void add(Component component) {
children.add(component);
}
// 移除子节点
public void remove(Component component) {
children.remove(component);
}
}
// main 方法示例
class CompositeDemo {
public static void main(String[] args) {
Composite root = new Composite(); // 创建根节点
Leaf leaf1 = new Leaf("叶子1"); // 创建叶子节点
Leaf leaf2 = new Leaf("叶子2");
Composite subTree = new Composite(); // 创建子树
Leaf leaf3 = new Leaf("叶子3");
subTree.add(leaf3); // 添加叶子到子树
root.add(leaf1); // 将叶子节点添加到根节点
root.add(leaf2);
root.add(subTree); // 将子树添加到根节点
root.operation(); // 调用根节点的操作,输出整个树形结构
}
}
3. 外观模式(Facade)
使用场景:为复杂的子系统提供一个简化的接口,客户端通过该接口与系统交互。适用于简化复杂系统的使用。
java
// 子系统类A
class SubSystemA {
public void operationA() {
System.out.println("子系统A的操作");
}
}
// 子系统类B
class SubSystemB {
public void operationB() {
System.out.println("子系统B的操作");
}
}
// 子系统类C
class SubSystemC {
public void operationC() {
System.out.println("子系统C的操作");
}
}
// 外观类,提供简化的接口
class Facade {
private SubSystemA subsystemA = new SubSystemA(); // 创建子系统A
private SubSystemB subsystemB = new SubSystemB(); // 创建子系统B
private SubSystemC subsystemC = new SubSystemC(); // 创建子系统C
// 提供简化的操作接口,调用子系统的操作
public void simplifiedOperation() {
subsystemA.operationA();
subsystemB.operationB();
subsystemC.operationC();
}
}
// main 方法示例
class FacadeDemo {
public static void main(String[] args) {
Facade facade = new Facade(); // 创建外观类
facade.simplifiedOperation(); // 调用外观类的方法,简化客户端调用
}
}
4. 享元模式(Flyweight)
使用场景:通过共享对象来有效地支持大量细粒度的对象。适用于对象数目庞大且大部分对象相似的场景,例如文字、图形的绘制。
java
import java.util.HashMap;
import java.util.Map;
// 享元接口,定义享元对象的操作
interface Flyweight {
void operation(String extrinsicState); // 外部状态
}
// 具体享元类,实现享元接口
class ConcreteFlyweight implements Flyweight {
private String intrinsicState; // 内部状态
// 构造方法,接收并设置内部状态
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
@Override
public void operation(String extrinsicState) {
System.out.println("享元对象:" + intrinsicState + ",外部状态:" + extrinsicState);
}
}
// 享元工厂类,用于管理共享的享元对象
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>(); // 存储享元对象的池
// 获取享元对象,如果池中没有,则创建并放入池中
public Flyweight getFlyweight(String intrinsicState) {
if (!flyweights.containsKey(intrinsicState)) {
flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
}
return flyweights.get(intrinsicState);
}
}
// main 方法示例
class FlyweightDemo {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory(); // 创建享元工厂
Flyweight flyweight1 = factory.getFlyweight("共享对象1"); // 获取共享对象
flyweight1.operation("外部状态1"); // 调用操作方法
Flyweight flyweight2 = factory.getFlyweight("共享对象1"); // 再次获取相同的共享对象
flyweight2.operation("外部状态2");
Flyweight flyweight3 = factory.getFlyweight("共享对象2"); // 获取不同的共享对象
flyweight3.operation("外部状态3");
}
}
常用行为型模式:
1. 命令模式(Command)
使用场景:将请求封装为对象,从而使您能够使用不同的请求、队列或日志来参数化其他对象。适用于需要将请求抽象化为对象的场景。
java
// 命令接口
interface Command {
void execute(); // 执行命令
}
// 具体命令类A,实现命令接口
class ConcreteCommandA implements Command {
private Receiver receiver; // 持有接收者的引用
public ConcreteCommandA(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.actionA(); // 执行接收者的操作
}
}
// 具体命令类B,实现命令接口
class ConcreteCommandB implements Command {
private Receiver receiver;
public ConcreteCommandB(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.actionB();
}
}
// 接收者类,执行具体的操作
class Receiver {
public void actionA() {
System.out.println("执行接收者的操作A");
}
public void actionB() {
System.out.println("执行接收者的操作B");
}
}
// 调用者类,负责发出命令
class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute(); // 执行命令
}
}
// main 方法示例
class CommandDemo {
public static void main(String[] args) {
Receiver receiver = new Receiver(); // 创建接收者
Command commandA = new ConcreteCommandA(receiver); // 创建命令A
Command commandB = new ConcreteCommandB(receiver); // 创建命令B
Invoker invoker = new Invoker();
invoker.setCommand(commandA); // 设置命令A
invoker.executeCommand(); // 执行命令A
invoker.setCommand(commandB); // 设置命令B
invoker.executeCommand(); // 执行命令B
}
}
2. 解释器模式(Interpreter)
使用场景:为语言的语法定义一个解释器,适用于需要解释语法的场景,如计算器、编译器等。
java
// 抽象表达式
interface Expression {
int interpret();
}
// 终结符表达式
class Number implements Expression {
private int number;
public Number(int number) {
this.number = number;
}
@Override
public int interpret() {
return number; // 返回数字
}
}
// 非终结符表达式(加法)
class Add implements Expression {
private Expression left;
private Expression right;
public Add(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() + right.interpret(); // 返回加法结果
}
}
// 非终结符表达式(减法)
class Subtract implements Expression {
private Expression left;
private Expression right;
public Subtract(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() - right.interpret(); // 返回减法结果
}
}
// main 方法示例
class InterpreterDemo {
public static void main(String[] args) {
Expression left = new Number(5); // 5
Expression right = new Number(3); // 3
Expression addExpression = new Add(left, right); // 5 + 3
System.out.println("5 + 3 = " + addExpression.interpret()); // 输出:5 + 3 = 8
Expression subtractExpression = new Subtract(left, right); // 5 - 3
System.out.println("5 - 3 = " + subtractExpression.interpret()); // 输出:5 - 3 = 2
}
}
3. 迭代器模式(Iterator)
使用场景:提供一种方法顺序访问集合对象,而不暴露该对象的内部表示。适用于需要遍历集合的场景。
java
import java.util.ArrayList;
import java.util.List;
// 迭代器接口
interface Iterator {
boolean hasNext(); // 判断是否还有下一个元素
Object next(); // 获取下一个元素
}
// 集合接口
interface Collection {
Iterator createIterator(); // 创建迭代器
}
// 具体集合类
class ConcreteCollection implements Collection {
private List<String> items = new ArrayList<>();
public ConcreteCollection() {
items.add("Item1");
items.add("Item2");
items.add("Item3");
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(this); // 返回具体的迭代器
}
// 获取集合中的元素
public String getItem(int index) {
return items.get(index);
}
// 集合大小
public int size() {
return items.size();
}
}
// 具体迭代器类
class ConcreteIterator implements Iterator {
private ConcreteCollection collection;
private int index = 0;
public ConcreteIterator(ConcreteCollection collection) {
this.collection = collection;
}
@Override
public boolean hasNext() {
return index < collection.size(); // 判断是否还有下一个元素
}
@Override
public Object next() {
return collection.getItem(index++); // 返回当前元素,并移动到下一个
}
}
// main 方法示例
class IteratorDemo {
public static void main(String[] args) {
ConcreteCollection collection = new ConcreteCollection(); // 创建集合
Iterator iterator = collection.createIterator(); // 获取迭代器
while (iterator.hasNext()) {
System.out.println(iterator.next()); // 输出集合中的每个元素
}
}
}
4. 中介者模式(Mediator)
使用场景:通过一个中介者来协调多个对象之间的交互,避免对象之间直接交互导致的耦合。适用于复杂对象交互的场景。
java
// 中介者接口
interface Mediator {
void send(String message, Colleague colleague); // 发送消息给某个同事
}
// 同事类
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive(String message); // 接收消息
}
// 具体同事类A
class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
@Override
public void receive(String message) {
System.out.println("同事A收到消息: " + message);
}
}
// 具体同事类B
class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
@Override
public void receive(String message) {
System.out.println("同事B收到消息: " + message);
}
}
// 具体中介者类
class ConcreteMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == colleagueA) {
colleagueB.receive(message); // 同事A发送消息给同事B
} else {
colleagueA.receive(message); // 同事B发送消息给同事A
}
}
}
// main 方法示例
class MediatorDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.setColleagueA(colleagueA);
mediator.setColleagueB(colleagueB);
colleagueA.receive("Hello from A");
colleagueB.receive("Hello from B");
}
}
5. 备忘录模式(Memento)
使用场景:在不暴露对象实现细节的情况下,保存和恢复对象的内部状态。适用于需要保存状态并能够恢复状态的场景。
java
// 备忘录类,保存状态
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起人类,维护当前状态
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento saveStateToMemento() {
return new Memento(state); // 保存状态到备忘录
}
public void restoreStateFromMemento(Memento memento) {
state = memento.getState(); // 从备忘录恢复状态
}
}
// 管理者类,管理多个备忘录
class Caretaker {
private Memento memento;
public void saveMemento(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
}
// main 方法示例
class MementoDemo {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("状态1");
System.out.println("当前状态: " + originator.getState());
caretaker.saveMemento(originator.saveStateToMemento()); // 保存状态
originator.setState("状态2");
System.out.println("修改后的状态: " + originator.getState());
originator.restoreStateFromMemento(caretaker.getMemento()); // 恢复状态
System.out.println("恢复后的状态: " + originator.getState());
}
}
6. 状态模式(State)
使用场景:允许对象在其内部状态改变时改变其行为。适用于对象的行为与其状态相关的场景。
java
// 状态接口
interface State {
void handleRequest(); // 处理请求
}
// 具体状态类A
class ConcreteStateA implements State {
@Override
public void handleRequest() {
System.out.println("处理请求,当前状态A");
}
}
// 具体状态类B
class ConcreteStateB implements State {
@Override
public void handleRequest() {
System.out.println("处理请求,当前状态B");
}
}
// 环境类,持有当前状态的对象
class Context {
private State currentState;
public Context() {
currentState = new ConcreteStateA(); // 默认状态A
}
public void setState(State state) {
this.currentState = state;
}
public void request() {
currentState.handleRequest(); // 调用当前状态的操作
}
}
// main 方法示例
class StateDemo {
public static void main(String[] args) {
Context context = new Context(); // 创建环境对象
context.request(); // 执行状态A的操作
context.setState(new ConcreteStateB()); // 切换到状态B
context.request(); // 执行状态B的操作
}
}