Operation Patterns中Template Method, State和Strategy的理解和分析

本文解析了模板方法、状态模式及策略模式的核心概念与应用场景。模板方法定义算法骨架并允许子类重定义步骤;状态模式使对象随内部状态变化而改变行为;策略模式则封装算法族并允许独立于客户端进行互换。

闲话不多说,先从Template Method开始。

对于Template Methods,官方(指GoF书中)的定义的是:"Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. "

简单用中文来说,就是将某个方法中的一些子操作(通过将子操作定义为虚函数的形式)保留,留待该方法所在类子类来实现。简单的示例图:

其中,PrimitiveOperation就是要留待子类实现的部分操作。这个设计模式看似没有很复杂的内容,但是有两点需要记住:

首先是如一本书中提到的"classes in a hierarchy share the outline of an algorithm in an abstract superclass",具体怎么应用要看理解,由于我的应用经验也不是很足,这里无法做出非常清晰的解释

还有一点是Template Method在 "to implenment similar algorithms in more than one method" 时也有很好的用法。这个用法的一个例子就是在与Factory Method结合的时候(这个应用有些类似基于Factory Method再应用一次多态,当然,这是笔者个人的理解)。具体可以去看《Design Pattern Java Workbook》,里面有不错的例子。

 

简单介绍完Template Method,接下来看一下State。如它的名字所说,这个模式与程序状态有关。GoF的定义为: "Allow an object to alter its behavior when its internal state changes. The object will appear to change its class".

在分析以前看一下图例:

我认为对State的理解有两个,一个是GoF提出State的时候的意思,即,使对象状态的改变可以动态改变其行为;还有一个是我们在实践中体会到的,即在某个对象状态变化十分复杂的时候,将其每个状态都封装成一个类,实现if-else的功能。

 

接下来是Strategy的一些理解。GoF的定义为: "Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.".  以笔者的观点看来,这个模式的主要作用是,对于程序提供的多个可能的策略,利用多态,这个模式可以动态的选择其中的某一策略。看一下图:

 

 

 图里面已经比较清楚,笔者将自己认为的几点说一下:

一是对于具体的策略(如ConcreteStrategyA),有时需要采用Singleton模式

二是在策略很多很复杂时,在具体的策略类(如ConcreteStrategyA)中,我们往往不直接将策略写在AlgorithmInterface里,而是应用Flyweitht模式,抽取某些可重用的部分。

 

以上是笔者对三个模式的一些理解,可以看到,三者的区别是明显的,但又不是完全不同(废话)。也许正确的使用全凭乎一个感觉,即经验。而通过对这三个模式的学习,笔者认为自己对多态有了更深入的理解,希望对看这片文章的人也有所帮助。

设计模式是软件开发中经过验证的最佳实践,用来解决常见的设计问题。Java 中常见的 **23 种设计模式** 可以分为三大类: - **创建型模式(Creational Patterns)**:处理对象的创建机制,隐藏对象创建的细节。 - **结构型模式(Structural Patterns)**:处理对象类的组合方式。 - **行为型模式(Behavioral Patterns)**:处理对象之间的通信职责分配。 下面我会依次详细讲解每种设计模式,给出 Java 示例代码,并说明其适用场景结构。 --- ## 一、创建型模式(Creational Patterns) ### 1. 工厂方法模式(Factory Method) **定义**:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。 ```java // 产品接口 interface Shape { void draw(); } // 具体产品 class Circle implements Shape { public void draw() { System.out.println("Circle.draw()"); } } class Square implements Shape { public void draw() { System.out.println("Square.draw()"); } } // 工厂接口 abstract class ShapeFactory { abstract Shape createShape(); } // 具体工厂 class CircleFactory extends ShapeFactory { public Shape createShape() { return new Circle(); } } class SquareFactory extends ShapeFactory { public Shape createShape() { return new Square(); } } // 客户端 public class Client { public static void main(String[] args) { ShapeFactory factory = new CircleFactory(); Shape shape = factory.createShape(); shape.draw(); } } ``` **适用场景**:需要将对象的创建逻辑与使用逻辑解耦,允许子类决定实例化哪个类。 --- ### 2. 抽象工厂模式(Abstract Factory) **定义**:提供一个接口,用于创建一组相关或依赖对象的家族,而无需指定具体类。 ```java interface GUIFactory { Button createButton(); Checkbox createCheckbox(); } class WinFactory implements GUIFactory { public Button createButton() { return new WinButton(); } public Checkbox createCheckbox() { return new WinCheckbox(); } } class MacFactory implements GUIFactory { public Button createButton() { return new MacButton(); } public Checkbox createCheckbox() { return new MacCheckbox(); } } interface Button { void paint(); } interface Checkbox { void paint(); } class WinButton implements Button { public void paint() { System.out.println("WinButton"); } } class MacButton implements Button { public void paint() { System.out.println("MacButton"); } } class WinCheckbox implements Checkbox { public void paint() { System.out.println("WinCheckbox"); } } class MacCheckbox implements Checkbox { public void paint() { System.out.println("MacCheckbox"); } } // 客户端 public class Application { private Button button; private Checkbox checkbox; public Application(GUIFactory factory) { this.button = factory.createButton(); this.checkbox = factory.createCheckbox(); } public void render() { button.paint(); checkbox.paint(); } public static void main(String[] args) { GUIFactory factory = new WinFactory(); Application app = new Application(factory); app.render(); } } ``` **适用场景**:需要创建一组相互关联或依赖的对象族,而不需要依赖于具体类。 --- ### 3. 建造者模式(Builder) **定义**:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 ```java class Product { private String partA; private String partB; private String partC; public void setPartA(String a) { partA = a; } public void setPartB(String b) { partB = b; } public void setPartC(String c) { partC = c; } public void show() { System.out.println(partA + " " + partB + " " + partC); } } interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); Product getResult(); } class ConcreteBuilder implements Builder { private Product product = new Product(); public void buildPartA() { product.setPartA("PartA"); } public void buildPartB() { product.setPartB("PartB"); } public void buildPartC() { product.setPartC("PartC"); } public Product getResult() { return product; } } class Director { public void construct(Builder builder) { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); } } // 客户端 public class Client { public static void main(String[] args) { Builder builder = new ConcreteBuilder(); Director director = new Director(); director.construct(builder); Product product = builder.getResult(); product.show(); } } ``` **适用场景**:当对象的构造过程复杂且需要分步骤进行时。 --- ### 4. 单例模式(Singleton) **定义**:确保一个类只有一个实例,并提供一个全局访问点。 ```java class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } ``` **适用场景**:日志记录器、数据库连接池、配置管理等需要全局唯一实例的地方。 --- ### 5. 原型模式(Prototype) **定义**:通过克隆已有对象来创建新对象,而不是通过实例化。 ```java interface Prototype { Prototype clone(); } class ConcretePrototype implements Prototype { private String name; public ConcretePrototype(String name) { this.name = name; } public Prototype clone() { return new ConcretePrototype(this.name); } public String toString() { return "ConcretePrototype{name='" + name + "'}"; } } // 客户端 public class Client { public static void main(String[] args) { ConcretePrototype p1 = new ConcretePrototype("原型"); ConcretePrototype p2 = (ConcretePrototype) p1.clone(); System.out.println(p2); } } ``` **适用场景**:对象创建成本高,或需要基于已有对象进行修改时。 --- ## 二、结构型模式(Structural Patterns) ### 6. 适配器模式(Adapter) **定义**:将一个类的接口转换成客户期望的另一个接口。 ```java class Adaptee { public void specificRequest() { System.out.println("Adaptee.specificRequest()"); } } interface Target { void request(); } class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } public void request() { adaptee.specificRequest(); } } // 客户端 public class Client { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target target = new Adapter(adaptee); target.request(); } } ``` **适用场景**:整合不兼容接口、遗留代码集成。 --- ### 7. 桥接模式(Bridge) **定义**:将抽象部分与其实现部分分离,使它们可以独立变化。 ```java interface Implementor { void operationImpl(); } class ConcreteImplementorA implements Implementor { public void operationImpl() { System.out.println("ConcreteImplementorA.operationImpl()"); } } abstract class Abstraction { protected Implementor implementor; protected Abstraction(Implementor implementor) { this.implementor = implementor; } abstract void operation(); } class RefinedAbstraction extends Abstraction { public RefinedAbstraction(Implementor implementor) { super(implementor); } public void operation() { implementor.operationImpl(); } } // 客户端 public class Client { public static void main(String[] args) { Implementor impl = new ConcreteImplementorA(); Abstraction abs = new RefinedAbstraction(impl); abs.operation(); } } ``` **适用场景**:避免类爆炸问题,如多个维度的组合。 --- ### 8. 组合模式(Composite) **定义**:将对象组合成树形结构以表示“部分-整体”的层次结构。 ```java import java.util.*; abstract class Component { protected String name; public Component(String name) { this.name = name; } public abstract void add(Component c); public abstract void remove(Component c); public abstract void display(int depth); } class Leaf extends Component { public Leaf(String name) { super(name); } public void add(Component c) { System.out.println("Cannot add to a leaf"); } public void remove(Component c) { System.out.println("Cannot remove from a leaf"); } public void display(int depth) { System.out.println("-".repeat(depth) + name); } } class Composite extends Component { private List<Component> children = new ArrayList<>(); public Composite(String name) { super(name); } public void add(Component c) { children.add(c); } public void remove(Component c) { children.remove(c); } public void display(int depth) { System.out.println("-".repeat(depth) + name); for (Component child : children) { child.display(depth + 2); } } } // 客户端 public class Client { public static void main(String[] args) { Component root = new Composite("root"); root.add(new Leaf("Leaf A")); root.add(new Leaf("Leaf B")); Component subComp = new Composite("SubComposite"); subComp.add(new Leaf("Leaf C")); subComp.add(new Leaf("Leaf D")); root.add(subComp); root.display(1); } } ``` **适用场景**:表示文件系统、UI组件树等树形结构。 --- ### 9. 装饰器模式(Decorator) **定义**:动态地给对象添加职责,比继承更灵活。 ```java interface Component { void operation(); } class ConcreteComponent implements Component { public void operation() { System.out.println("ConcreteComponent.operation()"); } } abstract class Decorator implements Component { protected Component component; public Decorator(Component component) { this.component = component; } public void operation() { component.operation(); } } class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } public void operation() { super.operation(); addedBehavior(); } private void addedBehavior() { System.out.println("ConcreteDecoratorA.addedBehavior()"); } } // 客户端 public class Client { public static void main(String[] args) { Component component = new ConcreteComponent(); Component decorated = new ConcreteDecoratorA(component); decorated.operation(); } } ``` **适用场景**:Java IO 流、权限增强、日志包装等。 --- ### 10. 代理模式(Proxy) **定义**:为其他对象提供一种代理以控制对这个对象的访问。 ```java interface Subject { void request(); } class RealSubject implements Subject { public void request() { System.out.println("RealSubject.request()"); } } class Proxy implements Subject { private RealSubject realSubject; public void request() { if (realSubject == null) { realSubject = new RealSubject(); } preRequest(); realSubject.request(); postRequest(); } private void preRequest() { System.out.println("Proxy.preRequest()"); } private void postRequest() { System.out.println("Proxy.postRequest()"); } } // 客户端 public class Client { public static void main(String[] args) { Subject proxy = new Proxy(); proxy.request(); } } ``` **适用场景**:远程调用、延迟加载、权限控制、日志记录等。 --- ### 11. 享元模式(Flyweight) **定义**:共享对象以减少内存使用。 ```java class Flyweight { private String intrinsicState; public Flyweight(String state) { this.intrinsicState = state; } public void operation(String extrinsicState) { System.out.println("Intrinsic: " + intrinsicState + ", Extrinsic: " + 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 Client { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight f1 = factory.getFlyweight("A"); Flyweight f2 = factory.getFlyweight("B"); Flyweight f3 = factory.getFlyweight("A"); f1.operation("X"); f2.operation("Y"); f3.operation("Z"); } } ``` **适用场景**:大量细粒度对象,如字符、图形、线程池等。 --- ### 12. 外观模式(Facade) **定义**:为子系统中的一组接口提供一个统一的入口。 ```java class SubsystemA { void operationA() { System.out.println("SubsystemA.operationA()"); } } class SubsystemB { void operationB() { System.out.println("SubsystemB.operationB()"); } } class Facade { private SubsystemA a = new SubsystemA(); private SubsystemB b = new SubsystemB(); void operation() { a.operationA(); b.operationB(); } } // 客户端 public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.operation(); } } ``` **适用场景**:简化复杂系统的使用,提供统一接口。 --- ### 13. 适配器模式(Adapter) - 对象适配器 (略,已讲) --- ## 三、行为型模式(Behavioral Patterns) (由于篇幅限制,这里只展示部分行为型模式,如需完整版请继续提问) --- ### 14. 观察者模式(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; } public void update(String message) { System.out.println(name + " received: " + message); } } class Subject { private List<Observer> observers = new ArrayList<>(); public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notify(String message) { for (Observer observer : observers) { observer.update(message); } } } // 客户端 public class Client { public static void main(String[] args) { Subject subject = new Subject(); Observer o1 = new ConcreteObserver("A"); Observer o2 = new ConcreteObserver("B"); subject.attach(o1); subject.attach(o2); subject.notify("Hello Observers"); } } ``` **适用场景**:事件监听机制、MVC 模式中 View 与 Model 的通信。 --- ### 15. 策略模式(Strategy) **定义**:定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换。 ```java interface Strategy { int doOperation(int num1, int num2); } class OperationAdd implements Strategy { public int doOperation(int num1, int num2) { return num1 + num2; } } class OperationSubtract implements Strategy { public int doOperation(int num1, int num2) { return num1 - num2; } } class Context { private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy = strategy; } public int executeStrategy(int num1, int num2) { return strategy.doOperation(num1, num2); } } // 客户端 public class Client { public static void main(String[] args) { Context context = new Context(); context.setStrategy(new OperationAdd()); System.out.println("Add: " + context.executeStrategy(10, 5)); context.setStrategy(new OperationSubtract()); System.out.println("Subtract: " + context.executeStrategy(10, 5)); } } ``` **适用场景**:支付方式、排序算法、策略切换等。 --- ### 16. 模板方法模式(Template Method) **定义**:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。 ```java abstract class AbstractClass { final void templateMethod() { primitiveOperation1(); primitiveOperation2(); } abstract void primitiveOperation1(); abstract void primitiveOperation2(); } class ConcreteClass extends AbstractClass { void primitiveOperation1() { System.out.println("ConcreteClass.primitiveOperation1()"); } void primitiveOperation2() { System.out.println("ConcreteClass.primitiveOperation2()"); } } // 客户端 public class Client { public static void main(String[] args) { AbstractClass obj = new ConcreteClass(); obj.templateMethod(); } } ``` **适用场景**:JUnit 测试框架、算法流程控制。 --- ### 17. 命令模式(Command) **定义**:将请求封装为对象,从而使你可用不同的请求对客户进行参数化。 ```java interface Command { void execute(); } class Receiver { void action() { System.out.println("Receiver.action()"); } } class ConcreteCommand implements Command { private Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(); } } class Invoker { private Command command; public void setCommand(Command command) { this.command = command; } public void executeCommand() { command.execute(); } } // 客户端 public class Client { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(); invoker.setCommand(command); invoker.executeCommand(); } } ``` **适用场景**:事务回滚、命令队列、操作日志。 --- ### 18. 责任链模式(Chain of Responsibility) **定义**:使多个对象都有机会处理请求,从而避免请求的发送者接收者之间的耦合。 ```java abstract class Handler { protected Handler next; public void setNext(Handler next) { this.next = next; } public abstract void handleRequest(int request); } class ConcreteHandlerA extends Handler { public void handleRequest(int request) { if (request >= 0 && request < 10) { System.out.println("HandlerA handled request " + request); } else if (next != null) { next.handleRequest(request); } } } class ConcreteHandlerB extends Handler { public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println("HandlerB handled request " + request); } else if (next != null) { next.handleRequest(request); } } } // 客户端 public class Client { public static void main(String[] args) { Handler h1 = new ConcreteHandlerA(); Handler h2 = new ConcreteHandlerB(); h1.setNext(h2); h1.handleRequest(5); h1.handleRequest(15); } } ``` **适用场景**:审批流程、异常处理链、过滤器链等。 --- ### 19. 迭代器模式(Iterator) **定义**:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。 ```java import java.util.*; interface Iterator { boolean hasNext(); Object next(); } interface Aggregate { Iterator createIterator(); } class ConcreteAggregate implements Aggregate { private List<String> items = new ArrayList<>(); public void addItem(String item) { items.add(item); } public Iterator createIterator() { return new ConcreteIterator(); } private class ConcreteIterator implements Iterator { private int index = 0; public boolean hasNext() { return index < items.size(); } public Object next() { return items.get(index++); } } } // 客户端 public class Client { public static void main(String[] args) { ConcreteAggregate aggregate = new ConcreteAggregate(); aggregate.addItem("Item 1"); aggregate.addItem("Item 2"); aggregate.addItem("Item 3"); Iterator iterator = aggregate.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } } ``` **适用场景**:集合遍历、自定义容器类的迭代。 --- ### 20. 中介者模式(Mediator) **定义**:用一个中介对象来封装一系列对象之间的交互。 ```java interface Mediator { void send(String message, Colleague colleague); } class ConcreteMediator implements Mediator { private Colleague colleagueA; private Colleague colleagueB; public void setColleagueA(Colleague colleagueA) { this.colleagueA = colleagueA; } public void setColleagueB(Colleague colleagueB) { this.colleagueB = colleagueB; } public void send(String message, Colleague colleague) { if (colleague == colleagueA) { colleagueB.receive(message); } else { colleagueA.receive(message); } } } abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } abstract void receive(String message); abstract void send(String message); } class ConcreteColleagueA extends Colleague { public ConcreteColleagueA(Mediator mediator) { super(mediator); } public void receive(String message) { System.out.println("ColleagueA received: " + message); } public void send(String message) { mediator.send(message, this); } } class ConcreteColleagueB extends Colleague { public ConcreteColleagueB(Mediator mediator) { super(mediator); } public void receive(String message) { System.out.println("ColleagueB received: " + message); } public void send(String message) { mediator.send(message, this); } } // 客户端 public class Client { 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.send("Hello from A"); colleagueB.send("Hi from B"); } } ``` **适用场景**:对象之间复杂交互、解耦。 --- ### 21. 备忘录模式(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 getStateFromMemento(Memento memento) { state = memento.getState(); } } class CareTaker { private List<Memento> mementoList = new ArrayList<>(); public void add(Memento state) { mementoList.add(state); } public Memento get(int index) { return mementoList.get(index); } } // 客户端 public class Client { public static void main(String[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); originator.setState("State #1"); originator.setState("State #2"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #3"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #4"); System.out.println("Current State: " + originator.getState()); originator.getStateFromMemento(careTaker.get(0)); System.out.println("First saved State: " + originator.getState()); } } ``` **适用场景**:撤销/恢复、状态保存。 --- ### 22. 解释器模式(Interpreter) **定义**:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 (略,常用于编译器、DSL 解析) --- ### 23. 状态模式(State) **定义**:允许对象在其内部状态改变时改变它的行为。 ```java interface State { void handle(); } class ConcreteStateA implements State { public void handle() { System.out.println("State A handled"); } } class ConcreteStateB implements State { public void handle() { System.out.println("State B handled"); } } class Context { private State state; public void setState(State state) { this.state = state; } public void request() { state.handle(); } } // 客户端 public class Client { public static void main(String[] args) { Context context = new Context(); context.setState(new ConcreteStateA()); context.request(); context.setState(new ConcreteStateB()); context.request(); } } ``` **适用场景**:工作流、订单状态切换、状态机等。 --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值