设计模式(十一)享元模式

1、用途

  享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。属于结构型模式,提供了一种减少对象数量从而改善应用所需的对象结构的方式。

 

2、意图

  运营共享计算有效地支持大量细粒度的对象。

 

3、主要解决

  在存在大量对象时,有可能会造成内存溢出,我们把其他共同的部分抽象处理,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

 

4、使用场景

(1)系统有大量相似对象;

(2)需要缓存池的场景;

(3)细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。

 

5、UML类图

 

 享元模式注意包含三种角色:

  •  抽象享元模式(Flyweight):享元对象抽象基类或者接口,同时定义出对象的外部状态和内部状态的接口或实现;
  • 具体享元角色(ConcreteFlyweight):实现抽象角色定义的业务。该角色的内部状态处理应该与环境无关,不能出现会有一个操作改变内部状态,同时修改了外部状态;
  • 享元工厂(FlyweightFactory): 负责管理享元对象池和创建享元对象。

 

 6、代码实例

1 /**
2  * @author it-小林
3  * @desc 网站抽象类
4  * @date 2021年07月31日 14:08
5  */
6 public abstract class WebSite {
7     public abstract void use();
8 }
 1 /**
 2  * @author it-小林
 3  * @desc 具体网站类
 4  * @date 2021年07月31日 14:10
 5  */
 6 public class ConcreteWebSite extends WebSite{
 7 
 8     private String name = "";
 9 
10     public ConcreteWebSite(String name) {
11         this.name = name;
12     }
13 
14     @Override
15     public void use() {
16         System.out.println("网站分类:" + name);
17     }
18 }
/**
 * @author it-小林
 * @desc 网站工厂类
 * @date 2021年07月31日 14:11
 */
public class WebSiteFactory {
    private HashMap<String, ConcreteWebSite> pool = new HashMap<>();

    //获取网站分类
    public WebSite getWebSiteCategory(String key){
        if(!pool.containsKey(key)){
            pool.put(key, new ConcreteWebSite(key));
        }
        return pool.get(key);
    }


    //获得网站分类总数
    public int getWebSiteCount(){
        return pool.size();
    }
}
/**
 * @author it-小林
 * @desc 客户端
 * @date 2021年07月31日 14:15
 */
public class Client {

    public static void main(String[] args) {
        WebSiteFactory webSiteFactory = new WebSiteFactory();

        WebSite fx = webSiteFactory.getWebSiteCategory("产品展示");
        fx.use();

        WebSite fy = webSiteFactory.getWebSiteCategory("产品展示");
        fy.use();

        WebSite fz = webSiteFactory.getWebSiteCategory("产品展示");
        fz.use();

        WebSite fa = webSiteFactory.getWebSiteCategory("博客");
        fa.use();

        WebSite fb = webSiteFactory.getWebSiteCategory("博客");
        fb.use();

        WebSite fc = webSiteFactory.getWebSiteCategory("博客");
        fc.use();

        System.out.println("网站分类总数:" + webSiteFactory.getWebSiteCount());
    }
}

 

7、注意事项

(1)注意划分外部状态和内部状态,否则可能会引起线程安全问题;

(2)这些类必须有一个工厂对象加以控制。

 

8、优缺点

优点:大大减少对象的创建,降低系统的内存,使效率提高。

缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

posted @ 2021-07-31 14:24  it-小林  阅读(39)  评论(0编辑  收藏  举报