当前位置: 首页 > news >正文

设计模式之享元模式(Flyweight Pattern)【结构性模式】

在这里插入图片描述

为什么用结构性模式?

  • 结构性模式关注点“怎样组合对象/类?”所以我们关注下类的组合关系
  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的(继承)
  • 对象结构型模式关心类与对象的组合,通过关联关系在一个类中定义另一个类的实例对象(组合)
  • 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式
  1. 适配器模式(Adapter Pattern):两个不兼容接口之间适配的桥梁。
  2. 桥接模式(Bridge Pattern):相同功能抽象化与实现化解耦,抽象与实现可以独立升级。
  3. 过滤器模式(Filter、Criteria Pattern):使用不同的标准来过滤一组对象。
  4. 组合模式(Composite Pattern):相似对象进行组合,形成树形结构。
  5. 装饰器模式(Decorator Pattern):向一个现有的对象添加新的功能,同时又不改变其结构。
  6. 外观模式(Facade Pattern):向现有的系统添加一个接口,客户端访问此接口来隐藏系统的复杂性。
  7. 享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
  8. 代理模式(Proxy Pattren):一个类代表另一个类的功能。

🍭结构性模式之享元模式(Flyweight Pattern)

🍎享元模式

  • 享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的服用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。对象结构型。
  • 在享元模式中可以共享的相同内容为内部状态(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
  • 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。

在这里插入图片描述

享元模式包含如下角色:

  • Flyweight:抽象享元类
  • ConcreteFlyweight:具体享元类
  • UnsharedConcreateFlyweight:非共享具体享元类
  • FlyweightFactory:享元工厂类

🍔代码实现

/**
 * 可共享状态和不可共享状态
 * 
 * 享元和原型
 * 1、享元返回的是这个人本身
 * 2、原型返回的是克隆人
 */
public abstract class AbstractWaitressFlyweight {


    boolean canService = true; // 能否服务

    // 正在服务。享元的不可共享属性留给外部进行改变的接口。
    abstract void service();

    // 服务完成。享元的不可共享属性留给外部进行改变的接口。
    abstract void end();

    public boolean isCanService() {
        return canService;
    }
}

/**
 * 具体享元类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BeautifulWaitress extends AbstractWaitressFlyweight {

    String id; // 工号
    String name; // 名字
    int age; // 年龄

    // 以上是共享的,不变的

    @Override
    void service() {
        System.out.println("工号:" + id + " 名字: " + name + " 年龄:" + age + " 正在为您服务");
        // 改变外部状态
        this.canService = false;
    }

    @Override
    void end() {
        System.out.println("工号:" + id + " 名字: " + name + " 年龄:" + age + " 服务结束");
        this.canService = true;
    }
}

/**
 * 足道店:这相当于享元工厂。店里有很多服务员
 */
public class ZuDao {
    private static Map<String, AbstractWaitressFlyweight> pool = new HashMap<>();

    public void addWaitress(AbstractWaitressFlyweight waitress) {
        pool.put(UUID.randomUUID().toString(), waitress);
    }

    // 享元,池子中有对象
    static {
        BeautifulWaitress waitress1 = new BeautifulWaitress("1111", "张三", 1);
        BeautifulWaitress waitress3 = new BeautifulWaitress("9527", "张三", 3);
        pool.put(waitress1.getId(), waitress1);
        pool.put(waitress3.getId(), waitress3);
    }

    public static AbstractWaitressFlyweight getWaitress(String name) {
        AbstractWaitressFlyweight flyweight = pool.get(name);
        if (flyweight == null) {
            for (AbstractWaitressFlyweight waitressFlyweight : pool.values()) {
                // 当前共享对象能否使用
                if (waitressFlyweight.isCanService()) {
                    return waitressFlyweight;
                }
            }
            return null;
        } else {
            return flyweight;
        }
    }
}

public class MainTest {
    public static void main(String[] args) {
        // 1.我
        AbstractWaitressFlyweight waitress1 = ZuDao.getWaitress("");
        waitress1.service();
        System.out.println(waitress1);
        // 2.张三
        AbstractWaitressFlyweight waitress2 = ZuDao.getWaitress("");
        waitress2.service();
        System.out.println(waitress2);
        waitress2.end();
        // 3.李四
        AbstractWaitressFlyweight waitress3 = ZuDao.getWaitress("");
        waitress3.service();
        System.out.println(waitress3);
    }
}

工号:1111 名字: 张三 年龄:1 正在为您服务
BeautifulWaitress(id=1111, name=张三, age=1)
工号:9527 名字: 张三 年龄:3 正在为您服务
BeautifulWaitress(id=9527, name=张三, age=3)
工号:9527 名字: 张三 年龄:3 服务结束
工号:9527 名字: 张三 年龄:3 正在为您服务
BeautifulWaitress(id=9527, name=张三, age=3)

🍕应用场景

  • 典型的代表:数据库连接池
  • 所有的池化技术
  • 享元和原型模式有什么区别?享元是预先准备好的对象进行复用,原型没法确定预先有哪些。

相关文章:

  • EPSON XV4001BC陀螺仪传感器汽车导航系统的应用
  • 第二十七节 Java 多态
  • springboot2.7集成es8 https方式绕过证书访问集群
  • [游戏开发][Unity] 导出Xcode工程,完成调试与发布
  • 【linux】Debian访问Debian上的共享目录
  • wireshark windows 抓包https
  • HarmonyOS开发:超详细介绍如何开源静态共享包,实现远程依赖
  • 美易官方:美股调整即将到来?
  • 蓝桥杯C++大学B组一个月冲刺记录2024/3/19
  • Git常见命令
  • python爬虫实战——抖音
  • 京东云主机+京美建站SaaS版
  • 使用Cloudflare来给wordpress网站图片自动压缩加速
  • 从基础入门到学穿C++
  • IT系统可观测性
  • 算法——贪心算法
  • Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client
  • Layui表格复选框下一页后保持选中,table复选框checkbox跨页保持复选状态
  • [QJS xmake] 非常简单地在Windows下编译QuickJS!
  • 第十三届蓝桥杯省赛CC++ 研究生组
  • 马上评丨全民定制公交,打开城市出行想象空间
  • 印度一战机在巴基斯坦旁遮普省被击落,飞行员被俘
  • 国博馆刊|北朝至唐初夏州酋豪李氏家族的发展与身份记忆
  • 人民日报评“组团退演出服”:市场经济诚信原则需全社会维护
  • 中华人民共和国和俄罗斯联邦关于全球战略稳定的联合声明
  • 正荣地产:前4个月销售14.96亿元,控股股东已获委任联合清盘人