您的位置:首页 > 编程语言 > Java开发

JAVA设计模式之享元模式

2012-12-07 07:52 399 查看
Java 设计模式 之 享元模式(Flyweight)

享元模式的重点在于分离变与不变。把一个对象的状态分成内部状态和外部状态,内部状态是不变的,外部状态是可变的。然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

内部状态:通常指的是包含在享元对象内部的、对象本身的状态,不会随享元环境而变化,因此可共享。

外部状态:是享元对象之外的状态,取决于使用享元的场景,会根据使用场景而变化,因此不可共享。如果享元对象需要这些外部状态的话,可以从外部传到外部状态中。

外部状态和内部状态是相互独立的,外部状态的变换不会因起内部状态的变化。

享元对象的优点:减少对象数量,节省内存空间。

享元模式的缺点:维护共享对象,需要额外的开销(用一个线程来维护垃圾回收)。

享元模式的本质:分离与共享。

何时使用享元对象:

● 如果一个应用程序使用了大量的细粒度对象,可以使用享元模式来减少对象数量。

● 如果使用大量的对象,造成很大的存储开销,可以使用享元模式来减少对象数量,并节约内存。

● 如果对象的大多数状态都可以转变为外部状态,可以使用享元对象来实现外部状态与内部状态的分离。

◆ Flyweight :享元接口,通过这个接口可以接受并作用于外部状态。通过这个接口传入外部的状态。

◆ ConcreteFlyweight :具体的享元实现对象,必须是可共享的,需要封装享元对象的内部状态。

◆ UnsharedConcreteFlyweight :非共享的享元实现对象,并不是所有的享元对象都可以共享,非共享的享元对象通常是享元对象的组合对象。

◆ FlyweightFactory :享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口。

样例:

/**

* 享元接口

*/

public interface Flyweight {

/**

* 判断传入的安全实体和权限,是否和享元对象内部状态匹配

* @param securityEntity

* @param permit

* @return

*/

public booleanmatch(String securityEntity, String permit);

}

/**

* 享元对象

*/

public classAuthorizationFlyweight
implementsFlyweight {

/**

* 内部状态,安全实体

*/

privateString securityEntity;

/**

* 内部状态,权限

*/

privateString permit;

publicAuthorizationFlyweight(String state) {

String ss[] = state.split(",");

this.securityEntity = ss[0];

this.permit = ss[1];

}

@Override

public booleanmatch(String securityEntity, String permit) {

if(this.securityEntity.equals(securityEntity) &&this.permit.equals(permit)){

return true;

}

return false;

}

publicString getSecurityEntity() {

returnsecurityEntity;

}

publicString getPermit() {

returnpermit;

}

}

/**

* 享元工厂,通常实现为单例

*

*/

public classFlyweightFactory {

private staticFlyweightFactory
factory= new
FlyweightFactory();

privateFlyweightFactory(){

}

public staticFlyweightFactory
getInstance(){

return factory;

}

/**

* 缓存多个Flyweight对象

*/

privateMap<String, Flyweight> fsMap =
newHashMap<String, Flyweight>();

/**

* 获取享元对象

* @param key

* @return

*/

publicFlyweight getFlyweight(String key) {

Flyweight f = fsMap.get(key);

if(f ==null){

f =new
AuthorizationFlyweight(key);

fsMap.put(key, f);

}

returnf;

}

}

/**

* 安全管理器,实现成单例

*

*/

public classSecurityMgr {

private staticSecurityMgr
securityMgr= new SecurityMgr();

privateSecurityMgr(){

}

public staticSecurityMgr
getInstance() {

returnsecurityMgr;

}

/**

* 在运行期间,用来存放登陆人员对应的权限

* 在Web应用中,这些数据通常存放到session中

*/

privateMap<String, Collection<Flyweight>> map =
new HashMap<String, Collection<Flyweight>>();

/**

* 登陆功能

* @param user

*/

public voidlogin(String user) {

Collection<Flyweight> col = queryByUser(user);

map.put(user, col);

}

/**

* 从数据库中获取某人所拥有的权限

* @param user

* @return

*/

privateCollection<Flyweight> queryByUser(String user) {

Collection<Flyweight> col =new
ArrayList<Flyweight>();

for(String s : TestDB.colDB){

String ss[] = s.split(",");

if(ss[0].equals(user)){

//ss[0] - user

//ss[1] - securityEntity

//ss[2] - permit

Flyweight fm = FlyweightFactory.getInstance().getFlyweight(ss[1]+","+ss[2]);

col.add(fm);

}

}

returncol;

}

/**

* 判断用户对某个安全实体是否拥有某种权限

* @param user 用户

* @param securityEntity 安全实体

* @param permit 权限

* @return

*/

public booleanhasPermit(String user, String securityEntity, String permit){

Collection<Flyweight> col = map.get(user);

if(col ==null
|| col.size() == 0){

System.out.println(user + "没有登陆或没有被分配任何权限");

return false;

}

for(Flyweight fm : col) {

System.out.println("fm == " + fm);

if(fm.match(securityEntity, permit)){

return true;

}

}

return false;

}

}

/**

* 测试使用,在内存中存放模拟数据库的值

*

*/

public classTestDB {

public staticCollection<String>
colDB= new
ArrayList<String>();

static{

colDB.add("张三,人员列表,查看");

colDB.add("李四,人员列表,查看");

colDB.add("李四,薪资列表,查看");

colDB.add("李四,薪资列表,修改");

for(inti = 0; i < 3; i++){

colDB.add("张三" + i + ",人员列表,查看");

}

}

}

public class Client {

public static voidmain(String[] args) {

SecurityMgr mgr = SecurityMgr.getInstance();

mgr.login("张三");

mgr.login("李四");

booleanf1 = mgr.hasPermit("张三", "薪资列表", "查看");

booleanf2 = mgr.hasPermit("李四", "薪资列表", "查看");

booleanf3 = mgr.hasPermit("张三", "人员列表", "查看");

System.out.println("f1 == " + f1);

System.out.println("f2 == " + f2);

System.out.println("f3 == " + f3);

for(inti = 0; i < 3; i++){

mgr.login("张三" + i);

mgr.hasPermit("张三" + i, "薪资列表", "查看");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: