`

读《研磨设计模式》-代码笔记-享元模式-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;
	}
	//end
	
	public 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");	//a
		dataList.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("张三", "薪资数据", "操作"));
		
	}

}


0
0
分享到:
评论

相关推荐

    设计模式学习笔记--Flyweight享元模式.docx

    设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx设计模式学习笔记--Flyweight享元模式.docx

    c++设计模式-结构型模式-享元模式

    c++设计模式-结构型模式-享元模式;qt工程;c++简单源码; 享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类...

    研磨设计模式-part2

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    研磨设计模式-part4

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    研磨设计模式-part3

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    研磨设计模式(完整带书签).part2.pdf

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    C#设计模式-吕震宇

    设计模式(14)-Flyweight Pattern C#设计模式(13)-Proxy Pattern C#设计模式(12)-Decorator Pattern C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter Pattern C#设计模式(9)-Prototype ...

    研磨设计模式(完整带书签).part1.pdf

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) ...

    C#设计模式之Flyweight

    设计模式 Flyweight

    设计模式(C#)之享元模式(Flyweight Pattern)

    设计模式(C#)之享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度的对象。

    C++设计模式课件13_Flyweight_享元模式.pdf

    C++设计模式课件13_Flyweight_享元模式.pdf

    设计模式--C++

    4.6 Flyweight(享元)—对象结构型模式 128 4.7 Proxy(代理)—对象结构型模式 137 4.8 结构型模式的讨论 144 4.8.1 Adapter 与 Bridge 144 4.8.2 Composite、 Decorator 与 Proxy 145 第 5 章 行为模式 147 5.1 ...

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) (Level 300)

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) (Level 300)

    XiaokangLei#CS-Notes-Plus#设计模式 - 享元1

    Flyweight:享元对象IntrinsicState:内部状态,享元对象共享内部状态ExtrinsicState:外部状态,每个享元对象的外部状态不同pub

    C++设计模式之享元模式(Flyweight)

    主要为大家详细介绍了C++设计模式之享元模式Flyweight,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    研磨设计模式.part3(共4个)

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor)...

    研磨设计模式.part2(共4个)

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor)...

    研磨设计模式.part4(共4个)

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor)...

    研磨设计模式.part1(共4个)

    第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor)...

    head first 设计模式-设计模式必读

    至于第14章则很快地浏览尚未介绍的设计模式,包括Bridge、Builder、Chain of Responsibility、Flyweight、Interpreter、Mediator、Memento、Prototype,Visitor。第1章还介绍了四个○○基本概念(抽象、封装、继承、...

Global site tag (gtag.js) - Google Analytics