设计模式-建造者&观察者&抽象工厂&状态

发布于:2025-09-11 ⋅ 阅读:(19) ⋅ 点赞:(0)

设计模式概述 - 建造者 & 观察者 & 抽象工厂 & 状态

建造者模式简述

建造者模式(Builder Pattern)是一种创建型设计模式,它通过使用多个简单的对象一步步构建一个复杂的对象。建造者模式允许用户使用相同的构建过程创建不同的表示,适用于需要创建复杂对象的场景。

角色

  • 产品(Product):表示被构建的复杂对象。
  • 建造者接口(Builder):定义创建产品的各个部分的接口。
  • 具体建造者(ConcreteBuilder):实现建造者接口,构建并返回产品的实例。
  • 指挥者(Director):负责管理建造过程,调用建造者的方法。

优点

  • 分离复杂对象的构建与表示:建造者模式将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
  • 提高代码可读性:通过使用建造者模式,代码的结构更加清晰,易于理解和维护。
  • 灵活性:可以通过不同的建造者创建不同的产品。

缺点

  • 增加复杂性:引入建造者模式可能会导致类的数量增加,从而增加系统的复杂性。
  • 不适合简单对象:对于简单对象的创建,使用建造者模式可能显得过于复杂。

示例代码

// 产品类
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;
    }

    @Override
    public String toString() {
        return "Product{" +
                "partA='" + partA + '\'' +
                ", partB='" + partB + '\'' +
                ", partC='" + partC + '\'' +
                '}';
    }
}

// 建造者接口
interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
    Product getResult();
}

// 具体建造者
class ConcreteBuilder implements Builder {
    private Product product = new Product();

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

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

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

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

// 指挥者
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

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

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        director.construct();
        
        Product product = builder.getResult();
        System.out.println(product);
    }
}

观察者模式简述

观察者模式(Observer Pattern)是一种行为型设计模式,定义了一种一对多的依赖关系,使得当一个对象(主题)状态发生变化时,所有依赖于它的对象(观察者)都会得到通知并自动更新。该模式常用于实现事件处理系统。

角色

  • 主题(Subject):被观察的对象,维护观察者的列表并提供注册和注销观察者的方法。
  • 观察者(Observer):对主题的变化作出反应的对象,通常定义一个更新方法。
  • 具体主题(ConcreteSubject):实现主题接口,维护状态并通知观察者。
  • 具体观察者(ConcreteObserver):实现观察者接口,更新自身状态以反映主题的变化。

优点

  • 松耦合:观察者与主题之间的关系是松耦合的,观察者不需要知道主题的具体实现。
  • 动态关系:可以在运行时动态添加或移除观察者,灵活性高。
  • 促进广播通信:主题可以一次性通知所有观察者,简化了通信过程。

缺点

  • 可能导致过多通知:如果观察者数量较多,可能会导致性能问题,因为每次状态变化都需要通知所有观察者。
  • 观察者依赖:如果观察者未能正确处理更新,可能导致系统的不一致性。
  • 复杂性增加:在某些情况下,观察者模式可能导致系统的复杂性增加,特别是在观察者和主题之间的关系较为复杂时。

示例代码

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

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

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

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

    public String getState() {
        return 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);
        }
    }
}

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

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

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

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

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

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

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

抽象工厂模式简述

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式适用于需要创建多个相关对象的场景,能够提高代码的灵活性和可扩展性。(可以使用反射+配置文件的形式优化if判断)

角色

  • 抽象工厂(AbstractFactory):定义创建抽象产品的方法。
  • 具体工厂(ConcreteFactory):实现抽象工厂,创建具体的产品对象。
  • 抽象产品(AbstractProduct):定义产品的接口。
  • 具体产品(ConcreteProduct):实现抽象产品,定义具体的产品。

优点

  • 封装性:抽象工厂模式将具体类的实例化过程封装起来,客户端只需依赖于抽象接口。
  • 易于扩展:增加新产品时,只需新增具体工厂和具体产品,原有代码无需修改,符合开放-封闭原则。
  • 一致性:确保产品的一致性,避免产品之间不兼容的问题。

缺点

  • 类的数量增加:每增加一种产品系列,就需要增加相应的具体工厂和具体产品类,可能导致类的数量激增。
  • 复杂性:在某些情况下,使用抽象工厂模式可能会使系统变得复杂,尤其是在产品族较多时。

示例代码

// 抽象产品A
interface ProductA {
    void use();
}

// 具体产品A1
class ConcreteProductA1 implements ProductA {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductA1");
    }
}

// 具体产品A2
class ConcreteProductA2 implements ProductA {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductA2");
    }
}

// 抽象产品B
interface ProductB {
    void use();
}

// 具体产品B1
class ConcreteProductB1 implements ProductB {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductB1");
    }
}

// 具体产品B2
class ConcreteProductB2 implements ProductB {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductB2");
    }
}

// 抽象工厂
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

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

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

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

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

// 客户端代码
public class Client {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.use();
        productB1.use();

        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.use();
        productB2.use();
    }
}

状态模式简述

状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。状态模式将状态的相关行为封装在独立的状态类中,使得对象的行为随着状态的改变而改变,从而避免使用大量的条件语句

角色

  • 上下文(Context):维护一个对具体状态对象的引用,并定义客户端可以使用的接口。
  • 状态接口(State):定义一个接口,用于封装与上下文的一个特定状态相关的行为。
  • 具体状态(ConcreteState):实现状态接口,定义与上下文的一个特定状态相关的行为。

优点

  • 简化代码:通过将状态相关的行为封装在状态类中,减少了条件语句的使用,从而简化了代码。
  • 易于扩展:新状态的添加不需要修改现有代码,只需新增具体状态类,符合开放-封闭原则。
  • 状态独立:每个状态都可以独立变化,状态之间的逻辑清晰,易于理解。

缺点

  • 类的数量增加:每个状态都需要一个具体状态类,可能导致类的数量增加,增加系统复杂性。
  • 状态切换复杂:在某些情况下,状态之间的切换逻辑可能会变得复杂,尤其是状态依赖关系较多时。

示例代码

// 状态接口
interface State {
    void handle(Context context);
}

// 具体状态A
class ConcreteStateA implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling request in State A.");
        context.setState(new ConcreteStateB()); // 切换到状态B
    }
}

// 具体状态B
class ConcreteStateB implements State {
    @Override
    public void handle(Context context) {
        System.out.println("Handling request in State B.");
        context.setState(new ConcreteStateA()); // 切换到状态A
    }
}

// 上下文
class Context {
    private State state;

    public Context(State state) {
        this.state = state;
    }

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

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

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Context context = new Context(new ConcreteStateA());
        
        context.request(); // 处理请求并切换到状态B
        context.request(); // 处理请求并切换回状态A
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到