委托 (面向对象程序设计)

面向对象程序设计中的委托是指使用另一个对象(发送者)的上下文,对一个对象(接收者)的成员(属性方法)求值。通过把发送者对象传递给接收者对象,任何面向对象语言都可以做显式的委托。如果语言特性支持成员查询规则,则可以做隐式的委托。隐式委托是基于原型编程中行为重用的基本方法,对应于基于类编程继承。支持委托的最知名语言是SelfJavaScript

术语委托在两个对象之间还有别的用法。见委托 (编程)。最容易混淆的是在接收者的上下文中,与发送者成员对应的接收者成员被求值,精确地说这是转发(即包装者对象(wrapper object)并不把自身传递给被包装对象(wrapped object))。[1][2][lower-alpha 1]简单地使用另一个对象,这是对象聚合委托模式软件设计模式中实现委托的一种套路。

概述

1986年,MIT計算機科學與人工智慧實驗室亨利·利伯曼首创发表了基于原型编程、利用方法查询规则的面向对象的委托等技术和概念。[3]

委托依赖于动态绑定,因为它需要一个给定的方法可以在不同的运行时上下文中被调用。这可以用于操作系统提供单独一个类管理各个窗口。例如,当用户点击close box, 窗口管理器发送委托:windowShouldClose调用;如果根据窗口的上下文有未保存数据,委托会延迟关闭这个窗口。

不同于转发,委托可以被刻画为自身的迟绑定:[4]

... messages sent to the self (or this) variable in the parent will "come back" to the object that originally received the message.

也就是说,接收对象的一个方法定义中的self并不是静态绑定到定义时的那个对象,而是在求值时才绑定到“最初”的对象。

有观点认为委托优于继承,使程序代码更为可多、可理解。[5]有观点认为委托和继承是等价的,但也有认为一个是另一个特例。[6]

语言支持

使用类似于C#/Java的伪代码的示例:

class A {
  public void foo() {
    // "this" also known under the names "current", "me" and "self" in other languages
    this.bar();
  }

  void bar() {
    Console.WriteLine("a.bar");
  }
};

class B {
  private delegate A a; // delegation link

  public B(A a) {
    this.a = a;
  }

  public void foo() {
    a.foo(); // call foo() on the a-instance
  }

  public void bar() {
    Console.WriteLine("b.bar");
  }
};

a = new A();
b = new B(a); // establish delegation between two objects
b.foo();  
b.bar();

调用b.foo()将打印b.bar, 因为在a的上下文中this引用到最初的接收者对象bthis的结果的二义性被称作object schizophrenia

把隐式的this翻译为显式参数,调用(在B中, a是个委托) a.foo()翻译为A.foo(b),使用a类型做方法的查询解析, 但调用委托的对象b作为this实参。

使用继承,类似代码为:

class A {
  void foo() {
    this.bar();
  }

  void bar() {
    print("A.bar");
  }
};

class B extends A {
  public B() {}

  void foo() {
    super.foo(); // call foo() of the superclass (A)
  }

  void bar() {
    print("B.bar");
  }
};

b = new B();

调用b.foo()的结果为B.bar. 其中this.bar()解析为子类的方法.

注释

  1. Beck 1997 uses the terms "simple delegation" for when the receiving object does not have access to the sending object, and "self delegation" for when the receiving object does have access to the sending object; in modern language these are "forwarding" and "delegation", as used in this article.

参考文献

  1. Gamma et al. 1995,"Delegation", pp. 20–21.
  2. Beck 1997,"Delegation", pp. 64–69.
  3. Lieberman, Henry. . 21. Portland. 1986: 214–223 [2022-04-15]. ISSN 0362-1340. doi:10.1145/960112.28718. (原始内容存档于2021-09-04). |journal=被忽略 (帮助); |issue=被忽略 (帮助)
  4. . . : 38.
  5. 页面存档备份,存于Trygve Reenskaug, Dept. of Informatics, University of Oslo, "The Case for Readable Code" (2007)
  6. Stein, Lynn Andrea. . OOPSLA '87 Conference proceedings on Object-oriented programming systems, languages and applications: 138–146. doi:10.1145/38807.38820.
  • Lieberman, Henry. . 21. Portland. 1986: 214–223 [2022-04-15]. CiteSeerX 10.1.1.48.69可免费查阅. doi:10.1145/960112.28718. (原始内容存档于2021-09-04). |journal=被忽略 (帮助); |issue=被忽略 (帮助)
  • Lynn Andrea Stein, Henry Liberman, David Ungar: A shared view of sharing: The Treaty of Orlando. In: Won Kim, Frederick H. Lochovsky (Eds.): Object-Oriented Concepts, Databases, and Applications ACM Press, New York 1989, ch. 3, pp. 31–48 ISBN 0-201-14410-7 (online at Citeseer页面存档备份,存于))
  • Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. . Addison-Wesley. 1995. ISBN 978-0-201-63361-0.
  • Malenfant, J.: On the Semantic Diversity of Delegation-Based Programming Languages, Proceedings of the OOPSLA95, New York: ACM 1995, pp. 215–230.
  • Beck, Kent. . Prentice Hall. 1997. ISBN 978-0134769042.
  • Kasper Bilsted Graversen: The nature of roles---A taxonomic analysis of roles as a language construct. Ph.D. Thesis 2006, (Online at IT University of Copenhagen)

外部链接

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.