博客信息

享元模式Flyweight(结构模式)

发布时间:『 2019-03-26 23:47』  博客类别:23种设计模式  阅读(630)
  • 术语

    Flyweight:享元

  • 角色

    • Flyweight 抽象的享元角色, Website

    • ConcreteFlyWeight(内部状态) 具体的享元角色 BlogWebSite NewsWebSite 这个是必须聚合到享元工厂

    • UnSharedConcreteFlyWeight(外部状态) 不可共享的角色,一般不会出现在享元工厂 这个是非必要的角色,视需求而定

    • FlyWeightFactory 享元工厂类,用于构建一个池容器(集合), 同时提供从池中获取对象方法 WebsiteFactory

  • 案例

    需求:项目外包案例;

    给客户A做了一个产品展示网站,客户A的朋友觉得效果不错,也需要一个类似的网站,但是运营的内容有所不同;

    具体需求:客户ABC三个客户要拿来展示博客,客户DEF三个客户要拿来展示新闻,客户GHL三个客户要拿来展示电影...

    • 使用前

      按照常规的逻辑来思考,ABCDEFGHL九个客户要求开发相同结构的网站,运营不同的网站,那么我们将只要将这个结构的网站做出来,打成jar包,复制九份部署到九个客户的服务器中,让客户查看项目展示效果即可;

      这就相当于工厂类创建出九个网站实例出来就可以了

      代码如下

      public class User {
        private String name;

        public User(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
      }


      package com.javaxl.design.flyweight.before;

      /**
      * @author 小李飞刀
      * @site www.javaxl.com
      * @company
      * @create  2020-02-23 19:50
      */
      public class WebSite {
        private String contentType;

        public String getContentType() {
            return contentType;
        }

        public void setContentType(String contentType) {
            this.contentType = contentType;
        }

        public WebSite(String contentType) {
            this.contentType = contentType;
        }

        public void use(User user) {
            System.out.println(user.getName() + "要求开发" + this.contentType);
        }
      }

      class WebSiteFactory {
        public static WebSite createWebSite(String contentType) {
            return new WebSite(contentType);
        }
      }


      public class Client {
        public static void main(String[] args) {
            WebSite webSite1 = WebSiteFactory.createWebSite("博客网站");
            WebSite webSite2 = WebSiteFactory.createWebSite("博客网站");
            WebSite webSite3 = WebSiteFactory.createWebSite("博客网站");
            webSite1.use(new User("客户A"));
            webSite2.use(new User("客户B"));
            webSite3.use(new User("客户C"));
            System.out.println(webSite1.hashCode());
            System.out.println(webSite2.hashCode());
            System.out.println(webSite3.hashCode());

            System.out.println("==================");

            WebSite webSite4 = WebSiteFactory.createWebSite("新闻网站");
            WebSite webSite5 = WebSiteFactory.createWebSite("新闻网站");
            WebSite webSite6 = WebSiteFactory.createWebSite("新闻网站");
            webSite4.use(new User("客户D"));
            webSite5.use(new User("客户E"));
            webSite6.use(new User("客户F"));

            WebSite webSite7 = WebSiteFactory.createWebSite("电影网站");
            WebSite webSite8 = WebSiteFactory.createWebSite("电影网站");
            WebSite webSite9 = WebSiteFactory.createWebSite("电影网站");
            webSite7.use(new User("客户G"));
            webSite8.use(new User("客户H"));
            webSite9.use(new User("客户L"));

        }
      }


小李飞刀_设计模式


思考:当客户ABC的开发要求一致时,还有必要搞三个服务器让客户去看项目展示效果吗?

我们可以让客户ABC,看部署在同一台服务器上的博客网站的展示效果;

享元模式(蝇量模式)干的就是这么一件事情。

  • 使用后

    UML类图


小李飞刀_设计模式

相较于上面的代码,工厂类做细微的改动

class WebSiteFactory {
  static HashMap<String, WebSite> webSiteMap = new HashMap();

  public static WebSite createWebSite(String contentType) {
      WebSite webSite = webSiteMap.get(contentType);
      if (webSite == null) {
          webSite = new WebSite(contentType);
          webSiteMap.put(contentType, webSite);
      }
      return webSite;
  }
}

小李飞刀_设计模式


结果:相同开发需求的客户,共享了同一个服务器来验收网站展示效果;

上面的是借助享元模式的思想进行类结构设计但不是标准的享元模式结构

标准的享元模式UML类图如下


小李飞刀_设计模式



  • 注意事项及细节

    • 大大减少了对象的创建,降低了程序内存的占用,提高效率

    • 用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用 HashMap/HashTable 存储

    • 使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制


    注意:享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变
  • 应用

    • 字符串常量池

    • 数据库连接池

    • 缓冲池

    • JDK源码中Integer类的valueOf

    • 新一代虚拟化技术Docker


over......

关键字:     设计模式  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有