享元模式(FlyWeight)

定义

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

UML类图

角色

  抽象享元(Flyweight)角色 :给出一个抽象接口,以规定出所有具体享元角色需要实现的方法。

  具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定出的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。

  享元工厂(FlyweightFactory)角色 :本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。

例子

  用户类

package com.csdhsm.pattemdesign.flyweight;

/**  
 * @Title:  User.java   
 * @Description: 用户类 
 * @author: Han   
 * @date:   2016年7月1日 上午8:50:54  
 */  
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;
    }
}

  网站抽象类,充当FlyWeight

package com.csdhsm.pattemdesign.flyweight;

/**  
 * @Title:  WebSite.java   
 * @Description: 网站抽象类
 * @author: Han   
 * @date:   2016年7月1日 上午8:53:39  
 */  
public abstract class WebSite {
    
    public abstract void user(User user);
}

  具体网站实现类,充当ConcreteFlyweight

package com.csdhsm.pattemdesign.flyweight;

/**  
 * @Title:  ConcreteWebsite.java   
 * @Description: 具体网站类
 * @author: Han   
 * @date:   2016年7月1日 上午8:53:53  
 */  
public class ConcreteWebsite extends WebSite {
    
    private String name = "";

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

    @Override
    public void user(User user) {
        System.out.println("网站分类: " + name + " 用户: " + user.getName());
    }
}

  网站享元工厂类,FlyweightFactory

package com.csdhsm.pattemdesign.flyweight;

import java.util.HashMap;

/**  
 * @Title:  WebSiteFactory.java   
 * @Description: 网站享元工厂类
 * @author: Han   
 * @date:   2016年7月1日 上午8:55:37  
 */  
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();
    }
}

  客户端

package com.csdhsm.pattemdesign.flyweight;

public class Solution {
    public static void main(String[] args) {

        WebSiteFactory factory = new WebSiteFactory();
        WebSite xm = factory.getWebSiteCategory("产品展示");
        xm.user(new User("小明"));

        WebSite xh = factory.getWebSiteCategory("产品展示");
        xh.user(new User("小红"));

        WebSite xx = factory.getWebSiteCategory("产品展示");
        xx.user(new User("小溪"));

        WebSite xc = factory.getWebSiteCategory("博客");
        xc.user(new User("小陈"));

        WebSite xl = factory.getWebSiteCategory("博客");
        xl.user(new User("小李"));

        WebSite xg = factory.getWebSiteCategory("产品展示");
        xg.user(new User("小侯"));
        
        System.out.println("网站总数为 " + factory.getWebSiteCount());
    }
}

  结果

  OK,可以看见,在享元工厂里的网站被共享了

总结

  享元模式的优点在于它大幅度地降低内存中对象的数量。

  享元模式的缺点是

    1使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

    2将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

 posted on 2016-07-01 09:04  韩思明  阅读(254)  评论(0编辑  收藏  举报