CSC/ECE 517 Fall 2010/ch2 2c ck: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(108 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Prototype Based Inheritance =
<div class="usermessage hideme" align="center" style="font-size:16pt"><b>Prototype Based Object Oriented Design</b></div>
== Introduction ==
== Introduction ==
Dictionary Definition: An original, full-scale, and usually working model of a new product or new version of an existing product. [1] <br/>
Dictionary Definition of Prototype: 'An original, full-scale, and usually working model of a new product or new version of an existing product'.<sup>[1]</sup> <br/><br/>
In Object Oriented Programming (OOP) the term "Prototype" refers a fully working model of new version of an existing object.<br/>
"... the prototype approach in some ways corresponds more closely to the way people seem to acquire knowledge from concrete situations"<sup>[2]</sup> <br/><br/>
The mechanism for implementing prototyping is called Delegation.[2]<br/>Delegation is a process whereby an existing object dynamically searches for properties and methods first within itself, then if an match is not found, it delegates that search to its parent object. The parent then repeats the exact same delegation process until a match is found. Once a match is found the result is returned to the requester. <br/>
Since the early period of implementation of Object Oriented Design (OOD), there have been two schools of thought concerning the best method of implementing OOD. The class approach, which is the static method of implementation. And the Prototype approach, which is the dynamic method of implementation.<br/>
==Contracting Approaches==
<br/>
The class based implementation of OOD is very rigid and favors a design first approach. The prototype based implementation of OOD favors a design as we go or iterative approach.
<br/>
<br/>
This article assumes that the reader is familiar with class based object oriented design and will focus mostly on the specifics of prototype based object oriented design. In doing so, we will also contrast the differences between the two and try to determine what is in the future.
 
==Brief History==
Even though the prototype implementation of OOD has been around for a long time, it took a very long time to reach the mainstream development community. The purest form was in a language called Self<sup>[3]</sup>. Self, was created in 1986 as a project at Sun Labs. It was one of the first languages to support prototyping and it was built entirely from the ground up using prototypes. In 1995 version 4 was released and Sun culminated it as a project. Even though it is no longer an official project at Sun Labs, Sun Labs stills ports version 4 to keep it runing on several OS's. It is now at version 4.4.<br/>
<br/>
Prototype OOD reached the mainstream development community when the internet became popular and it was adopted by ECMAScript(JavaScript) as their OOD environment in 1997.<sup>[4]</sup> and also in Adobe Flash Action Script. There was a lot of speculation that version 4.0 of ECMAScript would have traditional classes instead of or in addition to prototyping, however verion 4.0 was never realeased. When version 5.0 of ECMAScript.<sup>[5]</sup> was released in December 2009,  prototyping still existed as the only OOD that was to be supported.<br/>
<br/>
Even some class based languages, such as C# <sup>[6]</sup> in particular and several others in general, implemented a variation of prototyping called extensions. 'Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.' .<sup>[6]</sup>. While this does not have all of the features that a prototyping language does, it shows the influence that prototype OOD has had on many of the main stream languages in use today.<br/>
 
== Delegation ==
The mechanism for implementation of prototyping is called Delegation.<sup>[2]</sup><br/>
<br/>
'Operationally, delegation is the redirection of field access and method invocation from an object or prototype to another, in such a way that an object can be seen as an extension of another.'&nbsp<sup>[7]</sup><br/>
<br/>
Delegation is a process whereby an existing object dynamically searches for properties and methods first within itself, then if an match is not found, it delegates that search to its parent object. The parent then repeats the exact same delegation process until a match is found. Once a match is found the result is returned to the requester. <br/><br/>
'''Simple Example'''<br>
This example demonstrates two objects that I always want aligned on the same y axis, however I want them to be independent on the x axis.<br/>
[[Image:ch2ckdelegation1.jpg]]<br/>
Box remains as is but Point is changed<br>
[[Image:Ch2ckdelegation2.JPG]]<br/>
'''NOTE:''' In the above example Box.GetPoint() would also return [10,10]. When GetPoint() searches for X it starts at the original requestors level and uses delegation just like the method search for Box.GetPoint().<br><br/>
While delegation is simple in its design, we will see that it is also elegant. In that it opens the door for several different techniques which allow software developers to morph an existing object, into a much larger and more robust object. While still retaining the original objects simplicity.
 
==Competing Approaches==
===Class Approach===
===Class Approach===
New objects are made from classes. The class definition must exist to create a class. When a class is changed existing objects must be reconstructed and we need to ensure that nothing needs the prior constructed behavior.<br/>
New objects are made from predefined classes. A class definition must exist to create an instance of a class. When a class is changed, existing objects must be reconstructed and we also need to ensure that nothing else in the application requires the prior classes constructed behavior.<br/>
===Prototype Approach===
===Prototype Approach===
New objects are constructed by copying an existing object. After copying we are safe to change the class behavior knowing that we are independent of all other objects. Prototyping is dynamic allowing us to create a real world object as a single instance and then refactor it at run time. We can add to it and also breaking parts out of it. In its intirety the parts that we broke out can be added in to a different object in the same delegation tree thereby.
New objects are constructed by copying an existing object. After copying we are safe to change the class behavior knowing that we are independent of all other objects. Prototyping is dynamic allowing us to create a real world object as a single instance and then refactor it at run time.<br>
* We can add to it.<br/>
* We can remove parts from it.<br/>
* We can break parts out and move to a different location in the same delegation tree. Thereby extending the original behavior to more objects in the same object hierarchy.<br/>


==Origin==
"... the prototype approach in some ways corresponds more closely to the way people seem to acquire knowledge from concrete situations" [2] <br/>
The prototype behaviour was first defined in the language Self.
In Self all objects are prototypes.


==Extensions==
Some static class based computer languages use the term extension or method extension. [3]
This is very similar in function to dynamic OOP's prototype. <br/>
However, extensions must exist before an object is created and are therefore still rigid in design. Extensions are lacking the flexibility that dynamic prototyping provides.<br/>
Also as we will see, some dynamic languages use prototyping to support dynamic inheritance and multi-inheritance. This is a level beyond the facilities that extensions provide.


==Contrasting Development Styles==
==Contrasting Development Styles<sup>[7]</sup>==
===Class Based===
{| class="wikitable" cellpadding="3" width="100%"
Must think about object abstractly and develop a model before experimenting with it.
|+
!Class Development Style
!Prototype Development Style
|+
|Must think about objects abstractly and develop a model to simulate behavior
|Most people can think clearly about objects that already exist
|+
|Many people lack the ability to perform well when working with abstract thoughts
|Most people have the ability to perform well when working with real world objects
|+
|Good communication is limited to those that can think abstractly
|Good communication is open to normal methods of everyday interaction
|+
|Real world examples need to be broken down to a model and then reconstructed before they can be worked with
|Real world examples can be worked with in real time, there is no need to model behavior
|}


===Prototype based===
==Analysis<sup>2</sup>==
May think about object concretely.
===Advantages of Prototype===
*Reduces development time.<br/>
*Reduces development costs.<br/>
*Developers receive quick results and can move on to the next task.<br/>


==Analysis==
===Advantages of Prototype===
Reduces development time.
Reduces development costs.
Developers receive quick results and can move on to the next task.
===Disadvantages of Prototype===
===Disadvantages of Prototype===
Can lead to insufficient analysis.
*Can lead to insufficient analysis.<br/>
The performance may be degraded by prototype overhead.
*The performance may be degraded by prototype overhead.<br/>
Can cause systems to be left unfinished and/or implemented before they are ready.
*Can cause systems to be left unfinished and/or implemented before they are ready.<br/>
Sometimes leads to incomplete documentation.
*Sometimes leads to incomplete documentation.<br/>


== Real World Example ==
==Prototype Inheritance==
As we will see, some dynamic languages use prototyping to support dynamic inheritance and multi-inheritance. <br/> All object inheritance is initially copied from an existing object, then when additional functionality is desired, inheritance may be added at runtime via delegation. <br>
The biggest design benefit of prototype inheritance is that inheritance functionality may be added anywhere within the existing objects class tree. It may be added to (or removed from) the end, the beginning, or anywhere in the middle. It is very flexible and powerful.


Model a bank account
==Real World Example==
A bank account


===Class Approach===
===Class Approach===
Start with use cases:
Focus of thought is constantly changing:
  As a customer I need to be able to view my balance.
#Start with use cases<br/>
  As a customer I need to be able to deposit money into my account.
#Create a class diagram<br/>
  As a customer I need to be able to withdrawl from my account.
#Write Code<br/>
  As a customer I need to be able to transfer funds between my accounts.
#Experiment<br/>
  As a teller I need to be able to view the balances off all accounts for a given customer.
#Modify class diagram<br/>
  As a teller I need to be able to see all tracnactions this customer has made in the past.
#Refactor<br/>
  As a teller I need to be able to modify a transaction amount that a customer has proven is invalid.
#Write Code<br/>
#Rewrite code that depended on the functionality removed from prior class diagram.
#Goto step 4<br/>


===Prototype Approach===
===Prototype Approach===
  Lets just build a back account object
Lets just build a bank account object and code it right now.<br/>
      Account number    abc123
[[Image:Ch2ckAccount1.JPG]]<br/>
      balance    12
Now I can show it to other people and get their inputs.<br/>
      Deposit(value) if(value>=0) balance += deposit else raise InvalidDepositError
<pre>
      Withdrawl(value)  if(balance >=withdawal) balance-=withdrawl else raise InsufficientFundsError
I show my account to Mary and she interacts with it.
      balance()  balance
Mary says that she has several accounts and often transfers money between them.
  Now I can show it to other people and get their inputs.
      I show my account to Mary and she interacts with it.
      Mary says that she has several accounts and often transfers money between them.
      I add the following to my account object.
        transfer from(account, value)
        transfer to(account, value)
      I show the new account object to Bill who is a teller and bill says that he need to see all of the customers transactions because sometimes he is asked a question about a particular transaction.
      Bill also says that if management approves the dispute, he needs to be able to modify a prior transaction.
      I add the following to my account object:
        TransactionHistory [[date location amount],[date location amount],[date location amount]]   
        DisplayTransactionHistory()
        Add Transaction(datetime, location, amount)
        AdjustTransaction(datetime, location, new amount)
      I show the latest account object to Joe who works in the ATM industry.
      Joes says that he needs to be able to transfer amount between my account and an account on another computer automously.
      Joes also says that there is a daily withdrawl limit on all ATM withdrawls and that ATM balances are not updated until the they are verified.
      I add the following to my account object:
        PinNumber
        ATMWithdrawlLimit
        ATMWithdrawlTotal
        TransferAmountNotVerified
        MyIP
        MyPort
        transfer to(account, value, IP, Port)
        receive from(account, value, IP, Port)
     
      I show the latest account object to my friend Candi.
      Candi says that sometimes she would like to give her daughter a card that accesses her account for cash withdrawls but with a very low daily withdrawl limit.
        ATMWithdrawlLimits[[[Pin,Amount],[Pin,Amount],[Pin,Amount]]
UserNames[[Pin, Name], [Pin, Name], [Pin, Name]]
        UserName(Pin)
      Now I have an awesome account object, but I only have one.
      Gee I need a way to copy this object so that I can give accounts to all of my friends.
   
      I then add the following:
        Clone()


      Now I decide that I would like some accounts to maybe not be accessable via ATM. The problem is that my clone method was added last.
I add the following to my account object.
      I would really like everything to inherit from clone so that I can make a copy of any of the above extenstions and not carry all of the overhead.
  TransferFrom(account, value)
      I used dynamic inheritance to move the clone method from the bottom of the extension tree to the very top. Now all of my extension can be cloned.
  TransferTo(account, value)
</pre>
[[Image:Ch2ckAccount2.JPG]]<br/>
<pre>
I show the new account object to Bill who is a teller.
Bill replies that he needs to see all of the customers transactions
because sometimes he is asked a question about a particular transaction.
Bill adds that if management approves the dispute, he needs to be able to modify a prior transaction.


I add the following to my account object:
  TransactionHistory [[date location amount],[date location amount],[date location amount]]   
  DisplayTransactionHistory()
  AddTransaction(DateTime, Location, Amount)
  AdjustTransaction(DateTime, Location, NewAmount)


Now that I am tracking transactions, I want deposits, withdrawals and transfers to create transactions.
Therefore, I also add the following:
  Deposit(value)
  Withdrawal(value) 
  TransferFrom(account, value)
  TransferTo(account, value)
</pre>
[[Image:Ch2ckAccount3.JPG]]<br/>
<pre>
Now I have an awesome account object, but I only have one.
<pre>
I need a way to copy this object so that I can give accounts to all of my friends.
I then add the following
  Clone()
However, I want Clone() to be available to all existing objects.
Instead of delegating from Clone to TransactionAccount,
I am going to delegate from BankAccount to Clone.
</pre>
[[Image:Ch2ckAccount4.JPG]]<br/>
<pre>
I would also like a ToString() for all objects.
But, I do not need a Clone.ToString().
I am going to delegate from BankAccount to ToString.
</pre>
[[Image:Ch2ckAccount5.JPG]]<br/>
==Clone and Change Technique==
Now that I have a clone() method, I can clone an existing object then morph it into a different object.<br/>
Given the above example. If I want to create an ATM account.
<pre>
  ATMAccount = TransferableAccount.Clone()
  def ATMAccount.Pin end
  def ATMAccount.DailyLimit end
  def ATMAccount.LastTransaction end
  def ATMAccount.DailyTotal end
</pre>
==Clone Types==
When copying a prototype object, there are different types of copying the existing object.<br/>
When using a prototype language, this is usually not a choice, it is implemented by the language.
===Deep Copy===
A deep copy, duplicates both the copied object and all objects that are delegated to.<br/>
In the above example a deep copy of TransferableAccount would make copies of TransferableAccount, BankAccount, Clone, ToString.<br/>
The benefit is that all parts may be modified without effecting the original object. The downside is that it consumes more resources.
===Shallow Copy===
A shallow copy, duplicates only the copied object and delegates to the same objects as the original.<br/>
The benefit is that it consumes less resources. The downside is that modification of a delegated object also effects the original object.
===Lazy Copy or Copy on Write===
A hybrid of a deep and shallow copy that gives the benefits of both.
As in a shallow copy, clone() duplicates only the copied object and delegates to the same objects as the original.<br/>
However when a delegated object is modified, a copy of the object to be modified is performed before the modification, and the delegate is adjusted to point to the copy. Then the copy is modified.
==Conclusion==
The debate over which is better, class based OOD or prototype based OOD, has been around since the beginning of OOD. Prototype OOD appears to be gaining some mainstream ground, but it is still a long way from taking over traditional class based OOD. It is this authors opinion that this debate is ongoing and will exist in one form or another into the future. I believe that in the past 15 years, neither has proven to be advantagous in all circumstances over the other. I also believe that the evolution of some hybrid language features that attempt to bridge the gap will continue to evolve. I beleive that the future will at times lean in the direction of one or in the direction of the other, bull will never quite cuminate on one or the other.


==References==
==References==
[1] [http://education.yahoo.com/reference/dictionary/entry/prototype Yahoo Online Dictionary - Prototype]<br/>
[1] [http://education.yahoo.com/reference/dictionary/entry/prototype Yahoo Online Dictionary - Prototype]<br/>
[2] [http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems By: Henry Lieberman]<br/>
[2] [http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems By: Henry Lieberman]<br/>
[3] [http://msdn.microsoft.com/en-us/library/bb383977.aspx Method extensions in  C#]<br/>
[3] [http://selflanguage.org Self - The power of Simplicity By: David Ungar and Randall B - 1986]<br/>
Prototype and Scriptaculous in Action By: Dave Crane; Bear Bibeault; Tom Locke; Thomas Fuchs <br/>
[4] [http://www.mozilla.org/js/language/E262.pdf ECMA 262 standard version 1.0 July 1997]<br/>
ISBN-10: 1-933988-03-7 <br/>
[5] [http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf ECMA 262 standard version 5.0 December 2009]<br/>
<br/>
[6] [http://msdn.microsoft.com/en-us/library/bb383977.aspx MSDN article on C# Extension Methods]<br/>
Self - The power of Simplicity By: David Ungar and Randall B - 1986 <br/>
[7] [http://lucacardelli.name/Talks/1996-05%20Class-based%20vs%20Object-based%20Languages%20(PLDI%20Tutorial).pdf Object-based vs. Class-based Languages - Digital Equipment Corporation Systems Research Center]<br/>
http://selflanguage.org <br/>
[http://www.brics.dk/~hosc/local/LaSC-4-3-pp223-242.pdf Organizing Programs without Classes]<br/>
[http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56.4713&rep=rep1&type=pdf Classes vs. Prototypes Some Philosophical and Historical Observations]
[http://www.lirmm.fr/~dony/postscript/proto-book.pdf Classifying Prototype-Based Programming Languages]<br/>
<br/>
<br/>

Latest revision as of 23:15, 1 October 2010

Prototype Based Object Oriented Design

Introduction

Dictionary Definition of Prototype: 'An original, full-scale, and usually working model of a new product or new version of an existing product'.[1]

"... the prototype approach in some ways corresponds more closely to the way people seem to acquire knowledge from concrete situations"[2]

Since the early period of implementation of Object Oriented Design (OOD), there have been two schools of thought concerning the best method of implementing OOD. The class approach, which is the static method of implementation. And the Prototype approach, which is the dynamic method of implementation.

The class based implementation of OOD is very rigid and favors a design first approach. The prototype based implementation of OOD favors a design as we go or iterative approach.

This article assumes that the reader is familiar with class based object oriented design and will focus mostly on the specifics of prototype based object oriented design. In doing so, we will also contrast the differences between the two and try to determine what is in the future.

Brief History

Even though the prototype implementation of OOD has been around for a long time, it took a very long time to reach the mainstream development community. The purest form was in a language called Self[3]. Self, was created in 1986 as a project at Sun Labs. It was one of the first languages to support prototyping and it was built entirely from the ground up using prototypes. In 1995 version 4 was released and Sun culminated it as a project. Even though it is no longer an official project at Sun Labs, Sun Labs stills ports version 4 to keep it runing on several OS's. It is now at version 4.4.

Prototype OOD reached the mainstream development community when the internet became popular and it was adopted by ECMAScript(JavaScript) as their OOD environment in 1997.[4] and also in Adobe Flash Action Script. There was a lot of speculation that version 4.0 of ECMAScript would have traditional classes instead of or in addition to prototyping, however verion 4.0 was never realeased. When version 5.0 of ECMAScript.[5] was released in December 2009, prototyping still existed as the only OOD that was to be supported.

Even some class based languages, such as C# [6] in particular and several others in general, implemented a variation of prototyping called extensions. 'Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.' .[6]. While this does not have all of the features that a prototyping language does, it shows the influence that prototype OOD has had on many of the main stream languages in use today.

Delegation

The mechanism for implementation of prototyping is called Delegation.[2]

'Operationally, delegation is the redirection of field access and method invocation from an object or prototype to another, in such a way that an object can be seen as an extension of another.'&nbsp[7]

Delegation is a process whereby an existing object dynamically searches for properties and methods first within itself, then if an match is not found, it delegates that search to its parent object. The parent then repeats the exact same delegation process until a match is found. Once a match is found the result is returned to the requester.

Simple Example
This example demonstrates two objects that I always want aligned on the same y axis, however I want them to be independent on the x axis.

Box remains as is but Point is changed

NOTE: In the above example Box.GetPoint() would also return [10,10]. When GetPoint() searches for X it starts at the original requestors level and uses delegation just like the method search for Box.GetPoint().

While delegation is simple in its design, we will see that it is also elegant. In that it opens the door for several different techniques which allow software developers to morph an existing object, into a much larger and more robust object. While still retaining the original objects simplicity.

Competing Approaches

Class Approach

New objects are made from predefined classes. A class definition must exist to create an instance of a class. When a class is changed, existing objects must be reconstructed and we also need to ensure that nothing else in the application requires the prior classes constructed behavior.

Prototype Approach

New objects are constructed by copying an existing object. After copying we are safe to change the class behavior knowing that we are independent of all other objects. Prototyping is dynamic allowing us to create a real world object as a single instance and then refactor it at run time.

  • We can add to it.
  • We can remove parts from it.
  • We can break parts out and move to a different location in the same delegation tree. Thereby extending the original behavior to more objects in the same object hierarchy.


Contrasting Development Styles[7]

Class Development Style Prototype Development Style
Must think about objects abstractly and develop a model to simulate behavior Most people can think clearly about objects that already exist
Many people lack the ability to perform well when working with abstract thoughts Most people have the ability to perform well when working with real world objects
Good communication is limited to those that can think abstractly Good communication is open to normal methods of everyday interaction
Real world examples need to be broken down to a model and then reconstructed before they can be worked with Real world examples can be worked with in real time, there is no need to model behavior

Analysis2

Advantages of Prototype

  • Reduces development time.
  • Reduces development costs.
  • Developers receive quick results and can move on to the next task.

Disadvantages of Prototype

  • Can lead to insufficient analysis.
  • The performance may be degraded by prototype overhead.
  • Can cause systems to be left unfinished and/or implemented before they are ready.
  • Sometimes leads to incomplete documentation.

Prototype Inheritance

As we will see, some dynamic languages use prototyping to support dynamic inheritance and multi-inheritance.
All object inheritance is initially copied from an existing object, then when additional functionality is desired, inheritance may be added at runtime via delegation.
The biggest design benefit of prototype inheritance is that inheritance functionality may be added anywhere within the existing objects class tree. It may be added to (or removed from) the end, the beginning, or anywhere in the middle. It is very flexible and powerful.

Real World Example

A bank account

Class Approach

Focus of thought is constantly changing:

  1. Start with use cases
  2. Create a class diagram
  3. Write Code
  4. Experiment
  5. Modify class diagram
  6. Refactor
  7. Write Code
  8. Rewrite code that depended on the functionality removed from prior class diagram.
  9. Goto step 4

Prototype Approach

Lets just build a bank account object and code it right now.

Now I can show it to other people and get their inputs.

I show my account to Mary and she interacts with it.
Mary says that she has several accounts and often transfers money between them.

I add the following to my account object.
  TransferFrom(account, value)
  TransferTo(account, value)


I show the new account object to Bill who is a teller.
Bill replies that he needs to see all of the customers transactions
because sometimes he is asked a question about a particular transaction.
Bill adds that if management approves the dispute, he needs to be able to modify a prior transaction.

I add the following to my account object:
  TransactionHistory [[date location amount],[date location amount],[date location amount]]     
  DisplayTransactionHistory()
  AddTransaction(DateTime, Location, Amount)
  AdjustTransaction(DateTime, Location, NewAmount)

Now that I am tracking transactions, I want deposits, withdrawals and transfers to create transactions.
Therefore, I also add the following: 
  Deposit(value) 
  Withdrawal(value)  
  TransferFrom(account, value)
  TransferTo(account, value)


Now I have an awesome account object, but I only have one.
<pre>
I need a way to copy this object so that I can give accounts to all of my friends.
I then add the following
  Clone()
However, I want Clone() to be available to all existing objects.
Instead of delegating from Clone to TransactionAccount,
I am going to delegate from BankAccount to Clone.


I would also like a ToString() for all objects.
But, I do not need a Clone.ToString().
I am going to delegate from BankAccount to ToString.


Clone and Change Technique

Now that I have a clone() method, I can clone an existing object then morph it into a different object.
Given the above example. If I want to create an ATM account.

  ATMAccount = TransferableAccount.Clone()
  def ATMAccount.Pin end
  def ATMAccount.DailyLimit end
  def ATMAccount.LastTransaction end
  def ATMAccount.DailyTotal end

Clone Types

When copying a prototype object, there are different types of copying the existing object.
When using a prototype language, this is usually not a choice, it is implemented by the language.

Deep Copy

A deep copy, duplicates both the copied object and all objects that are delegated to.
In the above example a deep copy of TransferableAccount would make copies of TransferableAccount, BankAccount, Clone, ToString.
The benefit is that all parts may be modified without effecting the original object. The downside is that it consumes more resources.

Shallow Copy

A shallow copy, duplicates only the copied object and delegates to the same objects as the original.
The benefit is that it consumes less resources. The downside is that modification of a delegated object also effects the original object.

Lazy Copy or Copy on Write

A hybrid of a deep and shallow copy that gives the benefits of both. As in a shallow copy, clone() duplicates only the copied object and delegates to the same objects as the original.
However when a delegated object is modified, a copy of the object to be modified is performed before the modification, and the delegate is adjusted to point to the copy. Then the copy is modified.

Conclusion

The debate over which is better, class based OOD or prototype based OOD, has been around since the beginning of OOD. Prototype OOD appears to be gaining some mainstream ground, but it is still a long way from taking over traditional class based OOD. It is this authors opinion that this debate is ongoing and will exist in one form or another into the future. I believe that in the past 15 years, neither has proven to be advantagous in all circumstances over the other. I also believe that the evolution of some hybrid language features that attempt to bridge the gap will continue to evolve. I beleive that the future will at times lean in the direction of one or in the direction of the other, bull will never quite cuminate on one or the other.

References

[1] Yahoo Online Dictionary - Prototype
[2] Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems By: Henry Lieberman
[3] Self - The power of Simplicity By: David Ungar and Randall B - 1986
[4] ECMA 262 standard version 1.0 July 1997
[5] ECMA 262 standard version 5.0 December 2009
[6] MSDN article on C# Extension Methods
[7] Object-based vs. Class-based Languages - Digital Equipment Corporation Systems Research Center
Organizing Programs without Classes
Classes vs. Prototypes Some Philosophical and Historical Observations Classifying Prototype-Based Programming Languages