翻译:Prototype-based programming 基于原型的编程
原文地址 http://en.wikipedia.org/wiki/Prototype-based_programming
Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is performed via a process of cloning existing objects that serve as prototypes. This model can also be known as class-less, prototype-oriented or instance-based programming.
基于原型的编程是面向对象编程的子系统和一种形式。在基于原型的编程中,类不是实时的,而且行为重用(通常认为继承自基于类的语言)是通过复制已经存在的原型对象的过程实现的。这个模型一般被认为是class-less,面向原型,或者是基于实例的编程。
The original (and most canonical) example of a prototype-based language is the programming language Self developed by David Ungar and Randall Smith. However, the classless programming style has recently grown increasingly popular, and has been adopted for the programming languagesJavaScript, Squeak (when using the Viewer framework to manipulate Morphic components), Cecil, NewtonScript, Io, MOO, REBOL and several others.
基于原型的语言最初的(也是最经典的)例子是程序语言Self,它是由David Ungar 和 Randall Smith开发的。但是classless编程方式最近变得越来越受欢迎,并且被JavaScript, Squeak (当使用观察者框架操作Morphic组件时), Cecil, NewtonScript, Io, MOO, REBOL还有一些其他的程序语言所采纳。
Contents 1 Comparison with class-based models 2 Object construction 3 Delegation 4 Concatenation 5 Criticism 6 Languages 7 References 8 Further reading 9 See also |
内容提要 1 与基于类的模型的比较 2 对象构造 3 委托 4 关联 5 评论 6 语言 7 引用 8 进一步读物 9 其他相关 |
Comparison with class-based models
与基于类的模型的比较
With class-based languages, objects come in two general types. Classes define the basic layout and functionality of objects, and instances are "usable" objects based on the patterns of a particular class. In this model, classes act as collections of behavior (methods) and structure that are the same for all instances, whereas instances carry the objects' data. The role distinction is thus primarily based on a distinction between structure and behavior on the one hand, and state on the other.
在基于类的编程当中,对象总共有两种类型。类定义了对象的基本布局和函数特性,而接口是"可以使用的"对象,它基于特定类的样式。在此模型中,类表现为行为和结构的集合,就接口持有对象的数据而言,对所有接口来说是相同的。区分规则因而首先是基于结构和行为,而后是状态。
Advocates of prototype-based programming often argue that class-based languages encourage a model of development that focuses first on the taxonomy and relationships between classes. In contrast, prototype-based programming is seen as encouraging the programmer to focus on the behavior of some set of examples and only later worry about classifying these objects into archetypal objects that are later used in a fashion similar to classes. As such, many prototype-based systems encourage the alteration of prototypes during runtime, whereas only very few class-based object-oriented systems (such as the first dynamic object-oriented system, Smalltalk) allow classes to be altered during the execution of a program.
基于原型编程的主张者经常争论说基于类的语言提倡使用一个关注分类和类之间关系开发模型。与此相对,基于原型的编程看起来提倡程序员关注一系列对象实例的行为,而之后才关心如何将这些对象划分到最近的使用方式相似的原型对象,而不是分成类。因为如此,很多基于原型的系统提倡运行时原型的修改,而只有极少数基于类的面向对象系统(比如第一个动态面向对象的系统,Smalltalk)允许类在程序运行时被修改。
Prototype-based programming is often associated with particular schools of thought in cognitive psychology which emphasize prototypes or exemplars as key attributes of the learning process.
基于原型的编程通常穿插在教授cognitive psychology的课程中,他强调prototypes 和 exemplars作为学习中的关键词。
While the vast majority of prototype-based systems are based around interpreted and dynamically typed programming languages, it is important to point out that statically typed systems based around prototypes are technically feasible. The Omega programming language discussed in Prototype-Based Programming [1] is an example of such a system, though according to Omega's website even Omega is not exclusively static but rather its "compiler may choose to use static binding where this is possible and may improve the efficiency of a program."
考虑到绝大多数基于原型的系统势基于解释性的和动态类型程序语言,这里要重点指出的是静态类型语言实现基于原型从技术上是可行的。用基于原型编程描述的Omega语言就是这样系统的一个例子。尽管根据Omega网站所述,Omega也不是完全的静态,但是可能的时候,它的编译器有时会使用静态绑定来改进程序的效率。
Object construction
对象构造
In class-based languages a new instance is constructed through the class's constructor and an optional set of constructor arguments. The resulting instance is modeled on the layout and behavior dictated by the chosen class.
In prototype-based systems there are two methods of constructing new objects, through cloning of an existing object, and through ex nihilo ("from nothing") object creation. While most systems support a variety of cloning, ex nihilo object creation is not as prominent.[2]
在基于类的语言中,一个新的实例通过类构造器和构造器可选的参数来构造,结果实例由类选定的行为和布局建立模型。在基于原型的系统中构造对象有两种方法,通过复制已有的对象 或者通过扩展nihilo(空的)对象创建,因为大多数系统提供了不同的复制方法,扩展nihilo对象的方式鲜为人知。
Systems that support ex nihilo object creation allow new objects to be created from scratch without cloning from an existing prototype. Such systems provide a special syntax for specifying the properties and behaviors of new objects without referencing existing objects. In many prototype languages, there is often a basic Object prototype that carries commonly needed methods and is used as a master prototype for all other objects. One useful aspect of ex nihilo object creation is to ensure that a new object's slot names do not have namespace collisions with the top-level Object object. (In the Mozilla JavaScript implementation, one can accomplish this by setting a newly constructed object's __proto__ property to null.)
提供 扩展nihilo对象创建 的系统允许对象从空白中创建而无需从已有的原型中复制。这样的系统提供特殊的文法用以指定新对象的行为和属性,无须参考已存在的对象。在很多原型语言中,通常有一个Object原型,其中有普遍需要的方法。它被用作所有其它对象的最终原型。扩展nihilo对象创建可以保证新对象不会被顶级对象的命名空间污染。(在Mozilla的JavaScript实现中,可以通过设置一个新创建对象的__proto__属性为null来做到.)
Cloning refers to a process whereby a new object is constructed by copying the behavior of an existing object (its prototype). The new object then carries all the qualities of the original. From this point on, the new object can be modified. In some systems the resulting child object maintains an explicit link (via delegation or resemblance) to its prototype, and changes in the prototype cause corresponding changes to be apparent in its clone. Other systems, such as the Forth-like programming language Kevo, do not propagate change from the prototype in this fashion, and instead follow a more concatenative model where changes in cloned objects do not automatically propagate across descendants.[3]
Cloning指一个新对象通过复制一个已经存在的对象(就是他的原型)来构造自己的过程。于是新的对象拥有原来对象的所有属性,从这一点出发新对象的属性可以被修改。在某些系统中,子对象持有一个到它原型的直接链接(经由授权或类似方式)。并且原型的改变同样会导致它的副本的变化。其他系统中,如类Forth的程序语言,Kevo在此情况下不传播原型的改变,而遵循一个更加连续的模型,其中被复制的对象改变不会通过他的副本传播。
Delegation
委托
In prototype-based languages that use delegation, the language runtime is capable of dispatching the correct method or finding the right piece of data simply by following a series of delegation pointers (from object to its prototype) until a match is found. All that is required to establish this behavior-sharing between objects is the delegation pointer. Unlike the relationship between class and instance in class-based object-oriented languages, the relationship between the prototype and its offshoots does not require that the child object have a memory or structural similarity to the prototype beyond this link. As such, the child object can continue to be modified and amended over time without rearranging the structure of its associated prototype as in class-based systems. It is also important to note that not only data but also methods can be added or changed. For this reason, most prototype-based languages refer to both data and methods as "slots".
在使用委托的基于原型的语言中,运行时语言可以仅仅通过循着一个序列的指针直到找到匹配这样的方式来定位属性或者寻找寻找正确的数据。所有这些 建立行为共享的行为 需要的是委托指针。不像是基于类的面向对象语言中类和借口的关系,原型和他的分支之间的关系并不要求子对象有相似的内存结构,因为如此,子对象可以继续修改和...而无须像基于类的系统那样整理结构。还有一个要提到的地方是,不仅仅是数据,方法也能被修改。因为这个原因,大多数基于类型的语言把数据和方法提作"slots"
Concatenation
关联
Under pure prototyping, which is also referred to as concatenative prototypes, and is exemplified in the Kevo language, there are no visible pointers or links to the original prototype from which an object is cloned. The prototype object is copied exactly, but given a different name (or reference). Behavior and attributes are simply duplicated as-is.
在纯粹的原型--又被称作concatenative原型——以Kevo语言为例——中 没有到被复制的原型对象的指针或链接。原型对象以重新给定名字(或引用)的方式被确实的复制了。这个过程类似于生物学上的分裂,属性和方法被原样复制。
Advantages to this approach include the fact that object authors can alter the copy without worrying about side-effects across other children of the parent. A further advantage is that the computational cost of method lookup during dispatch is drastically reduced when compared to delegation, where an exhaustive search must be made of the entire delegation chain before failure to find a method or slot can be admitted.
Disadvantages to the concatenative approach include the organizational difficulty of propagating changes through the system; if a change occurs in a prototype, it is not immediately or automatically available on its clones. However, Kevo does provide additional primitives for publishing changes across sets of objects based on their similarity (so-called family resemblances) rather than through taxonomic origin, as is typical in the delegation model.
这样做的好处包括对象的作者可以修改这份副本而无须担心对此父类的其他子类产生副作用。进一步的优点是查找属性运算的消耗同授权相比大大降低了,授权查找必须遍历整个委托链才能判定不存在。
Concatenative的坏处包括传播变化到整个系统的难度;如果一个变化作用到某个原型,它不会立即或者自动的对它的所有副本生效。然而Kevo提供了额外的在对象系统中传播变化的方式。这种方式是基于他们的相似性(所谓的family相似)而非像委托模型具有代表性的那样源自分类学。
Another disadvantage is that, in the most naive implementations of this model, additional memory is wasted (versus the delegation model) on each clone for the parts that have stayed the same between prototype and clone. However, it is possible to provide concatenative behavior to the programming while sharing implementation and data behind-the-scenes; such an approach is indeed followed by Kevo.[4].
An alternative quasi-solution to the problem of clones interfering with the behavior of the parent is to provide a means whereby the potential parent is flagged as being clonable or not. In MOO, this is achieved with the "f" flag. Only objects with the "f" flag can be cloned. In practice, this leads to certain objects serving as surrogate classes; their properties are kept constant to serve as initial values for their children. These children then tend to have the "f" flag not set.
另外一个坏处是在这个模型的大多数自然的实现下,每一个副本上都有额外的内存被浪费掉了(相对委托模型而言),因为副本和原型之间有相同的部分存在。然而,在共享的实现和后台数据中提供concatenative行为的编程编程是可行的。这种做法为Kevo所遵从。
Criticism
批评
Advocates of class-based object models who criticize prototype-based systems often have concerns that could be seen as similar to those concerns that proponents of static type systems for programming languages have of dynamic type systems (see Datatype). Usually, such concerns involve: correctness, safety, predictability, and efficiency.
那些经常批评基于原型系统的class-based对象模型的支持者通常有类似静态类型系统相对于动态类型系统的担心。通常这些担心是:正确性、安全性、可预测性以及效率。
On the first three points, classes are often seen as analogous to types (in most statically typed object-oriented languages they serve that role) and are proposed to provide contractual guarantees to their instances, and to users of their instances, that they will behave in some given fashion.
在前三点上,类可以看作和类型等效(多数静态语言遵守此规则)而且提供保证他们实例的契约,而对这些实例的使用者保证特定场景中的行为。
On the last point, efficiency, the declaration of classes simplifies many compiler optimizations that allow developing efficient method and instance variable lookup. For the Self language, much development time was spent on developing, compiling, and interpreting techniques to improve the performance of prototype-based systems versus class-based systems. For example, the Lisaac compiler produces code almost as fast as C. Tests have been run with an MPEG-2 codec written in Lisaac, copied from a C version. These tests show the Lisaac version is 1.9% slower than the C version with 37% fewer lines of code[5]. However, the C programming language is not a class-based object-oriented language, but rather a procedural language. A Lisaac to C++ comparison would be more appropriate.
在最后一点上,效率,类的声明简化了编译器的组织,允许开发高效的方法以及实例变量查找。对Self语言来说,大多开发时间都消耗在开发、编译以及解释技术用以改进基于原型的系统相对于基于类的系统。举例来说Lisaac产生的代码速度几乎跟C一样快。测试是由MPEG-2编码器的Lisaac版本得出的,它由一个C语言版本复制而来。测试显示,Lisaac版本比C版本慢1.9%,但代码行数少了37%。然而C语言并非面向对象语言,而是一个过程式语言。Lisaac跟C++版本相比可能更说明问题。
The most common criticism made against prototype-based languages is that the community of software developers is not familiar with them, despite the popularity and market permeation of JavaScript. This knowledge level of prototype based systems seems to be changing with the proliferation of JavaScript frameworks and increases in the complex use of JavaScript as "Web 2.0" matures.
Possibly because of these reasons, work on a fourth edition of the ECMAScript standard seeks to provide JavaScript with class-based language constructs. It is worth noting that according to this specification, the prototype for an object still exists when traditional class based syntax is used.
最普遍的对基于原型的语言的批评来自不喜欢它的软件开发者社区,尽管有JavaScript的人气和市场。对基于原型系统的了解程度似乎因为JavaScript框架的广泛应用以及JavaScript针对Web2.0的复杂应用而改变。很可能由于这些原因,在ECMAScript标准的第四版开始寻求令JavaScript提供基于类的构造。根据标准定义来看,它毫无用处。用传统的基于类的语法构造的对象仍然存在原型。(译者:这两句骂得好,es4去死吧!)
Languages
语言
Actor-Based Concurrent Language (ABCL): ABCL/1, ABCL/R, ABCL/R2, ABCL/c+
ActionScript (Used by Adobe Flash and Adobe Flex)
JavaScript (first named Mocha, then LiveScript)
Perl, with the Class::Prototyped module
Squeak when using the Viewer framework to manipulate Morphic components
References
引用
- ^ Section 2.8 (pg.177). Günther Blaschek, Omega: Statically Typed Prototypes
- ^ Section 1.2 (pg.17). Chistophe Dony, Jacques Malenfan, Daniel Bardou, Classifying Prototype-based Programming Languages
- ^ Section 1.1 (pg.14). Antero Taivalsaari, Classes vs. Prototypes: Some Philosophical and Historical Observations
- ^ Antero Taivalsaari. Kevo, a prototype-based object-oriented programming language based on concatenation and module operations. Technical Report Report LACIR 92-02, University of Victoria, 1992.
- ^Isaac project benchmarks. Retrieved on 2007-07-24.
Further reading
进一步阅读
Wikibooks' [[wikibooks:|]] has more about this subject:
Computer programming/Object oriented programming
(1999) in James Noble (ed.), Antero Taivalsaari (ed.), Ivan Moore (ed.): Prototype-Based Programming: Concepts, Languages and Applications. Springer-Verlag. ISBN 981-4021-25-3.
Abadi, Martin; Luca Cardelli. A Theory of Objects. Springer-Verlag. ISBN 0-387-94775-2.