论坛首页 Java企业应用论坛

delegation(委托) vs. composition(复合) ?

浏览 9393 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-07-08  
在《efficient java》中第14条:复合优先于继承。这条规则本身比较容易理解,在这条规则中,有这么一段代码:
public class InstrumentedSet implements Set {

    private final Set s;

    private int addCount = 0;

    .....

    public InstrumentedSet(Set s); {

        this.s = s;

    }

    ....

    // Forwarding methods

    public void clear();                 { s.clear();; }

    public boolean contains(Object o);   { return s.contains(0);; }

    public boolean isEmpty();            { return s.isEmpty();; }

    public int size();                   { return s.size();; }

    .......

}


这段代码很清楚,典型的复合(composition)和转发(forwarding),但是他(Joshua Bloch)还提到如下两点:

[list=1]
  • 有时,复合(composition)和转发(forwarding)这两项技术的结合被错误地引用为“委托(delegation)”
  • 从技术的角度而言,这不是委托(delegation),除非包装对象把自己(InstrumentedSet)传递给一个被包装的对象(Set)
  • [/list:o]

    我以前一直认为像上面那段代码(Decorator Pattern)也可以叫作delegation,但并非如此,很显然两者的概念不同,上面的只能算作复合(composition)和转发(forwarding)。

    不知道大家对这两者是如何理解的?那究竟如何才算是delegation?
       发表时间:2004-07-08  
    Bloch的那句话是从GOF那本书上的描述得来的,关键词就是“pass”:
    Delegation
    Delegation is a way of making composition as powerful for reuse as inheritance [Lie86, JZ91]. In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate. This is analogous to subclasses deferring requests to parent classes. But with inheritance, an inherited operation can always refer to the receiving object through the this member variable in C++ and self in Smalltalk. To achieve the same effect with delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver

    接着GOF那本书上说:
    Several design patterns use delegation. The State (305), Strategy (315), and Visitor (331) patterns depend on it

    于是我查看了这几个模式的例子的实现代码,发现了的确是如Bloch所说的那样。按照这个理解,对于你举的那个例子而言,InstrumentedSet应该把自己的对象传入到Set中去才算委托吧。

    The main advantage of delegation is that it makes it easy to compose behaviors at run-time and to change the way they're composed

    不过我个人觉得,除非是做学问,实用的时候这些概念上的细节不用分的那么清楚吧,什么用的更有效更简单就用什么,不在乎用什么名字的模式吧。
    0 请登录后投票
       发表时间:2004-07-08  
    mochow 写道
    Bloch的那句话是从GOF那本书上的描述得来的,关键词就是“pass”:
    Delegation
    Delegation is a way of making composition as powerful for reuse as inheritance [Lie86, JZ91]. In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate. This is analogous to subclasses deferring requests to parent classes. But with inheritance, an inherited operation can always refer to the receiving object through the this member variable in C++ and self in Smalltalk. To achieve the same effect with delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver


    又琢磨了一阵子,发觉自己对于委托与被委托者到底是谁有些糊涂了,被绕进去了,于是再细化一下我的理解,不知道对不对:
    基本概念:
    delegation模式中有两个角色:
    接受请求的角色:这里简称请求接受者,我的理解是InstrumentedSet
    代理操作的角色:这里简称为代理者,例子中是Set

    在委托方式下,请求者和代理者共同参与处理一个请求,请求接受者将操作委托给代理者来处理。

    如果上述理解是正确的话,那么:
    GOF的那段话可以理解为:请求接受者将自己(对象)传给代理者,使代理者可以通过该对象执行那些委托的操作。也即InstrumentedSet要将自己的对象传到Set的对象中去。
    如果由此来判断是否为delegation模式的话,那么楼主的例子的确不是委托模式。
    0 请登录后投票
       发表时间:2004-07-08  
    mochow 写道

    不过我个人觉得,除非是做学问,实用的时候这些概念上的细节不用分的那么清楚吧,什么用的更有效更简单就用什么,不在乎用什么名字的模式吧。


    说得不错。只是当我看到这儿的时候,突然有点惊诧:自己竟然把概念给理解错了。

    我从What Is Delegation上找到了一些资料:

    [list=1]
  • Let me state a theory: polymorphic behavior is always delegation of some sort, and thus delegation (to impliment polymorphism) always has a layer of indirection. Please find a problem here, so we can make this more succinct/correct, or dis/prove it.

  • Lets also try to say what delegation is NOT.

    From my above theory, a simple subroutine may have responsibility for the computation of some part of a program, but a subroutine call is not delegation because it is direct. It lacks a layer of indirection. A function-pointer IS however, since it can point to any function, and the decision of what function it points to must already have been made when it is dereferenced and called. Even a switch/case statement can be delegation, provided it adds a layer of indirection.

    So what does OO and polymorphic behavior have to do with delegation, if delegation is such a simple, ubiquitous thing? Perhaps this is the real core of the matter. OO is about resolving polymorphic behavior by delegating to objects.
  • Better yet: delegation is done by the caller, while indirection is a function of (dispatch to) the callee
  • [/list:o]

    按照上面的定义,在delegate和delegatee之间必须有一层indirection。画个简单的示意图:
    1:
    A --> B
    
    2:
    delegate -----> delegatee
         ^                  |
         |   indirection    |
         --------------------
    


    part1
    
    delegateA {
       delegateeB b;
      
       void methodA(); { b.methodB();;}
    }
    
    delegateeB {
         void methodB(); {}
    }
    
    

    上面的代码就不是delegation,而是composition,因为直接调用了delegatee的方法,这只是forwarding methods。

    part2
    
    delegateA {
        delegateeB b;
    
         void methodA(); { b.methodB(this);; }   
         void  do(); {}
    }
    
    delegateeB {
         void methodB(delegateA a); { a.do();; }
    }
    

    part2好像又回到了part1,其实不然,delegate已经把自身pass给了delegatee,并且delegatee调用了delegate的方法,这就是一种indirection。

    在现实世界中,假如董事长A把权利授权给总经理B,总经理B一定会获取董事长A才拥有的权利,它会利用这些权利来替公司做事。这才是真正的delegation,也就是说delegatee一定会调用delegate的某些方法,因此你首先得把delegate传递给delegatee。
    0 请登录后投票
       发表时间:2004-08-26  
    后山的解释不错,委派的方法可以用来
    处理权限控制,这是他天然的优势,
    使代码更合理
    0 请登录后投票
    论坛首页 Java企业应用版

    跳转论坛:
    Global site tag (gtag.js) - Google Analytics