JiveJdon Community Forums
在线286人   首页   主题总表   培训咨询   精华   查搜   注册    登陆
首页 » 论坛 » 设计模式、框架和架构
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表
???en_US.forumThreadNext.name??? 下一主题
Go 总共有 5 回复 / 1
 发表新帖子   回复该主题贴
thy3368

悄悄话
发表文章: 9
注册时间: 2003年10月21日 16:30
Decorator模式有代理的味道 2004年02月03日 17:26 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
标签列表 decorator模式(12)     
这是一个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.其中一个实现类引用了另一个实现类,并作了功能的增加




cats_tiger

悄悄话
发表文章: 185
注册时间: 2003年05月16日 16:58
Re: Decorator模式有代理的味道 2004年02月10日 10:26 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Decorator和Proxy在实现手法上确有类似之处。但是模式的含义和目的大相径庭。
kewan

悄悄话
发表文章: 46
注册时间: 2003年04月20日 19:11
Re: Decorator模式有代理的味道 2004年02月17日 01:10 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
如果说代理是一种Decorator,我觉得更恰当一些。

在代理模式中,可以附加一些全县控制功能。这其实就是Decorator。
yycjava

悄悄话
发表文章: 3
注册时间: 2003年08月02日 22:40
Re: Decorator模式有代理的味道 2004年02月21日 00:01 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我同意你的观点,把思维再抽象一些就会发现Proxy就是Decorator的一个特例。
pikachu

悄悄话
发表文章: 7
注册时间: 2004年02月21日 11:25
Re: Decorator模式有代理的味道 2004年02月21日 11:56 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
不能这样解释的吧?
先想想现实中的代理。上网为什么要用proxy?因为我无法直接访问到我的目的地!
那么现实中的decorator是什么?可能,页面的重定向比较类似。我们要先访问某个页面,结果先访问到了一个特殊的页面(可能是广告,可能是通知,等等),然后被重定向到需要的页面。

所以,proxy的主要功能是,替你访问到你不能直接访问的资源。这个在分布式开发中运用比较多。
decorator的功能是在你访问某个资源之前,先送你一套附加的功能(买一送一?)

当然proxy和decorator有一个共同的特点,他们都需要设计一个类从某个interface继承下来再转掉实际功能。

所以proxy和decorator只是形似,而神不似。
kewan

悄悄话
发表文章: 46
注册时间: 2003年04月20日 19:11
Re: Decorator模式有代理的味道 2004年02月24日 00:19 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
你对Proxy的理解还是稍微狭隘了一点。Proxy可用在用户不能直接到达的情况下,但还有一种情况,我不想让你直接到达,比如:防火墙。在这里,代理就泛化了。你甚至可以看成是一个拦截器,过滤器,何况是Decorator。看模式不必拘泥于一点,大可以想开了去。
这个主题有 5 回复 / 1Go
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表    返回页首返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache 缓存 DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Seam Spring Struts
正在读取,请等待...
google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘 博采网摘
查询本论坛内 回复超过的热门帖子
     回复该主题贴
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 

手机阅读 add to google add to yahoo
解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com
anti spam