首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

读《研磨设计形式》-代码笔记-享元模式-Flyweight

2012-12-22 
读《研磨设计模式》-代码笔记-享元模式-Flyweight声明:本文只为方便我个人查阅和理解,详细的分析以及源代码

读《研磨设计模式》-代码笔记-享元模式-Flyweight
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/



import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.List;import java.util.Map;/* * 个人理解: * 1、Flyweight模式其实就是缓存:把公用的、可共享的数据缓存(示例里面把数据存放在一个单例的Map里面) * 2、不需共享的享元对象:因为这些对象是Flyweight的组合,Flyweight已经共享了,就不需要重复缓存了 *   例如:操作薪资数据=查看薪资数据+修改薪资数据 *//** * Flyweight模式的主要原理就在这里 * 假设要描述“张三拥有薪资数据的查看权限”“李四拥有薪资数据的查看权限”,“王五拥有薪资数据的查看权限”…… * 我们很容易看出,“薪资数据的查看权限”是可共享的。我们把它定义为IFlyweight接口,并将它缓存在一个HashMap里面: */enum FlyweightFactory {        INSTANCE;        //Map<"薪资数据,查看",IFlyweight(entity="薪资数据",permission="查看")>    private Map<String, IFlyweight> flyweightMap = new HashMap<String, IFlyweight>();        public IFlyweight getFlyweight(String state) {        IFlyweight flyweight = flyweightMap.get(state);        if (flyweight == null) {            flyweight = new AuthorizationFlyweight(state);            flyweightMap.put(state, flyweight);        }        return flyweight;    }}//要共享的数据-接口interface IFlyweight {/** * 验证是否对该“安全实体”有权限 * @param securityEntity 安全实体,即需要保证安全的数据,访问时要做访问控制,例如,工资数据 * @param permission权限描述,例如:查看、修改等等 * @return true 表示通过 false表示不通过 */boolean testify(String securityEntity, String permission);//这个方法是提供给“不需共享的对象”的。“共享对象”不支持这个方法(throw unsupportException)void add(IFlyweight flyweight);//返回Flyweight的描述String getDescription();}//要共享的数据-具体实现类class AuthorizationFlyweight implements IFlyweight {private String securityEntity;private String permission;public boolean testify(String securityEntity, String permission) {return this.securityEntity.equals(securityEntity)&& this.permission.equals(permission);}//e.g. state="薪资数据,查看"public AuthorizationFlyweight(String state) {String[] states = state.split(",");this.securityEntity = states[0];this.permission = states[1];}public String getSecurityEntity() {return securityEntity;}public String getPermission() {return permission;}public void add(IFlyweight flyweight) {throw new UnsupportedOperationException("对象不支持此功能");}public String getDescription() {return permission + securityEntity;}}//不需共享的数据class UnsharedFlyweight implements IFlyweight {//保存了一系列的“共享对象”private List<IFlyweight> list = new ArrayList<IFlyweight>();public void add(IFlyweight flyweight) {list.add(flyweight);}public boolean testify(String securityEntity, String permission) {for (IFlyweight flyweight : list) {if (flyweight.testify(securityEntity, permission)) {return true;}}return false;}public String getDescription() {StringBuilder sb = new StringBuilder("(组合权限 ");for (IFlyweight flyweight : list) {sb.append(flyweight.getDescription()).append("=").append(flyweight).append(" ");}sb.append(")\n");return sb.toString();}}enum SecurityManagement {INSTANCE;//Map<用户名,用户权限> 在web应用中,这些数据通常存放在session中private Map<String, Collection<IFlyweight>> userPermissionMap = new HashMap<String, Collection<IFlyweight>>();//登录时查询并缓存用户拥有的权限public void login(String user) {Collection<IFlyweight> permissions = this.getPermissionsOf(user);userPermissionMap.put(user, permissions);}//begin-只测试“共享”private Collection<IFlyweight> getPermissionsOf(String user) {Collection<IFlyweight> permissions = new ArrayList<IFlyweight>();for (String data : TestDB.dataList) {String[] datas = data.split(",");String userName = datas[0];String securityEntity = datas[1];String permission = datas[2];if (userName.equals(user)) {String state = securityEntity + "," + permission;//从缓存中取数据。如果缓存中没有,就把这个数据保存在缓存中IFlyweight flyweight = FlyweightFactory.INSTANCE.getFlyweight(state);permissions.add(flyweight);}}return permissions;}public void login2(String user) {Collection<IFlyweight> permissions = this.getPermissionsOf2(user);userPermissionMap.put(user, permissions);}//end//begin-同时测试“共享”和“不共享”private Collection<IFlyweight> getPermissionsOf2(String user) {Collection<IFlyweight> permissions = new ArrayList<IFlyweight>();for (String data : TestDB2.dataList) {String[] datas = data.split(",");String userName = datas[0];String securityEntity = datas[1];String permission = datas[2];String type = datas[3];if (userName.equals(user)) {IFlyweight flyweight = null;String state = null;if (type.equals("2")) {//表示是组合类型的授权state = securityEntity + permission;flyweight = new UnsharedFlyweight();String[] composites = TestDB2.dataMap.get(state);for (String composite : composites) {//“共享对象”的组合。“共享对象”从缓存中取出IFlyweight singleFlyweight = FlyweightFactory.INSTANCE.getFlyweight(composite);flyweight.add(singleFlyweight);}} else {state = securityEntity + "," + permission;flyweight = FlyweightFactory.INSTANCE.getFlyweight(state);}permissions.add(flyweight);}}return permissions;}//endpublic boolean hasPermission(String user, String securityEntity, String permission) {System.out.println("现在验证:"+ user + securityEntity + permission);boolean result = false;Collection<IFlyweight> flyweightCollection = userPermissionMap.get(user);if (flyweightCollection == null || flyweightCollection.size() == 0) {System.out.println(user + "没有登陆或是没有分配任何权限");result = false;} else {System.out.println("拥有的权限:");for (IFlyweight flyweight : flyweightCollection) {System.out.println(flyweight.getDescription()+ ";flyweight = " + flyweight);if (flyweight.testify(securityEntity, permission)) {result = true;break;}}}return result;}}//数据库1-共享class TestDB{public static Collection<String> dataList = new ArrayList<String>();static {dataList.add("张三,人员列表,查看");dataList.add("李四,人员列表,查看 ");dataList.add("李四,薪资数据,查看");dataList.add("李四,薪资数据,修改");dataList.add("张三1,人员列表,查看");dataList.add("张三2,人员列表,查看");dataList.add("张三3,人员列表,查看");}}//数据库2-同时有共享和不共享的数据。增加了一个字段表示权限类型是单个权限(1)还是组合权限(2)class TestDB2{public static Collection<String> dataList = new ArrayList<String>();public static Map<String, String[]> dataMap = new HashMap<String, String[]>();static {dataList.add("张三,人员列表,查看,1");dataList.add("张三1,人员列表,查看,1");dataList.add("张三2,人员列表,查看,1");dataList.add("张三3,人员列表,查看,1");dataList.add("李四,人员列表,查看,1");dataList.add("李四,薪资数据,查看,1");//adataList.add("李四,薪资数据,修改,1"); //b(a+b刚好是“薪资数据操作”;实际应用中不应该这样存储)dataList.add("张三,薪资数据,操作,2");dataMap.put("薪资数据操作", new String[]{"薪资数据,查看","薪资数据,修改"});}}//这个类是用来测试的public class FlyweightPattern {public static void main(String[] args) {SecurityManagement  securityManagement = SecurityManagement.INSTANCE;/*//测试“共享”securityManagement.login("张三");securityManagement.login("张三1");securityManagement.login("张三2");securityManagement.login("张三3");securityManagement.login("李四");boolean b1 = securityManagement.hasPermission("张三", "薪资数据", "查看");boolean b2 = securityManagement.hasPermission("李四", "薪资数据", "查看");System.out.println(b1 + "," + b2);//可以看到下面这四句,输出flyweight时,是同一个flyweight,表明缓存被使用了System.out.println(securityManagement.hasPermission("张三", "人员列表", "查看"));System.out.println(securityManagement.hasPermission("张三1", "人员列表", "查看"));System.out.println(securityManagement.hasPermission("张三2", "人员列表", "查看"));System.out.println(securityManagement.hasPermission("张三3", "人员列表", "查看"));*///测试“共享”和“不共享的对象”securityManagement.login2("张三");securityManagement.login2("张三1");securityManagement.login2("张三2");securityManagement.login2("张三3");securityManagement.login2("李四");//可以看到,张三“薪资数据操作”所包含的“薪资数据查看”、“薪资数据修改”这两个flyweight与李四的是同一对象System.out.println(securityManagement.hasPermission("张三", "薪资数据", "修改"));System.out.println(securityManagement.hasPermission("张三", "薪资数据", "查看"));System.out.println(securityManagement.hasPermission("李四", "薪资数据", "修改"));System.out.println(securityManagement.hasPermission("李四", "薪资数据", "查看"));System.out.println(securityManagement.hasPermission("李四", "人员列表", "修改"));//不能直接测试“操作”//System.out.println(securityManagement.hasPermission("张三", "薪资数据", "操作"));}}

热点排行