创建型设计模式
-
工厂方法模式 (Factory Method Pattern)
- 原理:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法使一个类的实例化延迟到其子类。
- 代码实例:
// 产品接口 interface Product { void use(); } // 具体产品A class ConcreteProductA implements Product { public void use() { System.out.println("Using Product A"); } } // 具体产品B class ConcreteProductB implements Product { public void use() { System.out.println("Using Product B"); } } // 工厂基类 abstract class Creator { public abstract Product factoryMethod(); public void doSomething() { Product product = factoryMethod(); product.use(); } } // 具体工厂A class ConcreteCreatorA extends Creator { public Product factoryMethod() { return new ConcreteProductA(); } } // 具体工厂B class ConcreteCreatorB extends Creator { public Product factoryMethod() { return new ConcreteProductB(); } } // 客户端代码 public class FactoryMethodExample { public static void main(String[] args) { Creator creatorA = new ConcreteCreatorA(); creatorA.doSomething(); Creator creatorB = new ConcreteCreatorB(); creatorB.doSomething(); } }
- 使用场景:适用于需要延迟实例化的情况,例如根据配置文件选择不同实现类。
- Spring应用:Spring中的
BeanFactory
就是工厂方法模式的应用。
-
抽象工厂模式 (Abstract Factory Pattern)
- 原理:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 代码实例:
// 抽象产品A interface ProductA { void use(); } // 抽象产品B interface ProductB { void eat(); } // 具体产品A1 class ConcreteProductA1 implements ProductA { public void use() { System.out.println("Using Product A1"); } } // 具体产品B1 class ConcreteProductB1 implements ProductB { public void eat() { System.out.println("Eating Product B1"); } } // 抽象工厂 interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); } // 具体工厂1 class ConcreteFactory1 implements AbstractFactory { public ProductA createProductA() { return new ConcreteProductA1(); } public ProductB createProductB() { return new ConcreteProductB1(); } } // 客户端代码 public class AbstractFactoryExample { public static void main(String[] args) { AbstractFactory factory = new ConcreteFactory1(); ProductA productA = factory.createProductA(); ProductB productB = factory.createProductB(); productA.use(); productB.eat(); } }
- 使用场景:适用于需要创建多个相互关联的对象系列,而无需关心它们具体实现的情况。
- Spring应用:Spring的
AbstractApplicationContext
可以视为抽象工厂的实现。
-
单例模式 (Singleton Pattern)
- 原理:确保一个类只有一个实例,并提供一个全局访问点。
- 代码实例:
class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } public class SingletonExample { public static void main(String[] args) { Singleton singleton1 = Singleton.getInstance(); Singleton singleton2 = Singleton.getInstance(); System.out.println(singleton1 == singleton2); // 输出: true } }
- 使用场景:适用于需要一个全局唯一类的情况,例如配置管理类、数据库连接池等。
- Spring应用:Spring的
@Component
和@Bean
默认是单例模式。
-
建造者模式 (Builder Pattern)
- 原理:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 代码实例:
class Product { private String partA; private String partB; private String partC; public void setPartA(String partA) { this.partA = partA; } public void setPartB(String partB) { this.partB = partB; } public void setPartC(String partC) { this.partC = partC; } public void show() { System.out.println("Product parts: " + partA + ", " + partB + ", " + partC); } } class ProductBuilder { private Product product = new Product(); public ProductBuilder buildPartA(String partA) { product.setPartA(partA); return this; } public ProductBuilder buildPartB(String partB) { product.setPartB(partB); return this; } public ProductBuilder buildPartC(String partC) { product.setPartC(partC); return this; } public Product build() { return product; } } public class BuilderPatternExample { public static void main(String[] args) { ProductBuilder builder = new ProductBuilder(); Product product = builder.buildPartA("Part A").buildPartB("Part B").buildPartC("Part C").build(); product.show(); } }
- 使用场景:构建复杂对象,且需要可变的步骤。例如构建复杂的UI。
- Spring应用:
Spring BeanDefinitionBuilder
用于构建Bean的定义。
-
原型模式 (Prototype Pattern)
- 原理:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
- 代码实例:
class Prototype implements Cloneable { private String name; public Prototype(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } @Override protected Prototype clone() throws CloneNotSupportedException { return (Prototype) super.clone(); } } public class PrototypePatternExample { public static void main(String[] args) { try { Prototype prototype1 = new Prototype("Prototype 1"); Prototype prototype2 = prototype1.clone(); prototype2.setName("Prototype 2"); System.out.println(prototype1.getName()); // 输出: Prototype 1 System.out.println(prototype2.getName()); // 输出: Prototype 2 } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
- 使用场景:创建代价较大的对象,或者需要保证对象状态一致时。
- Spring应用:Spring中通过
scope="prototype"
来创建每次调用都返回一个新的Bean实例。
结构型设计模式
-
适配器模式 (Adapter Pattern)
- 原理:将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 代码实例:
interface Target { void request(); } class Adaptee { void specificRequest() { System.out.println("Specific request"); } } class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } public void request() { adaptee.specificRequest(); } } public class AdapterPatternExample { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target adapter = new Adapter(adaptee); adapter.request(); } }
- 使用场景:当希望使用一个已有类,但其接口不符合要求时使用。
- Spring应用:
HandlerAdapter
是典型的适配器模式应用,负责将Controller处理的结果转化为用户能够理解的结果。
-
桥接模式 (Bridge Pattern)
- 原理:将抽象部分与实现部分分离,使它们都可以独立变化。
- 代码实例:
// 实现者接口 interface Implementor { void operationImpl(); } // 具体实现A class ConcreteImplementorA implements Implementor { public void operationImpl() { System.out.println("Concrete Implementor A operation"); } } // 抽象类 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); } public void operation() { implementor.operationImpl(); } } public class BridgePatternExample { public static void main(String[] args) { Implementor implementor = new ConcreteImplementorA(); Abstraction abstraction = new RefinedAbstraction(implementor); abstraction.operation(); } }
- 使用场景:系统需要在多个维度上独立扩展时,例如GUI系统的外观与功能。
- Spring应用:
JdbcTemplate
结合不同的数据库驱动就是桥接模式的应用。
-
组合模式 (Composite Pattern)
- 原理:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
- 代码实例:
interface Component { void operation(); } class Leaf implements Component { public void operation() { System.out.println("Leaf operation"); } } class Composite implements Component { private List<Component> children = new ArrayList<>(); public void add(Component component) { children.add(component); } public void operation() { for (Component child : children) { child.operation(); } } } public class CompositePatternExample { public static void main(String[] args) { Composite root = new Composite(); Leaf leaf1 = new Leaf(); Leaf leaf2 = new Leaf(); root.add(leaf1); root.add(leaf2); root.operation(); } }
- 使用场景:适用于需要表示树形结构的问题,例如文件系统、组织结构图。
- Spring应用:Spring的
BeanFactory
和ApplicationContext
都可以看作是组合模式的应用。
-
装饰器模式 (Decorator Pattern)
- 原理:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
- 代码实例:
interface Component { void operation(); } class ConcreteComponent implements Component { public void operation() { System.out.println("Concrete Component operation"); } } 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(); System.out.println("Adding additional functionality"); } } public class DecoratorPatternExample { public static void main(String[] args) { Component component = new ConcreteComponent(); Component decorator = new ConcreteDecorator(component); decorator.operation(); } }
- 使用场景:需要动态扩展对象的功能时,例如给一个按钮添加多种不同的样式。
- Spring应用:Spring中的
BeanWrapper
可以用于在运行时为Bean添加额外的功能。
-
外观模式 (Facade Pattern)
- 原理:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这一接口使得这一子系统更加容易使用。
- 代码实例:
class SubsystemA { void operationA() { System.out.println("Subsystem A operation"); } } class SubsystemB { void operationB() { System.out.println("Subsystem B operation"); } } class Facade { private SubsystemA subsystemA = new SubsystemA(); private SubsystemB subsystemB = new SubsystemB(); public void operation() { subsystemA.operationA(); subsystemB.operationB(); } } public class FacadePatternExample { public static void main(String[] args) { Facade facade = new Facade(); facade.operation(); } }
- 使用场景:提供一个简化的接口来访问复杂的子系统,例如简化数据库访问的外观类。
- Spring应用:
JdbcTemplate
是一个外观模式的实现,它简化了JDBC的操作。
- 享元模式 (Flyweight Pattern)
- 原理:运用共享技术有效地支持大量细粒度的对象。
- 代码实例:
class Flyweight { private String intrinsicState; public Flyweight(String state) { this.intrinsicState = state; } public void operation(String extrinsicState) { System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState); } } class FlyweightFactory { private Map<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String key) { if (!flyweights.containsKey(key)) { flyweights.put(key, new Flyweight(key)); } return flyweights.get(key); } } public class FlyweightPatternExample { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweight1 = factory.getFlyweight("State1"); Flyweight flyweight2 = factory.getFlyweight("State2"); Flyweight flyweight3 = factory.getFlyweight("State1"); flyweight1.operation("Extrinsic1"); flyweight2.operation("Extrinsic2"); flyweight3.operation("Extrinsic3"); } }
- 使用场景:适用于需要大量相似对象的场景,例如字符、图片等重复出现的情况。
- Spring应用:Spring中的缓存机制可以看作是享元模式的应用。
- 代理模式 (Proxy Pattern)
- 原理:为其他对象提供一种代理以控制对这个对象的访问。
- 代码实例:
interface Subject { void request(); } class RealSubject implements Subject { public void request() { System.out.println("Real subject request"); } } class Proxy implements Subject { private RealSubject realSubject; public void request() { if (realSubject == null) { realSubject = new RealSubject(); } realSubject.request(); } } public class ProxyPatternExample { public static void main(String[] args) { Subject proxy = new Proxy(); proxy.request(); } }
- 使用场景:需要控制对对象的访问,例如懒加载、安全控制等。
- Spring应用:AOP(面向切面编程)就是代理模式的一个典型应用,通过代理对方法进行增强。
行为型设计模式
- 责任链模式 (Chain of Responsibility Pattern)
- 原理:为请求创建一个接收者对象的链。每个对象沿着链处理请求,直到有一个对象处理它为止。
- 代码实例:
abstract class Handler { protected Handler next; public void setNext(Handler next) { this.next = next; } public abstract void handleRequest(String request); } class ConcreteHandlerA extends Handler { public void handleRequest(String request) { if (request.equals("A")) { System.out.println("Handler A handled request"); } else if (next != null) { next.handleRequest(request); } } } class ConcreteHandlerB extends Handler { public void handleRequest(String request) { if (request.equals("B")) { System.out.println("Handler B handled request"); } else if (next != null) { next.handleRequest(request); } } } public class ChainOfResponsibilityExample { public static void main(String[] args) { Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); handlerA.setNext(handlerB); handlerA.handleRequest("B"); } }
- 使用场景:有多个对象可以处理一个请求时,例如审批流程。
- Spring应用:Spring Security中的过滤器链就是责任链模式的典型应用。
- 命令模式 (Command Pattern)
- 原理:将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。
- 代码实例:
interface Command { void execute(); } class ConcreteCommand implements Command { private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(); } } class Receiver { public void action() { System.out.println("Receiver action"); } } public class CommandPatternExample { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); command.execute(); } }
- 使用场景:需要对请求排队、记录日志或者支持撤销操作时。
- Spring应用:
@Async
注解使用命令模式来异步执行命令。
- 解释器模式 (Interpreter Pattern)
- 原理:给定一个语言,定义它的文法表示,并定义一个解释器来处理这个文法中的句子。
- 代码实例:
interface Expression { int interpret(); } class Number implements Expression { private int number; public Number(int number) { this.number = number; } 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; } public int interpret() { return left.interpret() + right.interpret(); } } public class InterpreterPatternExample { public static void main(String[] args) { Expression left = new Number(5); Expression right = new Number(10); Expression add = new Add(left, right); System.out.println("Result: " + add.interpret()); } }
- 使用场景:当需要解释一种特定语言时,例如数学表达式的计算。
- Spring应用:Spring中的
SpEL
(Spring Expression Language)就是解释器模式的实现。
- 迭代器模式 (Iterator Pattern)
- 原理:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
- 代码实例:
interface Iterator { boolean hasNext(); Object next(); } class ConcreteIterator implements Iterator { private List<Object> items; private int position = 0; public ConcreteIterator(List<Object> items) { this.items = items; } public boolean hasNext() { return position < items.size(); } public Object next() { return items.get(position++); } } class Aggregate { private List<Object> items = new ArrayList<>(); public void addItem(Object item) { items.add(item); } public Iterator createIterator() { return new ConcreteIterator(items); } } public class IteratorPatternExample { public static void main(String[] args) { Aggregate aggregate = new Aggregate(); aggregate.addItem("Item1"); aggregate.addItem("Item2"); aggregate.addItem("Item3"); Iterator iterator = aggregate.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
- 使用场景:需要遍历一个聚合对象时,例如Java中的集合遍历。
- Spring应用:Spring的
ListableBeanFactory
可以使用迭代器模式来遍历Bean。
- 中介者模式 (Mediator Pattern)
- 原理:用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散。
- 代码实例:
interface Mediator { void notify(Component sender, String event); } class ConcreteMediator implements Mediator { private ComponentA componentA; private ComponentB componentB; public void setComponentA(ComponentA componentA) { this.componentA = componentA; } public void setComponentB(ComponentB componentB) { this.componentB = componentB; } public void notify(Component sender, String event) { if (event.equals("A")) { componentB.react(); } } } class Component { protected Mediator mediator; public Component(Mediator mediator) { this.mediator = mediator; } } class ComponentA extends Component { public ComponentA(Mediator mediator) { super(mediator); } public void triggerEvent() { System.out.println("Component A triggered event"); mediator.notify(this, "A"); } } class ComponentB extends Component { public ComponentB(Mediator mediator) { super(mediator); } public void react() { System.out.println("Component B reacting to event"); } } public class MediatorPatternExample { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); ComponentA componentA = new ComponentA(mediator); ComponentB componentB = new ComponentB(mediator); mediator.setComponentA(componentA); mediator.setComponentB(componentB); componentA.triggerEvent(); } }
- 使用场景:当对象之间的交互复杂且呈现网状结构时。
- Spring应用:Spring的
ApplicationEventPublisher
就是中介者模式的应用。
- 备忘录模式 (Memento Pattern)
- 原理:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复它。
- 代码实例:
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 Memento saveState() { return new Memento(state); } public void restoreState(Memento memento) { this.state = memento.getState(); } } public class MementoPatternExample { public static void main(String[] args) { Originator originator = new Originator(); originator.setState("State1"); Memento memento = originator.saveState(); originator.setState("State2"); System.out.println("Current State: " + originator.state); originator.restoreState(memento); System.out.println("Restored State: " + originator.state); } }
- 使用场景:需要保存对象的历史状态以便后续恢复时。
- Spring应用:Spring中没有直接的备忘录模式实现,但可以通过缓存等机制保存和恢复状态。
- 观察者模式 (Observer Pattern)
- 原理:定义对象间一种一对多的依赖关系,以便当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动更新。
- 代码实例:
interface Observer { void update(String message); } class ConcreteObserver implements Observer { public void update(String message) { System.out.println("Received update: " + message); } } class Subject { private List<Observer> observers = new ArrayList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } public class ObserverPatternExample { public static void main(String[] args) { Subject subject = new Subject(); Observer observer1 = new ConcreteObserver(); Observer observer2 = new ConcreteObserver(); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers("State has changed!"); } }
- 使用场景:当一个对象状态变化需要通知多个其他对象时,例如消息通知系统。
- Spring应用:Spring中的事件机制就是观察者模式的应用。
- 状态模式 (State Pattern)
- 原理:允许一个对象在其内部状态发生改变时改变其行为,看起来就像改变了它的类。
- 代码实例:
interface State { void handle(); } class ConcreteStateA implements State { public void handle() { System.out.println("Handling state A"); } } class ConcreteStateB implements State { public void handle() { System.out.println("Handling state B"); } } class Context { private State state; public void setState(State state) { this.state = state; } public void request() { state.handle(); } } public class StatePatternExample { public static void main(String[] args) { Context context = new Context(); State stateA = new ConcreteStateA(); State stateB = new ConcreteStateB(); context.setState(stateA); context.request(); context.setState(stateB); context.request(); } }
- 使用场景:对象行为依赖于状态变化,例如游戏角色状态。
- Spring应用:Spring中的
StatefulRetryOperationsInterceptor
实现了状态模式。
- 策略模式 (Strategy Pattern)
- 原理:定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可以独立于使用它的客户而变化。
- 代码实例:
interface Strategy { void execute(); } class ConcreteStrategyA implements Strategy { public void execute() { System.out.println("Executing Strategy A"); } } class ConcreteStrategyB implements Strategy { public void execute() { System.out.println("Executing Strategy B"); } } class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.execute(); } } public class StrategyPatternExample { public static void main(String[] args) { Context context = new Context(new ConcreteStrategyA()); context.executeStrategy(); context = new Context(new ConcreteStrategyB()); context.executeStrategy(); } }
- 使用场景:需要动态选择算法的场景,例如支付方式的选择。
- Spring应用:
TransactionTemplate
使用不同的事务策略。
- 模板方法模式 (Template Method Pattern)
- 原理:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重定义算法的某些步骤。
- 代码实例:
abstract class AbstractClass { final void templateMethod() { primitiveOperation1(); primitiveOperation2(); } abstract void primitiveOperation1(); abstract void primitiveOperation2(); } class ConcreteClass extends AbstractClass { void primitiveOperation1() { System.out.println("Primitive Operation 1"); } void primitiveOperation2() { System.out.println("Primitive Operation 2"); } } public class TemplateMethodPatternExample { public static void main(String[] args) { AbstractClass concrete = new ConcreteClass(); concrete.templateMethod(); } }
- 使用场景:适用于多个子类有公共行为且逻辑相同时,例如实现通用的数据处理流程。
- Spring应用:
JdbcTemplate
和HttpServlet
中的doGet()
、doPost()
等方法都是模板方法模式的应用。
- 访问者模式 (Visitor Pattern)
- 原理:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
- 代码实例:
interface Visitor { void visit(Element element); } interface Element { void accept(Visitor visitor); } class ConcreteElementA implements Element { public void accept(Visitor visitor) { visitor.visit(this); } } class ConcreteVisitor implements Visitor { public void visit(Element element) { System.out.println("Visiting element"); } } public class VisitorPatternExample { public static void main(String[] args) { Element element = new ConcreteElementA(); Visitor visitor = new ConcreteVisitor(); element.accept(visitor); } }
- 使用场景:需要对对象结构中的元素进行操作且操作易变时。
- Spring应用:Spring的BeanPostProcessor可以视为访问者模式的应用。