设计模式:观察者、享元、状态模式

1.观察者模式(Observer Pattern)

目的: 观察者模式是一种行为设计模式,它允许你定义一种订阅机制,当对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

结构

  • Subject(主题/被观察者):这是一个接口或抽象类,提供了添加、删除观察者对象的方法,同时还有一个通知所有观察者的方法。
  • ConcreteSubject(具体被观察者):实现了 Subject 接口,保存了一个观察者对象列表,并在状态发生变化时调用通知方法。
  • Observer(观察者):也是一个接口或抽象类,定义了一个更新方法,当被观察者调用此方法时,观察者可以执行相应的操作。
  • ConcreteObserver(具体观察者):实现了 Observer 接口,当收到 Subject 发出的通知时,会更新自身状态。

示例场景: 新闻订阅服务,当有新的新闻发布时,所有的订阅者(观察者)都会收到更新通知。

// Subject: 被观察者接口
import java.util.ArrayList;
import java.util.List;

interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// ConcreteSubject: 具体被观察者
class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<>();
    }

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

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

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this.temperature, this.humidity, this.pressure);
        }
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

// Observer: 观察者接口
interface Observer {
    void update(float temp, float humidity, float pressure);
}

// ConcreteObserver: 具体观察者
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " +
                           humidity + "% humidity");
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
        weatherData.registerObserver(currentDisplay);

        // 更新天气数据,触发通知
        weatherData.setMeasurements(80, 65, 30.4f);
    }
}

2.享元模式(Flyweight Pattern)

目的: 享元模式是一种结构型设计模式,用于减少应用程序中创建的相似对象的数量,以节约内存。它通过共享内部状态相同的对象来实现这一点。

结构

  • Flyweight(抽象享元):定义了对象的外部状态和内部状态的接口,共享的对象通过此接口访问和修改其内部状态。
  • ConcreteFlyweight(具体享元):实现了 Flyweight 接口,存储并共享内部状态,并提供了操作内部状态的方法。
  • UnsharedConcreteFlyweight(非共享具体享元):对于不可共享的部分,定义单独的类来处理。
  • FlyweightFactory(享元工厂):负责创建和管理享元对象,根据需要决定是否从已存在的享元对象池中取出对象,还是新建一个。

示例场景: 在图形渲染应用中,大量的像素点具有相同的颜色,而不是为每一个像素点都创建一个新的颜色对象,而是通过享元模式共享同一颜色对象。

// Flyweight: 抽象享元接口
interface Shape {
    void draw();
}

// ConcreteFlyweight: 具体享元类
class Circle implements Shape {
    private String color;
    private int x, y, radius;

    public Circle(int x, int y, int radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public void draw() {
        System.out.println("Drawing circle at (" + x + "," + y + ") with radius " + radius + " and color " + color);
    }
}

// FlyweightFactory: 享元工厂类
class ShapeFactory {
    private Map<String, Shape> circleCache = new HashMap<>();

    public Shape getCircle(int x, int y, int radius, String color) {
        String key = x + "," + y + "," + radius;
        if (!circleCache.containsKey(key)) {
            circleCache.put(key, new Circle(x, y, radius));
        }
        ((Circle) circleCache.get(key)).setColor(color);
        return circleCache.get(key);
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();

        Shape circle1 = factory.getCircle(0, 0, 5, "Red");
        Shape circle2 = factory.getCircle(0, 0, 5, "Blue"); // 享元复用,不会创建新的Circle对象

        circle1.draw();
        circle2.draw();
    }
}

3.状态模式(State Pattern)

目的: 状态模式是一种行为设计模式,允许对象在内部状态改变时改变其行为。对象看起来似乎改变了它的类,但实际上它是根据当前状态委托给相应状态对象来处理请求。

结构

  • Context(环境类):维护一个指向当前状态对象的引用,将与状态相关的操作委托给当前状态对象处理。
  • State(抽象状态):定义一个接口,声明与状态相关的行为,所有具体状态类都要实现这个接口。
  • ConcreteState(具体状态):实现 State 接口,定义与某个特定状态相关的行为。

示例场景: ATM机在不同状态下有不同的行为,如取款、查询余额、更改密码等。当插入银行卡后,ATM机会处于不同的状态,每种状态下响应的用户操作各不相同。

// Context: 环境类
class GumballMachine {
    private State soldOutState;
    private State noQuarterState;
    private State hasQuarterState;
    private State soldState;
    private State winnerState;

    private State state = soldOutState; // 初始状态为售罄状态

    public GumballMachine(int numberGumballs) {
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        winnerState = new WinnerState(this);

        insertQuarter(numberGumballs); // 初始化机器数量
    }

    public void insertQuarter() {
        state.insertQuarter();
    }

    public void ejectQuarter() {
        state.ejectQuarter();
    }

    public void turnCrank() {
        state.turnCrank();
        state.dispense();
    }

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

    // 其他用于状态切换的方法和状态相关的属性...
}

// State: 抽象状态接口
interface State {
    void insertQuarter();
    void ejectQuarter();
    void turnCrank();
    void dispense();
}

// ConcreteState: 具体状态类(仅展示其中一个)
class SoldOutState implements State {
    private GumballMachine gumballMachine;

    public SoldOutState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("You can't insert a quarter, the machine is sold out");
    }

    // 其他状态行为的实现...
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        GumballMachine gumballMachine = new GumballMachine(0); // 创建一台糖果机,初始糖果数为0
        gumballMachine.insertQuarter(); // 试图投币
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值