一、引言
(一)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();
}
}
// Usage
AbstractFactory 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;
}
}
// Usage
Prototype 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);
}
// 具体元素A
class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 具体元素B
class 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设计模式,并将其应用到实际开发中,不断提升自己的编程能力和解决问题的能力。