Java之美[从菜鸟到高手演变]之设计模式

一、引言

(一)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设计模式,并将其应用到实际开发中,不断提升自己的编程能力和解决问题的能力。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@sinner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值