zoukankan      html  css  js  c++  java
  • 大话设计模式笔记(二十三)の享元模式

    享元模式

    定义

    运用共享技术有效的支持大量细粒度的对象。

    UML图

    举个栗子

    实际开发当中,一个项目如果做得好,如果市场打通到其他地方,那么核心代码其实是可以通用的,只不过用着不同的数据和特性出来的模版而已,这些对用户来说是非透明的。使用最小的开销获得最大的收益,这是所有公司的目的。

    Talk is cheap, show me the code

    (屁话少说,放码过来)

    /**
     * 网站抽象类
     * Created by callmeDevil on 2019/12/15.
     */
    public abstract class WebSite {
        public abstract void use(User user);
    }
    
    /**
     * 具体网站类
     * Created by callmeDevil on 2019/12/15.
     */
    public class ConcreteWebSite extends WebSite{
    
        private String name = "";
    
        public ConcreteWebSite(String name){
            this.name = name;
        }
    
        @Override
        public void use(User user) {
            System.out.println("网站分类:" + name + " 用户:" + user.getName());
        }
    
    }
    
    /**
     * 网站工厂
     * Created by callmeDevil on 2019/12/15.
     */
    public class WebSiteFactory {
    
        private HashMap<String, WebSite> flyweights = new HashMap<>();
    
        // 获得网站分类
        public WebSite getWebSiteCategory(String key){
            // 判断是否存在这个对象,如果存在则直接返回,若不存在则实例化再返回
            if (!flyweights.containsKey(key)) {
                flyweights.put(key, new ConcreteWebSite(key));
            }
            return flyweights.get(key);
        }
    
        // 获得网站分类总数
        public int getWebSiteCount(){
            return flyweights.size();
        }
    
    }
    
    
    /**
     * 用户
     * Created by callmeDevil on 2019/12/15.
     */
    public class User {
    
        private String name;
    
        public User(String name){
            this.name = name;
        }
    
        // 省略 get set
    }
    
    public class Test {
        public static void main(String[] args) {
            WebSiteFactory factory = new WebSiteFactory();
    
            WebSite fx = factory.getWebSiteCategory("产品展示");
            fx.use(new User("路飞"));
    
            // 共享上方生成的对象,不再实例化
            WebSite fy = factory.getWebSiteCategory("产品展示");
            fy.use(new User("索隆"));
    
            WebSite fz = factory.getWebSiteCategory("产品展示");
            fz.use(new User("山治"));
    
            WebSite fl = factory.getWebSiteCategory("博客");
            fl.use(new User("娜美"));
    
            WebSite fm = factory.getWebSiteCategory("博客");
            fm.use(new User("乌索普"));
    
            WebSite fn = factory.getWebSiteCategory("博客");
            fn.use(new User("乔巴"));
    
            // 统计实例化个数,结果应为2
            System.out.println("网站分类总数为:" + factory.getWebSiteCount());
        }
    }
    

    运行结果

    网站分类:产品展示 用户:路飞
    网站分类:产品展示 用户:索隆
    网站分类:产品展示 用户:山治
    网站分类:博客 用户:娜美
    网站分类:博客 用户:乌索普
    网站分类:博客 用户:乔巴
    网站分类总数为:2
    

    总结

    好处

    享元模式可以避免大量非常相似的类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本相同的,有时就能够受大幅度的减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传进来,就可以通过共享大幅度的减少单个实例的数目。

    使用情景

    • 如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大存储开销时就应该考虑应用
    • 对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑应用。
  • 相关阅读:
    【算法学习笔记】27.动态规划 解题报告 SJTU OJ 1254 传手绢
    【算法学习笔记】26.扫描维护法 解题报告 SJTU OJ 1133 数星星
    【算法学习笔记】25.贪心法 均分纸牌问题的分析
    【算法学习笔记】24.记忆化搜索 解题报告 SJTU OJ 1002 二哥种花生
    【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
    【算法学习笔记】22.算法设计初步 二分查找 上下界判断
    【算法学习笔记】21.算法设计初步 求第k个数 划分法 快排法
    【算法学习笔记】20.算法设计初步 归并排序 求逆序数
    【算法学习笔记】19.算法设计初步 最大子列和问题的几种方法
    【算法学习笔记】18.暴力求解法06 隐式图搜索2 八数码问题 未启发
  • 原文地址:https://www.cnblogs.com/call-me-devil/p/12044428.html
Copyright © 2011-2022 走看看