【软件工程】23种设计模式原理java实现

文章目录


前言

设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的高内聚和低耦合。

在这里插入图片描述

23中设计模式的关系

在这里插入图片描述


创建型模式

一、工厂方法模式(Factory Method Pattern)

1、定义原理

定义一个用户创建对象的接口,但由子类决定实例化哪个类。

2、适用场景

当一个类无法准确预知需要创建的对象的确切类时,将对象的创建延迟到子类。

3、经典应用例子

> 这里是引用

4、类图

在这里插入图片描述

5、java代码实现

// 抽象产品
interface Product {
    void operation();
}

// 具体产品
class ConcreteProduct implements Product {
    @Override
    public void operation() {
        System.out.println("具体产品的操作");
    }
}

// 抽象工厂
interface Factory {
    Product createProduct();
}

// 具体工厂
class ConcreteFactory implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProduct();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Factory factory = new ConcreteFactory();
        Product product = factory.createProduct();
        product.operation();
    }
}

二、抽象工厂模式(Abstract Factory Pattern)

1、定义原理

提供一个创建相关或依赖接口的接口,而无需指定具体类。

2、适用场景

当需要创建一些列相互关联或依赖的对象时,且不希望暴露它们的具体实现细节。
在这里插入图片描述

3、经典应用例子

角色
1、抽象工厂(Creator)

是抽象工厂方法模式的核心角色,任何在模式中创建的对象的工厂类必须实现这此产品族接口;

2、具体工厂(Concrete Creator)

这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象;

3、抽象产品(Product)

所要创建的对象的基类,也就是产品对象的共同父类或共同拥有的接口;

4、具体产品(Concrete Product)
在这里插入图片描述

4、类图

在这里插入图片描述

5、java代码实现

// 抽象产品族
interface AbstractProductA {
    void operationA();
}

// 具体产品族
class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void operationA() {
        System.out.println("具体产品A1的操作");
    }
}

// 具体产品族
class ConcreteProductA2 implements AbstractProductA {
    @Override
    public void operationA() {
        System.out.println("具体产品A2的操作");
    }
}

// 抽象产品族
interface AbstractProductB {
    void operationB();
}

// 具体产品族
class ConcreteProductB1 implements AbstractProductB {
    @Override
    public void operationB() {
        System.out.println("具体产品B1的操作");
    }
}

// 具体产品族
class ConcreteProductB2 implements AbstractProductB {
    @Override
    public void operationB() {
        System.out.println("具体产品B2的操作");
    }
}

// 抽象工厂
interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// 具体工厂
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.operationA();
        productB1.operationB();

        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.operationA();
        productB2.operationB();
    }
}

三、单例模式(Singleton Pattern)

1、定义原理

确保一个类只有一个实例,并提供对该例的全局访问点。

2、适用场景

当需要确保一个类只有一个实例,并且需要全局访问该实例时。

3、经典应用例子

在这里插入图片描述

4、类图

在这里插入图片描述

5、java代码实现

class Singleton {
    private static Singleton instance;

    private Singleton() {
        // 私有构造函数
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public void operation() {
        System.out.println("单例对象的操作");
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        singleton.operation();
    }
}

四、建造者模式(Builder Pattern)

1、定义原理

将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

2、适用场景

当需要创建复杂对象,并且希望通过一步一步的方式构建对象。

3、经典应用例子

计算机是由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。

特点

建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

4、类图

在这里插入图片描述

5、java代码实现

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 operation() {
        System.out.println("产品的操作");
    }
}

interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
    Product getResult();
}

class ConcreteBuilder implements Builder {
    private Product product;

    public ConcreteBuilder() {
        this.product = new Product();
    }

    @Override
    public void buildPartA() {
        product.setPartA("部件A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("部件B");
    }

    @Override
    public void buildPartC() {
        product.setPartC("部件C");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

class Director {
    public void construct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director();
        director.construct(builder);
        Product product = builder.getResult();
        product.operation();
    }
}

五、原型模式(Prototype Pattern)

1、定义原理

用原型实例指定创建对象的种类,并且通过复制这个原型来创建新的对象。

2、适用场景

当需要创建多个相似的对象,并且创建过程比较复杂或耗时时,可以使用原型模式。

3、经典应用例子

一个图形绘制软件可以使用原型模式,通过复制已有的图形对象来创建新的图形对象,而无需重新创建和实例化对象。

4、类图

在这里插入图片描述

5、java代码实现

import java.util.HashMap;
import java.util.Map;

// 抽象原型类
abstract class Shape implements Cloneable {
    protected String type;

    public abstract void draw();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 具体原型类
class Circle extends Shape {
    public Circle() {
        type = "Circle";
    }

    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle extends Shape {
    public Rectangle() {
        type = "Rectangle";
    }

    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

// 原型管理器
class ShapeCache {
    private static Map<String, Shape> shapeMap = new HashMap<>();

    public static Shape getShape(String type) {
        Shape shape = shapeMap.get(type);
        return (Shape) shape.clone();
    }

    public static void loadCache() {
        Circle circle = new Circle();
        shapeMap.put(circle.type, circle);

        Rectangle rectangle = new Rectangle();
        shapeMap.put(rectangle.type, rectangle);
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        ShapeCache.loadCache();

        Shape clonedShape1 = ShapeCache.getShape("Circle");
        clonedShape1.draw();

        Shape clonedShape2 = ShapeCache.getShape("Rectangle");
        clonedShape2.draw();
    }
}

结构型模式

六、适配器模式(Adapter Pattern)

1、定义原理

将一个类的接口转换成客户希望的另一个接口,使得原本不兼容的类可以一起工作。

2、适用场景

当需要将一个类的接口转换成另一个类的接口时,可以使用适配器模式。

3、经典应用例子

一个手机充电器可以使用适配器模式,将电源插头的接口转换成手机充电接口的接口,使得不同类型的电源可以连通给手机充电。

4、类图

在这里插入图片描述

5、java代码实现

// 目标接口
interface Target {
    void request();
}

// 需要适配的类
class Adaptee {
    public void specificRequest() {
        System.out.println("适配者类的特殊请求");
    }
}

// 适配器类
class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();
    }
}

七、桥接模式(Bridge Pattern)

1、定义原理

将抽象部分与它的实现部分分离,使他们可以独立地变化。

2、适用场景

当需要将抽象部分与实现部分分离,使他们可以独立地变化,可以使用桥接模式。

3、经典应用例子

一个电视机可以使用桥接模式,将遥控器的抽象部分与电视机的实现部分分离,使他们可以独立地进行扩展。

4、类图

在这里插入图片描述

5、java代码实现

// 实现部分的接口
interface Implementor {
    void operationImpl();
}

// 具体实现部分A
class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("具体实现部分A的操作");
    }
}

// 具体实现部分B
class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("具体实现部分B的操作");
    }
}

// 抽象部分的接口
abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

// 扩展抽象部分的实现A
class RefinedAbstractionA extends Abstraction {
    public RefinedAbstractionA(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        implementor.operationImpl();
        System.out.println("扩展抽象部分A的操作");
    }
}

// 扩展抽象部分的实现B
class RefinedAbstractionB extends Abstraction {
    public RefinedAbstractionB(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        implementor.operationImpl();
        System.out.println("扩展抽象部分B的操作");
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Implementor implementorA = new ConcreteImplementorA();
        Abstraction abstractionA = new RefinedAbstractionA(implementorA);
        abstractionA.operation();

        Implementor implementorB = new ConcreteImplementorB();
        Abstraction abstractionB = new RefinedAbstractionB(implementorB);
        abstractionB.operation();
    }
}

八、组合模式(Composite Pattern)

1、定义原理

将对象组合成树形结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

2、适用场景

当需要表示对象的层次结构,并且希望用户可以一致地对待单个对象和组合对象时,可以使用组合模式。

3、经典应用例子

一个文件系统可以使用组合模式,将文件和文件夹组合成树状结构,使得用户可以一致地对待文件和文件夹。

4、类图

在这里插入图片描述

5、java代码实现

// 抽象构件
interface Component {
    void operation();
}

// 叶子构件
class Leaf implements Component {
    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("叶子构件" + name + "的操作");
    }
}

// 容器构件
class Composite implements Component {
    private List<Component> components = new ArrayList<>();

    public void add(Component component) {
        components.add(component);
    }

    public void remove(Component component) {
        components.remove(component);
    }

    @Override
    public void operation() {
        for (Component component : components) {
            component.operation();
        }
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Component leaf1 = new Leaf("Leaf 1");
        Component leaf2 = new Leaf("Leaf 2");

        Component composite1 = new Composite();
        composite1.add(leaf1);
        composite1.add(leaf2);

        Component leaf3 = new Leaf("Leaf 3");
        Component leaf4 = new Leaf("Leaf 4");

        Component composite2 = new Composite();
        composite2.add(leaf3);
        composite2.add(leaf4);

        Component composite3 = new Composite();
        composite3.add(composite1);
        composite3.add(composite2);

        composite3.operation();
    }
}

九、装饰器模式(DecoratorPattern)

1、定义原理

动态地给一个对象添加一些额外的职责,即在不改变其结构的情况下,对对象进行扩展。

2、适用场景

当需要动态地给一个对象添加功能,并且希望这些功能可以动态组合时,可以使用装饰器模式。

3、经典应用例子

一个咖啡店可以使用装饰器模式,将咖啡对象进行装饰,添加额外的配料(如牛奶、糖等)。

4、类图

在这里插入图片描述

5、java代码实现

// 抽象组件
interface Component {
    void operation();
}

// 具体组件
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("具体组件的操作");
    }
}

// 抽象装饰器
abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

// 具体装饰器A
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        System.out.println("具体装饰器A的操作");
    }
}

// 具体装饰器B
class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        System.out.println("具体装饰器B的操作");
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decoratorA = new ConcreteDecoratorA(component);
        Component decoratorB = new ConcreteDecoratorB(decoratorA);
        decoratorB.operation();
    }
}

十、外观模式(Facade Pattern)

1、定义原理

提供了一个统一的接口,用于访问子系统中的一群接口,从而简化了客户端与子系统之间的交互。

2、适用场景

当需要简化复杂子系统的接口,并提供一个统一的接口给客户端使用时,可以使用外观模式。

3、经典应用例子

一个家庭影院系统可以使用外观模式,将各种设备(如投影仪、音响、DVD播放器等)的复杂操作封装在一个外观类中,提供一个简单的接口给用户操作整个家庭影院系统。

4、类图

在这里插入图片描述

5、java代码实现

// 子系统类A
class SubsystemA {
    public void operationA() {
        System.out.println("子系统A的操作");
    }
}

// 子系统类B
class SubsystemB {
    public void operationB() {
        System.out.println("子系统B的操作");
    }
}

// 外观类
class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;

    public Facade() {
        this.subsystemA = new SubsystemA();
        this.subsystemB = new SubsystemB();
    }

    public void operation() {
        subsystemA.operationA();
        subsystemB.operationB();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operation();
    }
}

十一、享元模式(FlyWeight Pattern)

1、定义原理

运用共享技术有效地支持大量细粒度的对象。

2、适用场景

当需要创建大量相似对象,并且这些对象可以共享一些公共的状态时,可以使用享元模式。

3、经典应用例子

享元模式(Flyweight Pattern)又称为轻量级模式,是对象池的一种实现.类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能.提供了减少对象数量从而改善应用所需的对象结构的方式.其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,从此来降低内存的消耗,属于结构型模式.

4、类图

在这里插入图片描述

5、java代码实现

// 抽象享元类
interface Flyweight {
    void operation();
}

// 具体享元类
class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation() {
        System.out.println("具体享元类的操作,内部状态为:" + intrinsicState);
    }
}

// 享元工厂类
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 Main {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("key1");
        flyweight1.operation();

        Flyweight flyweight2 = factory.getFlyweight("key2");
        flyweight2.operation();

        Flyweight flyweight3 = factory.getFlyweight("key1");
        flyweight3.operation();
    }
}

十二、代理模式(Proxy Pattern)

1、定义原理

为其他对象提供一种代理以控制对这个对象的访问。

2、适用场景

当需要控制对一个对象的访问,并且希望通过代理来实现对原始对象的访问时,可以使用代理模式。

3、经典应用例子

一个网络代理服务器可以使用代理模式,代理服务器充当客户端和目标服务器之间的中间人,控制对目标服务器的访问。

4、类图

在这里插入图片描述

5、java代码实现

// 抽象主题
interface Subject {
    void request();
}

// 真实主题
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("真实主题的请求");
    }
}

// 代理类
class Proxy implements Subject {
    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        // 在调用真实主题之前可以执行一些操作
        System.out.println("代理类的请求");
        realSubject.request();
        // 在调用真实主题之后可以执行一些操作
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Proxy proxy = new Proxy(realSubject);
        proxy.request();
    }
}

行为型模式

十三、模板方法模式(Temolete Method Pattern)

1、定义原理

定义一个操作中的算法框架,将一些步骤延迟到子类中实现。

2、适用场景

当有一系列算法步骤,其中一些步骤的实现可能不同,但整体框架是固定的时,可以使用模板方法模式。

3、经典应用例子

假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 (PDF、 DOC 或 CSV) 的文档, 程序则会试图从这些文件中抽取有意义的数据, 并以统一的格式将其返回给用户。

该程序的首个版本仅支持 DOC 文件。 在接下来的一个版本中, 程序能够支持 CSV 文件。 一个月后, 你 “教会” 了程序从 PDF 文件中抽取数据。
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

4、类图

在这里插入图片描述

5、java代码实现

abstract class AbstractClass {
    public void templateMethod() {
        step1();
        step2();
        step3();
    }

    protected abstract void step1();
    protected abstract void step2();
    protected abstract void step3();
}

class ConcreteClass extends AbstractClass {
    @Override
    protected void step1() {
        System.out.println("ConcreteClass step1");
    }

    @Override
    protected void step2() {
        System.out.println("ConcreteClass step2");
    }

    @Override
    protected void step3() {
        System.out.println("ConcreteClass step3");
    }
}

public class Main {
    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass();
        abstractClass.templateMethod();
    }
}

十四、命令模式(Command Pattern)

1、定义原理

将请求封装成一个对象,从而可以用不同的请求对客户进行参数化。

2、适用场景

当需要将请求发送者和接受者解耦,并且希望以队列方式执行请求时,可以使用命令模式。

3、经典应用例子

假设有一个遥控器,这个遥控器可以控制各种家电设备,比如电视机、音响、灯光等等。每个家电设备都有自己的开关命令,而遥控器上的按钮就代表不同的命令对象。这样一来,用户只需要按下相应的按钮,就可以控制不同的家电设备,而无需关心具体的实现细节。

4、类图

在这里插入图片描述

5、java代码实现

interface Command {
    void execute();
}

class Receiver {
    public void action() {
        System.out.println("Receiver action");
    }
}

class ConcreteCommand implements Command {
    private Receiver receiver;

    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    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 Main {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        invoker.executeCommand();
    }
}

十五、迭代器模式(Iterator Pattern)

1、定义原理

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。

2、适用场景

当需要遍历一个聚合对象的元素,并且不希望暴露其内部表示时,可以使用迭代器模式。

3、经典应用例子

简单来说,迭代器模式使得你能够获取到序列中的所有元素而不用关心是其类型是array,list,linked list或者是其他什么序列结构。这一点使得能够非常高效的构建数据处理通道(data pipeline)–即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是Linq的核心模式。

4、类图

在这里插入图片描述

5、java代码实现

interface Iterator {
    boolean hasNext();
    Object next();
}

interface Aggregate {
    Iterator createIterator();
}

class ConcreteIterator implements Iterator {
    private Object[] elements;
    private int position = 0;

    public ConcreteIterator(Object[] elements) {
        this.elements = elements;
    }

    @Override
    public boolean hasNext() {
        return position < elements.length;
    }

    @Override
    public Object next() {
        return elements[position++];
    }
}

class ConcreteAggregate implements Aggregate {
    private Object[] elements;

    public ConcreteAggregate(Object[] elements) {
        this.elements = elements;
    }

    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(elements);
    }
}

public class Main {
    public static void main(String[] args) {
        Object[] elements = { "Element 1", "Element 2", "Element 3" };
        Aggregate aggregate = new ConcreteAggregate(elements);
        Iterator iterator = aggregate.createIterator();

        while (iterator.hasNext()) {
            Object element = iterator.next();
            System.out.println(element);
        }
    }
}

十六、观察者模式(Observer Pattern)

1、定义原理

定义了一种1对多的依赖关系,使得当一个对象的状态发生变化时,其所有依赖对象都会收到通知并自动更新。

2、适用场景

当一个对象的状态发生变化时,需要通知其他对象,并且对象之间的关系是一对多关系时,可以使用观察者模式。

3、经典应用例子

一个新闻发布系统可以使用观察者模式,当有新闻发布时,订阅了该类新闻的观察者都会收到通知。

4、类图

在这里插入图片描述

5、java代码实现

import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

// 具体主题
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }

    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }
}

// 观察者接口
interface Observer {
    void update(String state);
}

// 具体观察者
class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String state) {
        System.out.println(name + " received state update: " + state);
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        subject.attach(observer1);
        subject.attach(observer2);

        subject.setState("State 1");
        subject.setState("State 2");

        subject.detach(observer2);

        subject.setState("State 3");
    }
}

十七、中介者模式(Mediator Pattern)

1、定义原理

通过封装一系列对象之间的交互,使这些对象不需要显示地相互引用,从而使其耦合度降低。

2、适用场景

当一组对象之间存在复杂的相互关系,并且需要通过一个中介来协调时,可以使用中介者模式。

3、经典应用例子

一个聊天室可以使用中介者模式,将聊天室中的用户对象解耦,通过中介者进行消息的传递和处理。

4、类图

在这里插入图片描述

5、java代码实现

interface Mediator {
    void sendMessage(String message, User user);
}

class ConcreteMediator implements Mediator {
    private List<User> users = new ArrayList<>();

    public void addUser(User user) {
        users.add(user);
    }

    @Override
    public void sendMessage(String message, User sender) {
        for (User user : users) {
            if (user != sender) {
                user.receiveMessage(message);
            }
        }
    }
}

class User {
    private String name;
    private Mediator mediator;

    public User(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }

    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    public void receiveMessage(String message) {
        System.out.println(name + " received message: " + message);
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Mediator mediator = new ConcreteMediator();

        User user1 = new User("User 1", mediator);
        User user2 = new User("User 2", mediator);
        User user3 = new User("User 3", mediator);

        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);

        user1.sendMessage("Hello, everyone!");
    }
}

十八、备忘录模式(Memento Pattern)

1、定义原理

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后可以恢复原先的状态。

2、适用场景

当需要保存和恢复对象的状态时,使用备忘录模式。

3、经典应用例子

一个文本编辑器可以使用备忘录模式,通过保存文本编辑器的状态(如光标位置、文本内容等),以便之后可以恢复到之前的状态。

4、类图

在这里插入图片描述

5、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 Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento memento) {
        state = memento.getState();
    }

    public void showState() {
        System.out.println("Current state: " + state);
    }
}

class Caretaker {
    private Memento memento;

    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();

        originator.setState("State 1");
        originator.showState();

        caretaker.setMemento(originator.createMemento());

        originator.setState("State 2");
        originator.showState();

        originator.restoreMemento(caretaker.getMemento());
        originator.showState();
    }
}

十九、解释器模式(Interapter Pattern)

1、定义原理

给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器来解释语言中的句子。

2、适用场景

当需要解释和执行一种语言的语法时,可以使用解释器模式。

3、经典应用例子

一个数学表达式解析器可以使用解释器模式,将数学表达式的字符串解析成可以计算的表达式。

4、类图

在这里插入图片描述

5、java代码实现

interface Expression {
    int interpret();
}

class NumberExpression implements Expression {
    private int number;

    public NumberExpression(int number) {
        this.number = number;
    }

    @Override
    public int interpret() {
        return number;
    }
}

class AddExpression implements Expression {
    private Expression left;
    private Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

class SubtractExpression implements Expression {
    private Expression left;
    private Expression right;

    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Expression expression = new SubtractExpression(
            new AddExpression(new NumberExpression(10), new NumberExpression(5)),
            new NumberExpression(2)
        );

        int result = expression.interpret();
        System.out.println("Result: " + result);
    }
}

二十、状态模式(State Pattern)

1、定义原理

允许一个对象在其内部状态改变时修改其行为,对象看起来似乎修改了它的类。

2、适用场景

当一个对象的行为取决于其内部状态,并且需要在其运行时根据内部状态改变其行为时,可以使用状态模式。

3、经典应用例子

一个订单状态管理系统可以使用状态模式,根据订单的不同状态(如待支付、已支付、已发货等),订单对象的行为会有所不同。

4、类图

在这里插入图片描述

5、java代码实现

interface State {
    void handle();
}

class ConcreteStateA implements State {
    @Override
    public void handle() {
        System.out.println("处理状态A的逻辑");
    }
}

class ConcreteStateB implements State {
    @Override
    public void handle() {
        System.out.println("处理状态B的逻辑");
    }
}

class Context {
    private State state;

    public void setState(State state) {
        this.state = state;
    }

    public void request() {
        state.handle();
    }
}

// 示例用法
public class Main {
    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();
    }
}

二十一、访问者模式(Visitor Pattern)

1、定义原理

表示一个作用于某对象结构中的各元素的操作,使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

2、适用场景

当需要对一个对象中的各个元素进行不同的操作,并且希望在不改变元素类的情况下增加新的操作时,可以使用访问者模式。

3、经典应用例子

一个图形绘制软件可以使用访问者模式,通过访问者对象对不同类型的图形元素进行不同的操作,如计算面积、计算轮廓等。

4、类图

在这里插入图片描述

5、java代码实现

// 抽象元素
interface Element {
    void accept(Visitor visitor);
}

// 具体元素A
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationA() {
        System.out.println("具体元素A的操作");
    }
}

// 具体元素B
class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationB() {
        System.out.println("具体元素B的操作");
    }
}

// 抽象访问者
interface Visitor {
    void visit(ConcreteElementA elementA);
    void visit(ConcreteElementB elementB);
}

// 具体访问者
class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ConcreteElementA elementA) {
        elementA.operationA();
    }

    @Override
    public void visit(ConcreteElementB elementB) {
        elementB.operationB();
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Element elementA = new ConcreteElementA();
        Element elementB = new ConcreteElementB();

        Visitor visitor = new ConcreteVisitor();

        elementA.accept(visitor);
        elementB.accept(visitor);
    }
}

二十二、策略模式(Strategy Pattern)

1、定义原理

定义一系列算法,将每个算法封装起来,并使他们可以互换。

2、适用场景

当需要再运行时根据不同的情况选择不同的算法时,可以使用策略模式。

3、经典应用例子

一个支付系统可以使用策略模式,根据用户的支付方式(如支付宝、微信支付等),使用不同的支付策略进行支付。

4、类图

在这里插入图片描述

5、java代码实现

interface PaymentStrategy {
    void pay(double amount);
}

class AlipayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + "元");
    }
}

class WechatPayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount + "元");
    }
}

class PaymentContext {
    private PaymentStrategy strategy;

    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void pay(double amount) {
        strategy.pay(amount);
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext();
        PaymentStrategy alipayStrategy = new AlipayStrategy();
        PaymentStrategy wechatPayStrategy = new WechatPayStrategy();

        context.setStrategy(alipayStrategy);
        context.pay(100.0);

        context.setStrategy(wechatPayStrategy);
        context.pay(200.0);
    }
}

二十三、责任链模式(Chain of Responsibility Pattern)

1、定义原理

将请求的发送者和接受者解耦,使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

2、适用场景

当有多个对象可以处理一个请求,并且希望请求的发送者和接受者解耦时,可以使用责任链模式。

3、经典应用例子

一个审批流程可以使用责任链模式,将多个审批人组成一条链,依次处理审批请求,直到有一个人员处理为止。

4、类图

在这里插入图片描述

5、java代码实现

abstract class Approver {
    protected Approver nextApprover;

    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    public abstract void approve(int amount);
}

class Manager extends Approver {
    @Override
    public void approve(int amount) {
        if (amount <= 1000) {
            System.out.println("Manager approved");
        } else if (nextApprover != null) {
            nextApprover.approve(amount);
        }
    }
}

class Director extends Approver {
    @Override
    public void approve(int amount) {
        if (amount <= 5000) {
            System.out.println("Director approved");
        } else if (nextApprover != null) {
            nextApprover.approve(amount);
        }
    }
}

class CEO extends Approver {
    @Override
    public void approve(int amount) {
        if (amount <= 10000) {
            System.out.println("CEO approved");
        } else {
            System.out.println("Amount too large, approval denied");
        }
    }
}

// 示例用法
public class Main {
    public static void main(String[] args) {
        Approver manager = new Manager();
        Approver director = new Director();
        Approver ceo = new CEO();

        manager.setNextApprover(director);
        director.setNextApprover(ceo);

        manager.approve(500);
        manager.approve(5000);
        manager.approve(15000);
    }
}

总结

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值