结构模式

享元模式
   顾名思义:共享元对象。如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必
 
为每一次使用创建新的对象。
享元模式是为数不多的、只为提升系统性能而生的设计模式。它的主要作用就是复用大对象(重量级对象),以节省内存空间和对象创建时间。
 
享元模式需要一个工厂来控制对象的访问,保证只得到一个对象。一个对象有内部和外部状态,内部不变,外部可变,其实可变指的是入参可变,且不被对象持有。
 

一、什么是享元模式

大量细粒度对象共享复用

二、补充说明

可以节约内存空间,提高系统的性能;
一个对象有内部和外部两种状态,内部状态是不变的,外部状态是可变的,把一个对象分成内部状态和外部状态,然后通过共享内部状态,达到节约内存空间的目的;
应用场景举例:一个文档中多次出现相同的图片;一篇文章中出现了很多重复的字符串;围棋的棋子(黑棋和白旗);

三、角色

抽象享元:一个接口或抽象类;
具体享元:内部状态为其成员属性,其实例为享元对象,可以共享;
享元工厂:生产享元对象,将具体享元对象存储在一个享元池中,享元池一般设计为一个存储“键值对”的集合;
客户端:使用享元对象

四、例子,JAVA实现

一个共享字符串的例子
 
抽象享元
package com.pichen.dp.structuralpattern.flyweight;

public interface IFlyweight {
    //id为外部状态,不共享
    public void setId(int id);
}
具体享元
 
package com.pichen.dp.structuralpattern.flyweight;

public class ShareStr implements IFlyweight{
    
    private String str; // 内部状态str作为成员变量,共享的.

    public ShareStr(String str) {
        this.str = str;
    }

    @Override
    public void setId(int id) {
        // id为外部状态,不共享
        System.out.println("str: " + str + "id:" + id);
    }
}    
享元工厂
 
package com.pichen.dp.structuralpattern.flyweight;

import java.util.HashMap;
import java.util.Map;

public class FlyweightFactory {

    private Map<String, Object> strMap = new HashMap<String, Object>();
    
    public IFlyweight getInstance(String str){
        
        IFlyweight fly = (IFlyweight) strMap.get(str);
        
        if(fly == null){
            fly = new ShareStr(str);
            strMap.put(str, fly);
        }
        
        return fly;
    }
}
 
 
客户端
 
package com.pichen.dp.structuralpattern.flyweight;

public class Main {

    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        
        ShareStr hello = (ShareStr) factory.getInstance("hello");
        hello.setId(1);
        
        ShareStr hello2 = (ShareStr) factory.getInstance("hello");
        hello.setId(2);
        
        ShareStr test = (ShareStr) factory.getInstance("test");
        hello.setId(3);

        System.out.println(hello);
        System.out.println(hello2);
        System.out.println(hello.equals(hello2));
        
        System.out.println(test);
        System.out.println(hello.equals(test));
        
    }
}
 
一些常见的资源池,比如RedisClient的Manager,线程池,连接池,都是比较经典的享元模式的实现
 
 
 
 
 
原文地址:https://www.cnblogs.com/43726581Gavin/p/9043933.html