享元模式
1.定义
运用共享技术,有效的支持大量细粒度的对象。享元即是共享的对象。
2.示例代码
对于细粒度的权限对象进行管理,说明享元模式。
/*描述授权数据的享元接口*/ public interface Flyweight{ /*判断传入的安全实体和权限是否和享元对象内部状态匹配*/ public boolean match(String securityEntity,String permit); } /*封装授权数据中重复出部分的享元对象*/ public class AuthorizationFlyweight implements Flyweight{ private String securityEntity; private String permit; //构造方法,传入安全实体和权限数据,以逗号分隔 public AuthorizationFlyweight(String state){ String ss[] = state.split(","); securityEntity = ss[0]; permit = ss[1]; } public String getSecurityEntity(){ return securityEntity; } public String getPermit(){ return permit; } public boolean match(String securityEntity,String permit){ if(this.securityEntity.equals(securityEntity) && this.permit.equals(permit)){ return true; } return false; } } /*享元工厂定义,通常实现为单利模式*/ public class FlyweightFactory{ private static FlyweightFactory factory = new FlyweightFactory(); private FlyweightFactory(){ } public static FlyweightFactory getInstance(){ return factory; } //缓存多个享元对象 private Map<String,Flyweight> fsMap = new HashMap<String,Flyweight>(); //获取key对应的享元对象 public Flyweight getFlyweight(String key){ Flyweight f = fsMap.get(key); if(f == null){ f = new AuthorizationFlyweight(key); fsMap.put(key,f); } } }
/*定义安全管理类,实现成单利*/ public class SecurityMgr{ private static SecurityMgr securityMgr = new SecurityMgr(); private SecurityMgr(){ } public static getInstance(){ return securityMgr; } //在运行期间用来存放登陆人员的权限 private Map<String,Collection<Flyweight>> map = new HashMap<String,Collection<Flyweight>>(); //模拟用户登陆 public void login(){ Colllection<Flyweight> col = queryByUser(user); map.put(user,col); } //判断某个用户对某个安全实体是否有某种权限 public boolean hasPermit(String user,String securityEntity,String permit){ Colllection<Flyweight> col = map.get(user); if(col == null || col.size() == 0){ return false; } for(Flyweight fm:col){ if(fm.match(securityEntity,permit)){ return true; } } return false; } //从数据库中获取某人所有的权限 private Colllection<Flyweight> queryByUser(){ Colllection<Flyweight> col= new ArrayList<Flyweight>(); for(String s : TestDB.colDB){ String ss[] = s.split(","); if(ss[0].equals(user)){ Flyweight fm = FlyweightFactory.getInstance().getFlyweight(ss[1],ss[2]); col.add(fm); } } return col; } } /*模拟数据库运行*/ public class TestDB{ public static Collection<String> colDB = new ArrayList<String>(); static{ colDB.add("张三,人员列表,查看"); colDB.add("李四,人员列表,查看"); colDB.add("李四,薪资数据,查看"); colDB.add("李四,薪资数据,修改"); } }
/*客户端测试*/ public class Client{ public static void main(String args[]){ SecurityMgr mgr = new SecurityMgr(); mgr.login("张三"); mgr.login("李四"); boolean f1 = mrg.hasPermit("张三","薪资数据","查看"); boolean f2 = mrg.hasPermit("李四","薪资数据","查看"); } }
3.实际应用
享元模式的设计重点在于分离变与不变,在享元模式中,为了创建和管理共享的享元部分,引入了享元工厂,在享元工厂中一般都包含有享元对象的实例池。
享元模式的本质:分离与共享