设计模式-享元模式(Flyweight)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/love905661433/article/details/84402362

概述

  • 定义 : 提供了减少对象数量从而改善应用所需的对象结构的方式
  • 运用共享技术有效的支持大量细粒度的对象
  • 类型 : 结构型

适用场景

  • 常常应用于系统底层的开发, 以便解决系统的性能问题
  • 系统有大量相似的对象, 需要缓冲池的场景

优点

  • 减少对象的创建, 降低内存中对象的数量, 降低系统的内存, 提高效率
  • 减少内存之外的其他资源占用

缺点

  • 关注内/外部状态, 关注线程安全问题
  • 使系统, 程序的逻辑复杂化

扩展

  • 内部状态
  • 外部状态

模式角色

  • Flyweight : 描述一个接口,通过这个接口f l y w e i g h t可以接受并作用于外部状态

  • ConcreteFlyweight : 实 现 F l y w e i g h t 接 口 , 并 为 内 部 状 态 ( 如 果 有 的 话 ) 增 加 存 储 空 间 。
    ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的;即,它必
    须独立于 ConcreteFlyweight对象的场景。

  • UNsharedConcreteFlyweight : 并非所有的F l y w e i g h t子类都需要被共享。 F l y w e i g h t接口使共享成为可能,但它并不强制共享。在F l y w e i g h t对象结构的某些层次, U n s h a r e d C o n c r e t e F l y w e i g h t对象通常将C o n c r e t e F l y w e i g h t对象作为子节点

  • FlyweightFactory

    • 创建并管理Flyweight 对象。
    • 确保合理地共享Flyweight当用户请求一个Flyweight 时,F l y w e i g h t F a c t o r y对象提供一个已创建的实例或者创建一个(如果不存在的话)。
  • Client

    • 维持一个对Flyweight 的引用。
    • 计算或存储一个(多个)Flyweight 的外部状态。

代码实现

场景:

1.有一个员工接口Employee, 对应Flyweight接口
2.部门经理类Manger实现了员工接口, 对应ConcreteFlyweight接口实现
3. 一个EmployeeFactory类用于管理Employee, 对应FlyweightFactory
4. 场景就是部门经理做年终报告
代码如下 :

/**
 * Flyweight角色
 *
 * @author 七夜雪
 * @create 2018-11-23 18:52
 */
public interface Employee {
    void report();
}
/**
 * ConcreteFlyweight 角色
 * @author 七夜雪
 */
public class Manager implements Employee {
    @Override
    public void report() {
        System.out.println(reportContent);
    }
    // 这个就是内部状态
    private String title = "部门经理";
    private String department;
    private String reportContent;

    public void setReportContent(String reportContent) {
        this.reportContent = reportContent;
    }

    public Manager(String department) {
        this.department = department;
    }
}
/**
 * FlyweightFactory角色
 *
 * @author 七夜雪
 * @create 2018-11-23 14:07
 */
public class EmployeeFactory {
    private static final Map<String,Employee> EMPLOYEE_MAP = new HashMap<String,Employee>();

    public static Employee getManager(String department){
        Manager manager = (Manager) EMPLOYEE_MAP.get(department);

        if(manager == null){
            manager = new Manager(department);
            System.out.print("创建部门经理:"+department);
            String reportContent = department+"部门汇报:此次报告的主要内容是......";
            manager.setReportContent(reportContent);
            System.out.println(" 创建报告:"+reportContent);
            EMPLOYEE_MAP.put(department,manager);

        }
        return manager;
    }

}

测试代码:

    public static void main(String[] args) {
        for(int i=0; i<10; i++){
            String department = departments[(int)(Math.random() * departments.length)];
            Manager manager = (Manager) EmployeeFactory.getManager(department);
            manager.report();

        }

    }

测试结果:

创建部门经理:测试 创建报告:测试部门汇报:此次报告的主要内容是…
测试部门汇报:此次报告的主要内容是…
创建部门经理:开发 创建报告:开发部门汇报:此次报告的主要内容是…
开发部门汇报:此次报告的主要内容是…
创建部门经理:人力 创建报告:人力部门汇报:此次报告的主要内容是…
人力部门汇报:此次报告的主要内容是…
创建部门经理:产品 创建报告:产品部门汇报:此次报告的主要内容是…
产品部门汇报:此次报告的主要内容是…
人力部门汇报:此次报告的主要内容是…
产品部门汇报:此次报告的主要内容是…
开发部门汇报:此次报告的主要内容是…
人力部门汇报:此次报告的主要内容是…
开发部门汇报:此次报告的主要内容是…
人力部门汇报:此次报告的主要内容是…

从测试结果来看, 只有第一次使用时才创建了Manager对象, 其余都是直接从Map中获取了, 这就是享元模式的概念

猜你喜欢

转载自blog.csdn.net/love905661433/article/details/84402362