享元模式的定义
运用共享技术有效地支持大量细粒度的对象。
享元模式的本质
分离与共享
示例1
/**
* 享元接口,通过这个接口享元可以接受并作用于外部状态
*/
public interface Flyweight {
/**
* 传入外部状态
* @param extrinsicState
*/
void operation(String extrinsicState);
}
/**
* 享元对象
*/
public class ConcreteFlyweight implements Flyweight {
/**
* 示例,描述内部状态
*/
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
@Override
public void operation(String extrinsicState) {
//具体的功能处理,可能会用到享元内部、外部的状态
}
}
/**
* 不需要共享的Flyweight对象
*/
public class UnsharedConcreteFlyweight implements Flyweight {
/**
* 示例,描述对象的状态
*/
private String allState;
@Override
public void operation(String extrinsicState) {
//具体的功能处理
}
}
import java.util.HashMap;
import java.util.Map;
/**
* 享元工厂
*/
public class FlyweightFactory {
/**
* 缓存多个Flyweight对象,这里只是示意一下
*/
private Map<String, Flyweight> fsMap = new HashMap<>();
/**
* 获取key对应的享元对象
* @param key
* @return
*/
public Flyweight getFlyweight(String key) {
Flyweight f = fsMap.get(key);
if (null == f) {
f = new ConcreteFlyweight(key);
fsMap.put(key, f);
}
return f;
}
}
public class Client {
//具体的功能处理
}
示例2
public class AuthorizationModel {
/**人员*/
private String user;
/**安全实体*/
private String securityEntity;
/**权限*/
private String permit;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getSecurityEntity() {
return securityEntity;
}
public void setSecurityEntity(String securityEntity) {
this.securityEntity = securityEntity;
}
public String getPermit() {
return permit;
}
public void setPermit(String permit) {
this.permit = permit;
}
}
public interface Flyweight {
/**
* 判断传入的安全实体和权限,是否和享元对象内部状态匹配
* @param securityEntity
* @param permit
* @return
*/
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(",");
this.securityEntity = ss[0];
this.permit = ss[1];
}
@Override
public boolean match(String securityEntity, String permit) {
if (this.securityEntity.equals(securityEntity) &&
this.permit.equals(permit)) {
return true;
}
return false;
}
public String getSecurityEntity() {
return securityEntity;
}
public String getPermit() {
return permit;
}
}
import java.util.HashMap;
import java.util.Map;
/**
* 享元工厂
*/
public class FlyweightFactory {
private static FlyweightFactory factory = new FlyweightFactory();
private FlyweightFactory() {}
public static FlyweightFactory getInstance() {
return factory;
}
/**
* 缓存多个Flyweight对象
*/
private Map<String, Flyweight> fsMap = new HashMap<>();
public Flyweight getFlyweight(String key) {
Flyweight f = fsMap.get(key);
if (null == f) {
f = new AuthorizationFlyweight(key);
fsMap.put(key, f);
}
return f;
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* 安全管理,实现成单例
*/
public class SecurityMgr {
private static SecurityMgr securityMgr = new SecurityMgr();
private SecurityMgr() {}
public static SecurityMgr getInstance() {
return securityMgr;
}
private Map<String, Collection<Flyweight>> map = new HashMap<>();
public void login(String user) {
//登录时就需要把该用户所拥有的权限,从数据库中取出来,放到缓存中去
Collection<Flyweight> col = queryByUser(user);
map.put(user, col);
}
/**
* 判断某用户对某个安全实体是否拥有权限
* @param user
* @param securityEntity
* @param permit
* @return
*/
public boolean hasPermit(String user,String securityEntity,String permit) {
Collection<Flyweight> col = map.get(user);
if (null == col || 0 == col.size()) {
System.out.println(user+"没有登录或者是没有分配任何权限");
return false;
}
for (Flyweight fm: col) {
System.out.println("fm==" + fm);
if (fm.match(securityEntity,permit)) {
return true;
}
}
return false;
}
private Collection<Flyweight> queryByUser(String user) {
Collection<Flyweight> col =
new ArrayList<>();
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;
}
}
import java.util.ArrayList;
import java.util.Collection;
/**
* 模拟数据库的数据
*/
public class TestDB {
/**
* 用来存放授权数据的值
*/
public static Collection<String> colDB = new ArrayList<>();
static {
colDB.add("张三,人员列表,查看");
colDB.add("李四,人员列表,查看");
colDB.add("李四,薪资数据,查看");
colDB.add("李四,薪资数据,修改");
for (int i = 0; i < 3; i++) {
colDB.add("张三"+i+",人员列表,查看");
}
}
}
public class TestClient {
public static void main(String[] args) {
SecurityMgr mgr = SecurityMgr.getInstance();
mgr.login("张三");
mgr.login("李四");
boolean f1 = mgr.hasPermit("张三","薪资数据","查看");
boolean f2 = mgr.hasPermit("李四","薪资数据","查看");
System.out.println("f1=="+f1);
System.out.println("f2=="+f2);
for (int i = 0; i < 3; i++) {
mgr.login("张三" + i);
mgr.hasPermit("张三" + i, "薪资数据","查看");
}
}
}