我学会了,享元模式

简介: 享元模式属于结构型模式,这个类型的设计模式总结出了 类、对象组合后的经典结构,将类、对象的结构和使用解耦了,花式的去借用对象。

前言

享元模式属于结构型模式,这个类型的设计模式总结出了 类、对象组合后的经典结构,将类、对象的结构和使用解耦了,花式的去借用对象。

享元模式

使用场景:当需要复用大量的对象,这大量的对象几乎都差不多,频繁的去创建导致性能开销暴涨,这时候可以将这些对象存起来,之后需要用的时候,直接从缓存中去拿,用完再初始化一下状态,最后再放入容器中。这样就可以频繁的使用了,比如服务器端的线程池、连接池,它们都是享元模式的具体体现。

理解:类、对象的结构和使用解耦,享元模式以内存来换取时间,减少了重复的对象创建开辟内存的操作。享元模式的使用需要根据应用场景,如果根本不需要使用享元模式而强行去使用它,就会造成多余的性能开销了,就像你开店,本来开的是个小饭馆,你却请了一个大酒店那么多的员工,那可不就太浪费了。

namespace struct_mode_05 {

    // 接口
    interface IServer {

        recruit(worker: Worker): IServer
        work(guest: Guest): IServer

    }

    // 顾客:操作对象
    class Guest {
        name: string
        isAccept: boolean = false

        constructor(name: string) {
            this.name = name
        }
    }

    // 工人:元素
    class Worker {

        name: string
        isWorker: boolean = false

        constructor(name: string) {
            this.name = name
        }

        work(guest: string) {
            console.log(`${this.name}正在服务${guest}`)
        }
    }

    // 餐厅:享元工厂
    class DiningRoom implements IServer {

        workerList: Array<Worker> = []

        recruit(worker: Worker): IServer {
            this.workerList.push(worker)
            return this
        }

        work(guest: Guest): IServer {

            const obj = this.workerList.find(item => !item.isWorker)

            if (obj) {

                obj.isWorker = true
                guest.isAccept = true

                obj.work(guest.name)

                setTimeout(() => {
                    obj.isWorker = false
                }, 3000 * Math.random())
            } else {
                console.log('已没有工人可以提供服务,客户' + guest.name + ' 请稍等。。。 ')

                setTimeout(() => {
                    this.work(guest)
                }, 3000 * Math.random())
            }

            return this
        }
    }

    // 使用

    // 餐厅招人
    const diningRoom = new DiningRoom()
    Array(12).fill(true).forEach((item, itemIndex) => {
        diningRoom.recruit(new Worker('工人' + itemIndex))
    });

    // 客人扎堆
    const guestList = Array(30).fill(true).map((item, itemIndex) => {
        return new Guest('客人' + itemIndex)
    }).sort(() => Math.random() - 0.5)

    // 一堆客人进入餐厅接受服务
    guestList.forEach(guest => {
        diningRoom.work(guest)
    })

    // 轮询判断所有客户是否已经全部接受服务
    let acceptId = setInterval(() => {
        const acceptGuest = guestList.filter(guest => guest.isAccept)

        if (acceptGuest.length === guestList.length) {
            console.log('所有顾客接受服务完毕!!!!!')
            clearInterval(acceptId)
        }
    }, 1000)

}
目录
相关文章
|
Java 数据库连接 Go
如何在Spring Boot应用中使用Nacos实现动态更新数据源
如何在Spring Boot应用中使用Nacos实现动态更新数据源
979 0
|
JavaScript
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
553 0
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
|
XML 编解码 自然语言处理
不需要熟悉,但需要了解的libiconv库
但是很多老式的计算机还在使用当地的传统的字符编码方式。而一些程序,例如邮件程序和浏览器必须能在这些不同的用户编码之间作转换。其他的一些程序则内置支持Unicode,以顺利支持国际化的处理,但是仍然有在Unicode和其他的传统编码之间转换的需求。GNU的libiconv就是为这两种应用设计的编码转换库。
不需要熟悉,但需要了解的libiconv库
|
12月前
|
Java 应用服务中间件 Spring
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
263 4
|
10月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的binlog日志文件
MySQL的binlog日志记录了所有对数据库的更改操作(不包括SELECT和SHOW),主要用于主从复制和数据恢复。binlog有三种模式,可通过设置binlog_format参数选择。示例展示了如何启用binlog、设置格式、查看日志文件及记录的信息。
798 6
|
11月前
|
Docker 容器
docker的导入本地镜像和导出本地镜像
本文介绍了如何使用Docker对本地镜像进行导入和导出操作,包括从本地导入`nginx.tar`镜像以及将`open-webui`镜像导出并压缩为`open-webui.tar.gz`。
1245 1
|
异构计算
CCF推荐B类会议和期刊总结:(计算机体系结构/并行与分布计算/存储系统领域)
中国计算机学会(CCF)定期发布国际学术会议和期刊目录,为科研人员提供参考。本文总结了计算机体系结构、并行与分布计算、存储系统领域的CCF推荐B类会议和期刊,包括会议和期刊的全称、出版社、dblp文献网址及领域分类。会议涵盖了SoCC、SPAA、PODC等26项重要国际会议,期刊则包括TAAS、TODAES、TECS等9种权威期刊,为相关领域的研究者提供了宝贵的资源。
CCF推荐B类会议和期刊总结:(计算机体系结构/并行与分布计算/存储系统领域)
|
小程序 开发者
【微信小程序】-- 分包 - 独立分包 & 分包预下载(四十五)
【微信小程序】-- 分包 - 独立分包 & 分包预下载(四十五)
15225 0
|
SQL 关系型数据库 数据库
RDS PostgreSQL索引推荐原理及最佳实践
前言很多开发人员都知道索引对于数据库的查询性能至关重要,一个好的索引能使数据库的性能提升成千上万倍。但给数据库加索引是一项相对专业的工作,需要对数据库的运行原理有一定了解。同时,加了索引有没有性能提升、性能提升了多少,这些都是加索引前就想知道的。这项繁杂的工作有没有更好的方案呢?有!就是今天重磅推出...
278 1
RDS PostgreSQL索引推荐原理及最佳实践
无头单链表
无头单链表
86 0