一、引言
(一)Java 设计模式的重要性
设计模式是软件工程中解决常见问题的最佳实践。它们提供了一种在特定情境下重用设计经验的方式,有助于提高代码的可维护性、可扩展性和可重用性。
(二)本系列博客的目的
本系列博客旨在帮助读者从基础到高级逐步掌握Java设计模式,通过理论与实践相结合的方式,使读者能够理解和应用这些设计模式,提升编程技能和解决复杂问题的能力。
二、设计模式简介
(一)设计模式的定义和分类
设计模式是在特定环境下,解决某一类重复出现的问题的通用解决方案。它们分为三类:创建型模式、结构型模式和行为型模式。
(二)常见的设计模式概述
- 创建型模式:涉及对象创建机制,试图以适当方式创建对象,隐藏创建逻辑,而不是直接实例化对象。
- 结构型模式:关注类和对象的组合,继承机制,用组合的方式来解决不同问题。
- 行为型模式:描述类或对象交互以及职责的分配。
三、从菜鸟到高手的演变
(一)菜鸟阶段:了解基本的设计原则
1. 单一职责原则:一个类应该只有一个引起它变化的原因。
2. 开放封闭原则:软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。
3. 里氏替换原则:子类型必须能够替换掉它们的基类型。
4. 依赖倒置原则:高层模块不应该依赖于低层模块,两者都应该依赖其抽象。
5. 接口隔离原则:客户端不应该依赖它不需要的接口。
6. 迪米特法则:一个对象应该对其他对象保持最少的了解。
(二)进阶阶段:掌握常见的设计模式
1. 创建型模式
创建型模式主要关注对象的创建机制,目的是为了更灵活地创建对象,提高系统的灵活性和可维护性。下面我将详细解释每种创建型模式,并给出Java代码示例。
- 单例模式(Singleton Pattern)
单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
Java代码示例:
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }}
- 工厂模式(Factory Pattern)
工厂模式定义一个用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
Java代码示例:
interface Product { void use();}class ConcreteProductA implements Product { public void use() { System.out.println("Using Product A"); }}class ConcreteProductB implements Product { public void use() { System.out.println("Using Product B"); }}class Factory { public Product createProduct(String type) { if (type.equals("A")) { return new ConcreteProductA(); } else if (type.equals("B")) { return new ConcreteProductB(); } return null; }}
- 抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
Java代码示例:
interface AbstractFactory { Product createProduct();}class ConcreteFactoryA implements AbstractFactory { public Product createProduct() { return new ConcreteProductA(); }}class ConcreteFactoryB implements AbstractFactory { public Product createProduct() { return new ConcreteProductB(); }}// UsageAbstractFactory factory = new ConcreteFactoryA();Product product = factory.createProduct();product.use();
- 建造者模式(Builder Pattern)
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
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("Product Parts: " + partA + ", " + partB); }}class Builder { public void buildPartA() {} public void buildPartB() {} public Product getResult() { return new Product(); }}class Director { public void construct(Builder builder) { builder.buildPartA(); builder.buildPartB(); }}
- 原型模式(Prototype Pattern)
原型模式用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
Java代码示例:
import java.util.ArrayList;import java.util.List;class Prototype implements Cloneable { private List<String> list; public Prototype() { this.list = new ArrayList<>(); } public void add(String item) { list.add(item); } public List<String> getList() { return list; } @Override public Prototype clone() { Prototype clone = new Prototype(); clone.list = new ArrayList<>(this.list); return clone; }}// UsagePrototype prototype = new Prototype();prototype.add("Item 1");Prototype clone = prototype.clone();clone.add("Item 2");System.out.println(prototype.getList()); // [Item 1]System.out.println(clone.getList()); // [Item 1, Item 2]
2. 结构型模式
- 适配器模式(Adapter Pattern)
适配器模式允许接口不兼容的类能够一起工作。它通过包装一个对象,使其表现出另一个对象的接口。
// 目标接口interface Target { void request();}// 需要适配的类class Adaptee { void specificRequest() { System.out.println("Adaptee's specific request"); }}// 适配器class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } public void request() { adaptee.specificRequest(); }}// 使用适配器public class AdapterExample { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target target = new Adapter(adaptee); target.request(); }}
- 桥接模式(Bridge Pattern)
桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。
// 实现接口interface Implementor { void operationImpl();}// 具体实现类class ConcreteImplementorA implements Implementor { public void operationImpl() { System.out.println("ConcreteImplementorA operation"); }}class ConcreteImplementorB implements Implementor { public void operationImpl() { System.out.println("ConcreteImplementorB operation"); }}// 抽象类abstract class Abstraction { protected Implementor implementor; public 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 BridgeExample { public static void main(String[] args) { Implementor implementorA = new ConcreteImplementorA(); Abstraction abstraction = new RefinedAbstraction(implementorA); abstraction.operation(); }}
- 组合模式(Composite Pattern)
组合模式允许你将对象组合成树形结构来表示“部分-整体”的层次结构。
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; } public void operation() { System.out.println("Leaf " + name + " operation"); }}// 组合class Composite implements Component { private List<Component> children = new ArrayList<>(); private String name; public Composite(String name) { this.name = name; } public void add(Component component) { children.add(component); } public void operation() { System.out.println("Composite " + name + " operation"); for (Component component : children) { component.operation(); } }}// 使用组合模式public class CompositeExample { public static void main(String[] args) { Component leaf1 = new Leaf("Leaf1"); Component leaf2 = new Leaf("Leaf2"); Composite composite = new Composite("Composite1"); composite.add(leaf1); composite.add(leaf2); composite.operation(); }}
- 装饰模式(Decorator Pattern)
装饰模式动态地给一个对象添加一些额外的职责。
// 组件接口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("Added behavior from ConcreteDecoratorA"); }}// 使用装饰模式public class DecoratorExample { public static void main(String[] args) { Component component = new ConcreteComponent(); component = new ConcreteDecoratorA(component); component.operation(); }}
- 外观模式(Facade Pattern)
外观模式为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
// 子系统类class SubSystemA { public void methodA() { System.out.println("SubSystemA methodA"); }}class SubSystemB { public void methodB() { System.out.println("SubSystemB methodB"); }}// 外观类class Facade { private SubSystemA systemA; private SubSystemB systemB; public Facade() { systemA = new SubSystemA(); systemB = new SubSystemB(); } public void method() { systemA.methodA(); systemB.methodB(); }}// 使用外观模式public class FacadeExample { public static void main(String[] args) { Facade facade = new Facade(); facade.method(); }}
- 享元模式(Flyweight Pattern)
享元模式运用共享技术有效地支持大量细粒度的对象。
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; } public void operation(String extrinsicState) { System.out.println("Intrinsic State = " + intrinsicState); System.out.println("Extrinsic State = " + extrinsicState); }}// 享元工厂class FlyweightFactory { private Map<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String key) { if (flyweights.containsKey(key)) { return flyweights.get(key); } else { Flyweight flyweight = new ConcreteFlyweight(key); flyweights.put(key, flyweight); return flyweight; } }}// 使用享元模式public class FlyweightExample { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweight = factory.getFlyweight("key1"); flyweight.operation("extrinsicState1"); }}
- 代理模式(Proxy Pattern)
代理模式为其他对象提供一种代理以控制对这个对象的访问。
// 主题接口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 ProxyExample { public static void main(String[] args) { Proxy proxy = new Proxy(); proxy.request(); }}
3. 行为型模式
下面我将详细解释每种设计模式,并给出Java代码示例。
- 责任链模式(Chain of Responsibility Pattern)
责任链模式允许你将请求沿着处理者链进行发送,直到有一个处理者处理它为止。
// 抽象处理者abstract class Handler { protected Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public abstract void handleRequest(int request);}// 具体处理者class ConcreteHandler1 extends Handler { public void handleRequest(int request) { if (request >= 0 && request < 10) { System.out.println("ConcreteHandler1 handled the request"); } else if (successor != null) { successor.handleRequest(request); } }}class ConcreteHandler2 extends Handler { public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println("ConcreteHandler2 handled the request"); } else if (successor != null) { successor.handleRequest(request); } }}
- 命令模式(Command Pattern)
命令模式将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。
// 命令接口interface Command { void execute();}// 具体命令class ConcreteCommand implements Command { private Receiver receiver; ConcreteCommand(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(); }}// 接收者class Receiver { public void action() { System.out.println("Receiver action"); }}// 调用者class Invoker { private Command command; public void setCommand(Command command) { this.command = command; } public void executeCommand() { command.execute(); }}
- 解释器模式(Interpreter Pattern)
解释器模式为语言创建解释器。
// 抽象表达式interface Expression { boolean interpret(String context);}// 终结符表达式class TerminalExpression implements Expression { private String data; public TerminalExpression(String data) { this.data = data; } public boolean interpret(String context) { return context.contains(data); }}// 非终结符表达式class OrExpression implements Expression { private Expression expr1; private Expression expr2; public OrExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } public boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context); }}
- 迭代器模式(Iterator Pattern)
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
import java.util.Iterator;// 集合接口interface Aggregate { Iterator createIterator();}// 具体集合class ConcreteAggregate implements Aggregate { private Object[] items; public ConcreteAggregate() { items = new Object[10]; // 初始化元素 } public Iterator createIterator() { return new ConcreteIterator(this); } // 获取元素数量 public int count() { return items.length; } // 获取特定位置的元素 public Object get(int index) { return items[index]; }}// 迭代器class ConcreteIterator implements Iterator { private ConcreteAggregate aggregate; private int current; public ConcreteIterator(ConcreteAggregate aggregate) { this.aggregate = aggregate; } public boolean hasNext() { return current < aggregate.count() && aggregate.get(current) != null; } public Object next() { return aggregate.get(current++); }}
- 中介者模式(Mediator Pattern)
中介者模式定义了一个封装一组对象如何交互的对象。
// 中介者接口interface Mediator { void send(String message, Colleague colleague);}// 具体中介者class ConcreteMediator implements Mediator { private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2; public void setColleague1(ConcreteColleague1 colleague1) { this.colleague1 = colleague1; } public void setColleague2(ConcreteColleague2 colleague2) { this.colleague2 = colleague2; } public void send(String message, Colleague colleague) { if (colleague == colleague1) { colleague2.notify(message); } else { colleague1.notify(message); } }}// 同事类abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } public abstract void send(String message); public abstract void notify(String message);}// 具体同事类class ConcreteColleague1 extends Colleague { public ConcreteColleague1(Mediator mediator) { super(mediator); } public void send(String message) { mediator.send(message, this); } public void notify(String message) { System.out.println("Colleague1 gets message: " + message); }}
- 备忘录模式(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 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<Memento>(); public void add(Memento state) { mementoList.add(state); } public Memento get(int index) { return mementoList.get(index); }}
- 观察者模式(Observer Pattern)
观察者模式定义了对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。
// 主题接口interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers();}// 具体主题class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyObservers(); } public void registerObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyObservers() { for (Observer observer : observers) { observer.update(); } }}// 观察者接口interface Observer { void update();}// 具体观察者class ConcreteObserver implements Observer { private ConcreteSubject subject; public ConcreteObserver(ConcreteSubject subject) { this.subject = subject; subject.registerObserver(this); } public void update() { System.out.println("Observer state updated: " + subject.getState()); }}
- 状态模式(State Pattern)
状态模式允许一个对象在其内部状态改变时改变它的行为。
// 状态接口interface State { void doAction(Context context);}// 具体状态class StartState implements State { public void doAction(Context context) { System.out.println("Player is in start state"); context.setState(this); } public String toString() { return "Start State"; }}class StopState implements State { public void doAction(Context context) { System.out.println("Player is in stop state"); context.setState(this); } public String toString() { return "Stop State"; }}// 上下文class Context { private State state; public Context() { state = null; } public void setState(State state) { this.state = state; } public State getState() { return state; }}
- 策略模式(Strategy Pattern)
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。
// 策略接口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 Context(Strategy strategy) { this.strategy = strategy; } public int executeStrategy(int num1, int num2) { return strategy.doOperation(num1, num2); }}
- 模板方法模式(Template Method Pattern)
模板方法模式定义了一个算法的骨架,而将一些步骤延迟到子类中。
// 抽象类abstract class Game { abstract void initialize(); abstract void startPlay(); abstract void endPlay(); // 模板方法 public final void play() { initialize(); startPlay(); endPlay(); }}// 具体类class Cricket extends Game { void initialize() { System.out.println("Cricket Game Initialized! Start playing."); } void startPlay() { System.out.println("Cricket Game Started. Enjoy the game!"); } void endPlay() { System.out.println("Cricket Game Finished!"); }}
- 访问者模式(Visitor Pattern)
它允许你在不修改已有代码的情况下定义新的操作。这种模式的基本思想是将数据结构和对数据结构的操作分离开来,使得对数据结构的操作可以独立于数据结构本身进行扩展和修改。
在访问者模式中,通常有两个主要的组成部分:
1. 访问者(Visitor):定义了对每个具体元素(ConcreteElement)需要执行的操作。
2. 元素(Element):定义了一个接受访问者的方法,通常命名为accept。
以下是访问者模式的主要参与者:
- Visitor:声明了一个访问者可以访问的元素类型的访问操作。
- ConcreteVisitor:实现了Visitor接口,定义了对元素的具体操作。
- Element:定义了一个接受访问者的方法。
- ConcreteElement:实现了Element接口,具体元素类。
- ObjectStructure:能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。
下面是一个简单的Java代码示例,演示了访问者模式的使用:
// 访问者接口interface Visitor { void visit(ConcreteElementA element); void visit(ConcreteElementB element);}// 具体访问者class ConcreteVisitor implements Visitor { @Override public void visit(ConcreteElementA element) { System.out.println("ConcreteVisitor is visiting " + element.getClass().getSimpleName()); } @Override public void visit(ConcreteElementB element) { System.out.println("ConcreteVisitor is visiting " + element.getClass().getSimpleName()); }}// 元素接口interface Element { void accept(Visitor visitor);}// 具体元素Aclass ConcreteElementA implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); }}// 具体元素Bclass ConcreteElementB implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); }}// 对象结构class ObjectStructure { private List<Element> elements = new ArrayList<>(); public void addElement(Element element) { elements.add(element); } public void accept(Visitor visitor) { for (Element element : elements) { element.accept(visitor); } }}// 使用访问者模式的客户端代码public class VisitorPatternDemo { public static void main(String[] args) { ObjectStructure objectStructure = new ObjectStructure(); objectStructure.addElement(new ConcreteElementA()); objectStructure.addElement(new ConcreteElementB()); Visitor visitor = new ConcreteVisitor(); objectStructure.accept(visitor); }}
在这个例子中,Visitor接口定义了访问者可以访问的元素类型,ConcreteVisitor实现了具体的访问操作。Element接口定义了接受访问者的方法,而ConcreteElementA和ConcreteElementB是具体的元素类。ObjectStructure类管理元素集合,并允许访问者访问这些元素。
客户端代码创建了一个ObjectStructure对象,添加了一些元素,并创建了一个ConcreteVisitor对象来访问这些元素。通过调用ObjectStructure的accept方法,访问者可以遍历并操作所有元素。
(三)高手阶段:灵活运用设计模式解决实际问题
1. 设计模式的组合使用:例如,使用工厂模式结合单例模式来管理资源。
2. 设计模式的优化和改进:根据实际项目需求,对现有设计模式进行优化,如改进单例模式的线程安全性。
3. 设计模式在项目中的应用案例分析:分析具体项目中如何应用设计模式,如使用观察者模式实现事件驱动系统。
四、总结
(一)设计模式的学习方法和建议
- 理论学习:理解每种设计模式的目的、结构和适用场景。
- 实践应用:通过编写代码来实践设计模式,加深理解。
- 案例分析:分析实际项目中设计模式的应用,学习如何解决实际问题。
(二)对读者的鼓励和期望
希望读者通过本系列博客的学习,能够掌握Java设计模式,并将其应用到实际开发中,不断提升自己的编程能力和解决问题的能力。