Java-Spring框架中用到的设计模式
-
单例模式(Singleton)
Spring 中的 Bean 默认是单例的,容器中只存在一个实例。这有助于节省资源,提高性能。
-
工厂模式(Factory)
Spring 使用工厂模式来创建和管理 Bean。通过配置文件或注解,Spring 容器可以根据需要创建相应的 Bean 对象。
-
代理模式(Proxy)
Spring 使用代理模式来实现 AOP(面向切面编程)。AOP 将横切关注点(如日志、事务)与业务逻辑分离,通过代理来控制横切关注点的执行。
-
观察者模式(Observer)
Spring 事件机制是基于观察者模式实现的。应用程序可以发布事件,而监听器可以订阅这些事件,并在事件发生时执行相应的操作。
-
模板方法模式(Template Method)
Spring 的 JdbcTemplate 和 HibernateTemplate 等模板类使用了模板方法模式。在这些模板类中,定义了一套算法骨架,具体的步骤由子类实现。
-
策略模式(Strategy)
Spring 的资源加载和资源解析等机制中使用了策略模式。不同的实现类对应不同的策略,根据需要选择不同的策略。
-
适配器模式(Adapter)
Spring MVC 中的 HandlerAdapter 就是适配器模式的应用,它负责将处理器适配到框架中,使得可以处理不同类型的处理器。
适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户期望的另一个接口。这种模式通常用于使已有的类在不修改其源代码的情况下与其他类协作。
结构和角色:
- 目标接口(Target): 定义客户端使用的接口,客户端通过目标接口调用适配器的方法。
- 适配器(Adapter): 实现了目标接口,并包装了被适配者的对象,将客户端调用目标接口的请求转换为对被适配者的适当调用。
- 被适配者(Adaptee): 已存在的类,具有客户端需要的功能,但其接口与目标接口不匹配。
示例代码:
假设有一个英文播报系统和一个中文播报系统,现在希望通过适配器,使得英文播报系统也能以中文的方式播报。
// 目标接口 interface Speaker { void speak(); } // 被适配者 class EnglishSpeaker { void speakInEnglish() { System.out.println("Speaking in English"); } } // 适配器 class EnglishAdapter implements Speaker { private EnglishSpeaker englishSpeaker; public EnglishAdapter(EnglishSpeaker englishSpeaker) { this.englishSpeaker = englishSpeaker; } @Override public void speak() { englishSpeaker.speakInEnglish(); } } // 客户端代码 public class AdapterPatternDemo { public static void main(String[] args) { EnglishSpeaker englishSpeaker = new EnglishSpeaker(); Speaker adapter = new EnglishAdapter(englishSpeaker); // 调用适配器的接口,实际上会调用被适配者的方法 adapter.speak(); } }
-
装饰者模式(Decorator)
Spring AOP 中的增强(Advice)就是一种装饰者模式的应用。增强可以在目标方法执行前、执行后等时机进行装饰。
装饰者模式是一种结构型设计模式,允许向一个对象动态地添加功能,而无需通过继承来实现。这种模式是继承的一个替代方案。
结构和角色:
- 组件接口(Component): 定义了被装饰者和具体装饰者共同实现的接口。
- 具体组件(ConcreteComponent): 实现了组件接口的具体类,是被装饰的原始对象。
- 装饰者(Decorator): 包含一个指向组件对象的引用,并实现了组件接口。通常是一个抽象类。
- 具体装饰者(ConcreteDecorator): 扩展了装饰者,向组件添加新的行为或状态。
示例代码:
假设有一个咖啡店,提供基础的咖啡和可以选择添加不同调料的装饰者。
// 组件接口 interface Coffee { double cost(); } // 具体组件 class SimpleCoffee implements Coffee { @Override public double cost() { return 5.0; // 基础咖啡的价格 } } // 装饰者 abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee decoratedCoffee) { this.decoratedCoffee = decoratedCoffee; } @Override public double cost() { return decoratedCoffee.cost(); } } // 具体装饰者 class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee decoratedCoffee) { super(decoratedCoffee); } @Override public double cost() { return super.cost() + 2.0; // 添加牛奶的价格 } } // 客户端代码 public class DecoratorPatternDemo { public static void main(String[] args) { Coffee simpleCoffee = new SimpleCoffee(); System.out.println("Cost of simple coffee: $" + simpleCoffee.cost()); Coffee milkCoffee = new MilkDecorator(simpleCoffee); System.out.println("Cost of coffee with milk: $" + milkCoffee.cost()); } }
这个例子中,
SimpleCoffee
是基础咖啡,MilkDecorator
是具体装饰者,用于向咖啡添加牛奶。客户端可以根据需要选择添加不同的调料。这种方式使得代码更加灵活,可以动态地组合对象。