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

设计模式之享元模式

1. 概念

        享元模式(Flyweight Pattern), 运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。

        在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。

        在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。

享元模式包含如下角色:

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

2. 代码实现

        在了解了上述享元模式的基本概念后,我将模拟以下场景需求来实现享元模式以便我们更加深刻理解这个设计模式。我们这里以饭店服务为例,在饭店中有服务员对象,每个服务员会需要对不同的客户进行服务。这里的服务员就被多个客户所共享(享元类),但是每个服务员在同一时间只能为一名客户服务,即一对一的关系,只有完成后才可以为另一个客户所服务。

        这里我们先创建一个享元抽象类:

/**
 * 可共享和不可共享状态
 */
public abstract class AbstractWaitressFlyweight {

    boolean canService = true;//能否服务

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

    public boolean isCanService() {
        return canService;
    }
}

        同时我们也可以实现该抽象,创建一个具体享元类:

/**
 * 具体享元类
 */
@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 Resaurant {

    private static Map<String,AbstractWaitressFlyweight> pool = new HashMap<>();
    //享元,池子中有对象
    static {
        BeautifulWaitress waitress =
                new BeautifulWaitress("1111","张三",18);


        BeautifulWaitress waitress2 =
                new BeautifulWaitress("9527","李四",20);


        pool.put(waitress.id,waitress);
        pool.put(waitress2.id,waitress2);
    }

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

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

        return flyweight;

    }

}

         最后我们编写外部调用类进行测试:

public class MainTest {

    public static void main(String[] args) {

        //1、A客户
        AbstractWaitressFlyweight waitress = Restaurant.getWaitress("");
        waitress.service();
        System.out.println(waitress);
        //2、B客户
        AbstractWaitressFlyweight waitress1 = Restaurant.getWaitress("");
        waitress1.service();
        System.out.println(waitress1);

        waitress1.end();
        //3、C客户
        AbstractWaitressFlyweight waitress2 = Restaurant.getWaitress("");
        System.out.println(waitress2);

    }
}

3. 应用场景

  • 数据库连接池
  • 所有的池化技术
  • ...

4. 总结

        享元模式在平时我们编写代码时可能并不会设计太多,但是就想上述所提到的,几乎很多池化技术都是通过享元模式来实现的,所以在我们阅读一些优秀框架的源码时我们也会遇见该模式的实现。

        至此,设计模式篇的结构型模式就全部编写完成(由于组合模式我们平时四处可见没有什么讲解的必要就略过了;其次过滤器模式整体的思路也较为简单也直接略过)。结构型设计模式重点就在于开发人员在编写需求前就要对类的结构考虑清楚,是该选择组合模式还是继承来实现多个类的组合是我们开发过程中的重难点,我们需要根据具体的业务场景以及整个项目的性能来看待,并且当我们充分理解了结构型模式后阅读一些优秀的框架源码时也会更加得轻松。

相关文章:

  • 图解AUTOSAR_SWS_FlexRayDriver
  • 使用分布式锁和乐观锁解决超卖问题
  • 闪蒸高密度聚乙烯无纺布市场报告:探索高性能材料的新机遇
  • 搜广推面经六十八
  • yum拒绝连接
  • 【区块链+ 人才服务】蓝鲸智课——区块链课程与实训平台 | FISCO BCOS 应用案例
  • GS069W电动工具直流调速电路:高效调速方案解析
  • 【多线程-第四天-自己模拟SDWebImage的下载图片功能-取消操作 Objective-C语言】
  • Quartz 分布式集群 数据持久化任务调度系统
  • 【VScode】C/C++使用教程
  • C++11实现一个自旋锁
  • Flutter:Flutter SDK版本控制,fvm安装使用
  • 寄存器相关及清零、置1、取反等位移操作
  • 进程的创建态、运行状态和阻塞状态
  • FreeRTOS与RT-Thread深度对比:从入门到精通的全面解析
  • Redlinux(2025.3.29)
  • 地图与图层操作
  • 18-产品经理-跟踪进度
  • DeepSeek-R1-Distil-Qwen-7B:为何说它是Qwen模型的“瘦身版”?
  • 计科数据库第二次上机操作--实验二 表的简单查询
  • 对做网站公司的疑问/百度灰色词优化排名
  • 网站建设公司的年报/企业培训体系搭建
  • 阿里巴巴的网站应该怎么做/搜索引擎推广seo
  • 做设计什么网站可以兼职/百度seo排名在线点击器
  • 查询工具类网站制作/模板式自助建站
  • 厦门 外贸商城网站制作/成都网站seo厂家