这是一个Decorator模式例子的简单的三个文件
我们先建立一个接口:
public interface Work { public void insert();
}
接口Work有一个具体实现:插入方形桩或圆形桩,这两个区别对Decorator是无所谓.我们以插入方形桩为例:
public class SquarePeg implements Work{ public void insert(){ System.out.println("方形桩插入"); } }
现在有一个应用:需要在桩打入前,挖坑,在打入后,在桩上钉木板,这些额外的功能是动态,可能随意增加调整修改,比如,可能又需要在打桩之后钉架子(只是比喻).
那么我们使用Decorator模式,这里方形桩SquarePeg是decoratee(被刷油漆者),我们需要在decoratee上刷些"油漆",这些油漆就是那些额外的功能.
public class Decorator implements Work{
private Work work; //额外增加的功能被打包在这个List中 private ArrayList others = new ArrayList();
//在构造器中使用组合new方式,引入Work对象; public Decorator(Work work) { this.work=work; others.add("挖坑");
others.add("钉木板"); }
public void insert(){
newMethod(); }
//在新方法中,我们在insert之前增加其他方法,这里次序先后是用户灵活指定的 public void newMethod() { otherMethod(); work.insert();
}
public void otherMethod() { ListIterator listIterator = others.listIterator(); while (listIterator.hasNext()) { System.out.println(((String)(listIterator.next())) + " 正在进行"); }
}
}
好了,Decorator模式出来了,客户端也的代码:
Work squarePeg = new SquarePeg(); Work decorator = new Decorator(squarePeg); decorator.insert();
在ForumPermissions中定义了各种级别权限的用户:
public class ForumPermissions implements cacheable { /** * Permission to read object. */ public static final int READ = 0;
/** * Permission to administer the entire sytem. */ public static final int SYSTEM_ADMIN = 1;
/** * Permission to administer a particular forum. */ public static final int FORUM_ADMIN = 2;
/** * Permission to administer a particular user. */ public static final int USER_ADMIN = 3;
/** * Permission to administer a particular group. */ public static final int GROUP_ADMIN = 4;
/** * Permission to moderate threads. */ public static final int MODERATE_THREADS = 5;
/** * Permission to create a new thread. */ public static final int CREATE_THREAD = 6;
/** * Permission to create a new message. */ public static final int CREATE_MESSAGE = 7;
/** * Permission to moderate messages. */ public static final int MODERATE_MESSAGES = 8;
.....
public boolean isSystemOrForumAdmin() { return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]); }
.....
}
因此,Forum中各种操作权限是和ForumPermissions定义的用户级别有关系的,作为接口Forum的实现:ForumProxy正是将这种对应关系联系起来.比如,修改Forum的名称,只有论坛管理者或系统管理者可以修改,代码如下:
public class ForumProxy implements Forum {
private ForumPermissions permissions; private Forum forum; this.authorization = authorization;
public ForumProxy(Forum forum, Authorization authorization, ForumPermissions permissions) { this.forum = forum; this.authorization = authorization; this.permissions = permissions; }
.....
public void setName(String name) throws UnauthorizedException, ForumAlreadyExistsException { //只有是系统或论坛管理者才可以修改名称 if (permissions.isSystemOrForumAdmin()) { forum.setName(name); } else { throw new UnauthorizedException(); } }
...
}
而DbForum才是接口Forum的真正实现,以修改论坛名称为例:
public class DbForum implements Forum, cacheable { ...
public void setName(String name) throws ForumAlreadyExistsException {
....
this.name = name; //这里真正将新名称保存到数据库中 saveToDb();
.... }
...
}
凡是涉及到对论坛名称修改这一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy决定是否有权限做某一样事情,ForumProxy是个名副其实的"网关","安全代理系统".
在平时应用中,无可避免总要涉及到系统的授权或安全体系,不管你有无意识的使用Proxy,实际你已经在使用Proxy了.
我们继续结合Jive谈入深一点,下面要涉及到工厂模式了,如果你不了解工厂模式,请看我的另外一篇文章:设计模式之Factory
我们已经知道,使用Forum需要通过ForumProxy,Jive中创建一个Forum是使用Factory模式,有一个总的抽象类ForumFactory,在这个抽象类中,调用ForumFactory是通过getInstance()方法实现,这里使用了Singleton(也是设计模式之一,由于介绍文章很多,我就不写了,看这里),getInstance()返回的是ForumFactoryProxy.
为什么不返回ForumFactory,而返回ForumFactory的实现ForumFactoryProxy? 原因是明显的,需要通过代理确定是否有权限创建forum.
在ForumFactoryProxy中我们看到代码如下:
public class ForumFactoryProxy extends ForumFactory { protected ForumFactory factory; protected Authorization authorization; protected ForumPermissions permissions;
public ForumFactoryProxy(Authorization authorization, ForumFactory factory, ForumPermissions permissions) { this.factory = factory; this.authorization = authorization; this.permissions = permissions; }
public Forum createForum(String name, String description) throws UnauthorizedException, ForumAlreadyExistsException { //只有系统管理者才可以创建forum if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) { Forum newForum = factory.createForum(name, description); return new ForumProxy(newForum, authorization, permissions); } else { throw new UnauthorizedException(); } }
由上面可以找到两个共同点为
1.两个实现类都派生于同一个接口 2.其中一个实现类引用了另一个实现类,并作了功能的增加
|
|