aiyoudiao aiyoudiao
  • JavaScript
  • Vue
  • React
  • 低代码
  • 线性系统
  • 暂未分类
  • LeetCode
  • 算法
  • 数据结构
  • 设计模式
  • Other
  • PMP
  • Office
  • 面试
  • Bash
  • 流年往事
  • 经验片段
  • 读书杂感
  • 归档
  • 分类
  • 标签
  • 简介
  • 收藏
  • 有趣
  • 文档

码二

扫微信二维码,认识一下码二吧😉。
  • JavaScript
  • Vue
  • React
  • 低代码
  • 线性系统
  • 暂未分类
  • LeetCode
  • 算法
  • 数据结构
  • 设计模式
  • Other
  • PMP
  • Office
  • 面试
  • Bash
  • 流年往事
  • 经验片段
  • 读书杂感
  • 归档
  • 分类
  • 标签
  • 简介
  • 收藏
  • 有趣
  • 文档
  • LeetCode

  • 算法

  • 数据结构

  • 设计模式

    • 浅聊设计理念
    • 谈一谈设计原则
    • 工厂方法模式
    • 抽象工厂模式
    • 建造者模式
    • 原型模式
    • 单例模式
    • 桥接模式
    • 代理模式
    • 装饰器模式
    • 适配器模式
    • 享元模式
    • 组合模式
    • 外观模式
    • 观察者模式
      • 前言
      • 观察者模式
    • 模板方法模式
    • 策略模式
    • 职责链模式
    • 状态模式
    • 迭代器模式
    • 访问者模式
    • 备忘录模式
    • 命令模式
    • 解释器模式
    • 中介者模式
  • Other

  • vue3设计与实现

  • 算法与设计
  • 设计模式
aiyoudiao
2022-02-23

观察者模式

# 前言

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

# 观察者模式

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

理解:这是一种类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,这种方式有点花,但非常实用,当目标发生变化,其它关注目标的其它人就会做出相关反应。这个代码例子似乎结合了电影院买票和拍卖竞拍,原理一致,比如你用手机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()
    }
}

#设计模式
上次更新时间: 10年18月2023日 01时57分53秒
外观模式
模板方法模式

← 外观模式 模板方法模式 →

最近更新
01
01.数据结构导论一览.md
10-16
02
30.2023年06月04日.md
06-04
03
08.与测量相关.md
05-06
更多文章>
Theme by Vdoing | Copyright © 2017-2023 aiyoudiao 码二 备案号: 鄂ICP备2022002654号-1