运用设计模式设计一个票务系统(观察者模式使用)

195 阅读2分钟

观察者模式在票务系统的使用

不懂观察者模式的小伙伴可以先去我之前写的看看【设计模式】行为型模式其七: 观察者模式 - 掘金 (juejin.cn),这里写的代码注释不会很多。

票务系统为什么使用观察者模式

我们在票务系统中,经常会有买票的操作并且生成订单,我们在买票的时候需要将购买的票的状态置为已售出,防止多次卖票。

为此,我打算在生成订单时添加一个逻辑,改变票的状态为已售出。

为此,我设计代码如下

具体代码

观察者接口

public interface TicketObserver {
    void update(int ticketId);
}

具体观察者

update里面具体实现需要完成的操作,这里是将票的状态置为已售完,你还可以添加其它的方法,比如将总票数减一。

因为在springboot项目中,所以需要使用依赖注入
@Component
public class TicketSoldObserver implements TicketObserver {
    @Resource
    private SysTicketMapper mapper;

    // 具体的观察者,负责更新status的状态
    public void update(int ticketId) {
        SysTicket ticket = mapper.selectById(ticketId);
        ticket.setIsSale(1);
        mapper.updateById(ticket);
    }
}

目标类

// 本来应该写为抽象类(这样的话有更好的扩展性),为了简单这里就直接使用基本类了。 // 该类需要有几个基本方法,比如移除观察者, 添加观察者, 通知观察者和自己特别的方法(这里的特别方法为setStatus)

public class TicketStatus {
    private List<TicketObserver> observers = new ArrayList<>();
    private int ticketId;

    public void addObserver(TicketObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(TicketObserver observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (TicketObserver observer : observers) {
            observer.update(this.ticketId);
        }
    }

    public void setStatus(int ticketId) {
        this.ticketId = ticketId;
        notifyObservers();
    }
}

具体业务类

上面三个类已经完成了组成了基本的观察者模式,现在我需要调用它们。

我们业务调用一般写service层。

首先,我们需要进行依赖注入,让spring能找到该观察者与具体目标对象。

注意: 我这里只注入了一个观察者对象。

@Resource
private TicketStatus ticketStatus;
@Resource
private TicketSoldObserver ticketSoldObserver;

然后调用方法为先注册观察者,当订单创建时再通知观察者进行 观察者的方法调用。

// 注册观察者
ticketStatus.addObserver(ticketSoldObserver);
// 修改票的状态为已售出
ticketStatus.setStatus(ticketId);

上面即是我在票务系统中的使用。


当然,观察者模式不止这些使用场景。

我举几个例子

  • 删除订单,将票的状态置为未售出
  • 当某一张票被订购了, 通知其它还在订票的人:票已售完