我学会了,观察者模式

简介: 观察者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。

前言

观察者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。

观察者模式

使用场景:常见的观察者模式的使用就是发布订阅,比如拍卖商品,还有过节抢火车票、飞机票、电影票之类的。这种模式比较常见,当目标对象有变化了,关注这个目标的其它人也会迅速做出相应的反应。

理解:这是一种类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,这种方式有点花,但非常实用,当目标发生变化,其它关注目标的其它人就会做出相关反应。这个代码例子似乎结合了电影院买票和拍卖竞拍,原理一致,比如你用手机APP买票,如果别人选了你想要的票,那么你就不能再选这个票了,然后你就只能选其它的票。观察者需要关注这个目标,而这个目标也需要把观察者添加到候选名单中,这样目标和观察者就能相互调用,它们之间的调用是基于行为上的交互,也都封装到内部的方法中,所以能很好的将类、对象的行为和使用解耦了。

namespace action_mode_01 {

    // 票
    class Ticket {

        id: string
        position: string
        state: boolean
        user: string = ''
        price: number

        constructor(id: string, position: string) {
            this.id = id;
            this.position = position;
            this.price = ~~ (Math.random() * 1000)
            this.state = false;
        }

        // 买票,返回是否购买成功的状态
        buy() {
            if (this.isBuy()) {
                return false
            }

            this.state = true
            return this.state
        }

        isBuy() {
            return this.state
        }

    }

    // 目标:电影院卖票
    class Cinema {

        ticketBuyerList: Array<TicketBuyer> = []

        ticketList: Array<Ticket> = []

        addTicketBuyer(ticketBuyer: TicketBuyer) {
            this.ticketBuyerList.push(ticketBuyer)
        }

        constructor() {
            // 初始化十张电影票
            for (let i = 0; i < 10; i++) {
                const id = String(~~ (1000000000 * Math.random()));
                const position = String(i)
                const ticket = new Ticket(id, position)
                this.ticketList.push(ticket)
            }
        }

        startSell () {
            this.ticketBuyerList.forEach(item => {
                item.buyTicket(~~ (Math.random() * 1000))
            });

            const tempList = this.ticketList.filter(item => item.isBuy())
            if (tempList.length === this.ticketList.length) {
                console.log('======================================');
                console.log('============⭐⭐⭐⭐⭐⭐===========');
                console.log('本场电影票已卖完,买票成功的人员名单如下:');
                console.log('============⭐⭐⭐⭐⭐⭐===========');
                console.log('======================================');
                tempList.forEach(item => {
                    console.log(`票号:${item.id} 位置:${item.position} 买主是:${item.user}`)
                })

                return true
            }

            return false
        }

        sellTicket (ticketBuyer: TicketBuyer, money: number) {
            ticketBuyer.isBuy = false
            this.ticketList.forEach(item => {
                // 价格低或者本轮已经买过了
                if (money >= item.price && !ticketBuyer.isBuy) {
                    const result = item.buy()
                    // 购买成功
                    if (result) {
                        ticketBuyer.isBuy = true
                        ticketBuyer.mytickets.push(item)
                        item.user = ticketBuyer.name
                        console.log(item.user + ' 买票成功! 票号是:' + item.id + ' 位置是:' + item.position)
                    } else {
                        // 购买失败
                        console.log('票号:' + item.id + ' 位置:' + item.position + ',买主:' + item.user + ' 买票失败! ')
                    }
                }
            })
        }

    }

    // 观察者:买票黄牛
    class TicketBuyer {

        name: string
        cinema: Cinema
        isBuy: boolean = false
        mytickets: Array<Ticket> = [] 
        

        constructor (cinema: Cinema, name: string) {
            this.cinema = cinema
            this.name = name
            // this.cinema.addTicketBuyer(this) // 也可以在这里添加让目标把观察者添加进去
        }

        // 买票
        buyTicket ( money: number) {
            this.cinema.sellTicket(this,  money)
        }
    }

    // 使用
    const cinema = new Cinema()
    for (let i = 0; i < 99; i++) {
        const t = new TicketBuyer(cinema, '黄牛'+i+'号')
        cinema.addTicketBuyer(t)
    }

    let result = cinema.startSell()
    while(!result) {
        result = cinema.startSell()
    }
}
目录
相关文章
|
5天前
|
设计模式 监控 C#
观察者模式
观察者模式是一种行为型设计模式,用于定义对象间的一对多依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新。该模式主要用于实现发布-订阅机制。核心角色包括主题(Subject)、观察者(Observer)、具体主题(Concrete Subject)和具体观察者(Concrete Observer)。优点包括低耦合、动态添加观察者和自动更新,但也有可能引起过多更新、不适合同步通知和可能造成内存泄漏等缺点。适用于气象站数据更新、股票价格监控和用户界面组件更新等场景。
19 4
|
7月前
|
C++
【C++】—— 观察者模式
【C++】—— 观察者模式
|
7月前
|
设计模式 JavaScript 开发者
详细讲解什么是观察者模式
详细讲解什么是观察者模式
|
关系型数据库 API
观察者模式解读
观察者模式解读
|
7月前
|
设计模式 Java
【观察者模式】 ——每天一点小知识
【观察者模式】 ——每天一点小知识
5 # 观察者模式
5 # 观察者模式
38 0
|
XML 设计模式 Java
观察者模式(下)
观察者模式(下)
66 0
|
设计模式
观察者模式(上)
观察者模式(上)
87 0
|
存储
深入剖析观察者模式
深入剖析观察者模式
155 0
|
设计模式 Go 开发者
观察者模式的实际应用
遇到一个用观察者模式解决问题的场景,和大家一起分享