CSC/ECE 517 Summer 2008/wiki1 8 smr: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
== Introduction ==
== Introduction ==
Many of the object-oriented systems that have been created over the years have been done with class-based programming.  In class-based programming we define structures during implementation that describe the properties and operations of objects to be created during runtime.  At runtime, a program creates an instance of an object by referencing the class that defines the desired structure and behavior for that object.  While each instance contains its own copy of data, the behavioral aspects of a class are common between all instances and are not typically altered during the execution of the program.  Growing in popularity is another form of object-oriented programming known as prototype-based programming [1].
Many of the object-oriented systems that have been created over the years have been done using class-based programming.  In class-based programming we define structures during implementation that describe the properties and operations of objects to be created during runtime.  At runtime, a program creates an instance of an object by referencing the class that defines the desired structure and behavior for that object.  While each instance contains its own copy of data, the behavioral aspects of a class are common between all instances and are not typically altered during the execution of the program.  Growing in popularity is another form of object-oriented programming known as prototype-based programming [1].


In prototype-based programming instead of referencing a pre-defined class to create an object, an object is created by making a copy of an existing object.  Typically prototype-based programming follows these steps:
In prototype-based programming, instead of referencing a pre-defined class to create an object, an object is created by making a copy of an existing object.  Typically prototype-based programming follows these steps:
# '''Start with a Prototype:''' There is at least one concrete object in the system and it serves as the catalyst for all subsequently created objects.  This object as well as any other objects that exist serve as prototypes for creating new objects.
# '''Start with a Prototype:''' There is at least one concrete object in the system and it serves as the catalyst for all subsequently created objects.  This object as well as any other objects that exist serve as prototypes for creating new objects.
# '''Clone the Prototype:''' A new object is created by cloning an existing prototype.  The newly created object inherits all of the structural and behavioral aspects of the prototype.
# '''Clone the Prototype:''' A new object is created by cloning an existing prototype.  The newly created object inherits all of the structural and behavioral aspects of the prototype.
Line 15: Line 15:
=== Problem ===
=== Problem ===


Most organizations use some type of employee management system to store and modify a variety of information about their employees.  In this example, ABC Trucks needs a new system that allows them to support all the needs of all their employees.  ABC trucks classifies their employees as Full-time, Manager, Temporary, and/or Intern.  Each classification represents different information to be stored for an employee as well as added functionality need to manage that type of employee.  The classifications are not mutually exclusive so an employee might satisfy zero or more classifications.  The objective is to create an extensible employees management system that supports all of the ABC Trucks employees.
Most organizations use some type of employee management system to store and modify a variety of information about their employees.  In this example, ABC Trucks needs a new system that allows them to support the needs of all their employees.  ABC trucks classifies their employees as Full-time, Manager, Temporary, and/or Intern.  Each classification represents different information to be stored for an employee as well as added functionality need to manage that type of employee.  The classifications are not mutually exclusive so an employee might qualify for zero or more classifications.  The objective is to create an extensible employees management system that supports all of the ABC Trucks employees.


=== Class-based Approach ===
=== Class-based Approach ===


In a class-based approach, we might create classes to represent all of the possible employee classifications, while using inheritance to share common functionality between the classes.  For this example, we would need to define 16 (24) different classes, each with different properties and operations.   
In a class-based approach, we might create classes to represent all of the possible employee classifications, while using inheritance to share common functionality between the classes.  For this example, we would need to define 16 (2^4) different classes, each with different properties and operations.   


[[Image:wiki1_8_smr_class_diagram.gif]]
[[Image:wiki1_8_smr_class_diagram.gif]]
Line 104: Line 104:
'''Prototype-based Programming Advantage''': Object-oriented systems with objects requiring numerous classifications can benefit by using prototype-based programming.   
'''Prototype-based Programming Advantage''': Object-oriented systems with objects requiring numerous classifications can benefit by using prototype-based programming.   


If n is the number of classifications for a particular type of object, then class-based programming requires the definition of 2n classes to represent all possible objects.  Alternatively, prototype-based programming requires the definition of only n classes (or modules) to represent all possible objects.   
If n is the number of classifications for a particular type of object, then class-based programming requires the definition of 2^n classes to represent all possible objects.  Alternatively, prototype-based programming requires the definition of only n classes (or modules) to represent all possible objects.   


To drive this point home, consider if our requirements were later changed to add 1 more employee classification.  Our prototype-based solution would need the definition of 1 more module whereas the class-based solution would require the definition of 16 new classes.
To drive this point home, consider if our requirements were later changed to add 1 more employee classification.  Our prototype-based solution would need the definition of 1 more module whereas the class-based solution would require the definition of 16 new classes.
Line 154: Line 154:
   end
   end


The EmployeeSystem provides the method newEmployee(key), which returns a prototype employee object based on either an existing employee or a default employee object.  Note that the returned prototype is a clone of the requested employee object.   
The <code>EmployeeSystem</code> provides the method <code>newEmployee(key)</code>, which returns a prototype employee object based on either an existing employee or a default employee object.  Note that the returned prototype is a clone of the requested employee object.   


We now create a new employee object using the newEmployee method.
We now create a new employee object using the <code>newEmployee</code> method.


   # retrieve the default employee object to use a prototype
   # retrieve the default employee object to use a prototype
Line 215: Line 215:
<tr>
<tr>
   <td>
   <td>
'''Prototype-based Programming Advantage''':Using prototype-based programming, we simplified our ability to provide default data and functionality for newly created objects.  This simplification reduces the amount of code and logic needed for the initialize of new objects.  We have similar functionality in class-based programming by setting default values, but not to the extent of prototype-based programming.  Because in class-based programming we are creating classes in advance to represent multiple objects, we are less inclined to create separate classes to represent a subtle difference between objects.   
'''Prototype-based Programming Advantage''': Using prototype-based programming, we simplified our ability to provide default data and functionality for newly created objects.  This simplification reduces the amount of code and logic needed to initialize new objects.  We have similar functionality in class-based programming by setting default values, but not to the extent of prototype-based programming.  Because in class-based programming we are creating classes in advance to represent multiple objects, we are less inclined to create separate classes to represent a subtle difference between objects.   


Consider the exercise of ABC Trucks wanting to provide different benefits to the employees in NY and those employees in NC.  We are not likely to create another type of employee sub-class for this subtle difference (doing so would require an additional 16 classes!).  As a result, the initialization of the benefits field would have to occur after instantiation, and if that logic must be external to the class than it may end up existing in multiple places.  In our prototype-based solution however, we could maintain a hash table that has the subtly different objects that we can use as prototypes for creating new objects.  
Consider the exercise of ABC Trucks wanting to provide different benefits to the employees in NY and those employees in NC.  We are not likely to create another type of employee sub-class for this subtle difference (doing so would require an additional 16 classes!).  As a result, the initialization of the benefits field would have to occur after instantiation, and if that logic must be external to the class than it may end up existing in multiple places.  In our prototype-based solution however, we could maintain a hash table that has the subtly different objects that we can use as prototypes for creating new objects.  
Line 234: Line 234:
    
    
   -----General Information--------
   -----General Information--------
   benefits: Private plane during week, Yacht on weekends
   benefits: Private plane on the weekends
   salary: 100000
   salary: 100000
   name: Mia Marie
   name: Mia Marie
Line 253: Line 253:
== Conclusion ==
== Conclusion ==


The article provided a brief overview of prototype-based programming along with an example of its use in the real world.  Our example highlighted some advantages of prototype-based programming over class-based programming for solving problems for certain object-oriented systems.  Despite the advantages highlighted and the fact that prototype-based programming is gaining in popularity [1], class-based programming is still more widely used [3].  In closing, we recommend readers stay informed on the growing appeal of prototype-based programming and consider embracing a language like Ruby that may offer the best of both worlds.  
In this article we have provided a brief overview of prototype-based programming along with an example of its use in the real world.  Our example highlighted some advantages of prototype-based programming over class-based programming for solving problems of certain object-oriented systems.  Despite the advantages highlighted and the fact that prototype-based programming is gaining in popularity [1], class-based programming is still more widely used [3].  In closing, we recommend readers stay informed on the growing appeal of prototype-based programming and consider embracing a language like Ruby that may offer the best of both worlds.  


== Related Reading ==
== Related Reading ==

Revision as of 01:56, 7 June 2008

Introduction

Many of the object-oriented systems that have been created over the years have been done using class-based programming. In class-based programming we define structures during implementation that describe the properties and operations of objects to be created during runtime. At runtime, a program creates an instance of an object by referencing the class that defines the desired structure and behavior for that object. While each instance contains its own copy of data, the behavioral aspects of a class are common between all instances and are not typically altered during the execution of the program. Growing in popularity is another form of object-oriented programming known as prototype-based programming [1].

In prototype-based programming, instead of referencing a pre-defined class to create an object, an object is created by making a copy of an existing object. Typically prototype-based programming follows these steps:

  1. Start with a Prototype: There is at least one concrete object in the system and it serves as the catalyst for all subsequently created objects. This object as well as any other objects that exist serve as prototypes for creating new objects.
  2. Clone the Prototype: A new object is created by cloning an existing prototype. The newly created object inherits all of the structural and behavioral aspects of the prototype.
  3. Tailor or Extend the Object The newly created object is then tailored for its specific purposes and its possible the object is enhanced to provide new functionality.

Prototype-based programming continues to follow the steps to create the host of objects which exist within the runtime environment.

Prototype-based programming has been said to be more powerful than class-based programming [2], which is something we explore in this article. Below we use an example information-management system to compare alternative approaches provided by class-based and prototype-based programming. In the example, we highlight the tasks made easier by prototype-based programming.

Example

Problem

Most organizations use some type of employee management system to store and modify a variety of information about their employees. In this example, ABC Trucks needs a new system that allows them to support the needs of all their employees. ABC trucks classifies their employees as Full-time, Manager, Temporary, and/or Intern. Each classification represents different information to be stored for an employee as well as added functionality need to manage that type of employee. The classifications are not mutually exclusive so an employee might qualify for zero or more classifications. The objective is to create an extensible employees management system that supports all of the ABC Trucks employees.

Class-based Approach

In a class-based approach, we might create classes to represent all of the possible employee classifications, while using inheritance to share common functionality between the classes. For this example, we would need to define 16 (2^4) different classes, each with different properties and operations.

These classes are certainly representative of the employees that work at ABC Trucks. However, this approach requires quite a bit of code to be developed, tested, and maintained.

We’re now going to discuss a prototype-based programming approach to this same problem. Throughout the discussion of the prototype-based approach, we will refer back to this class-based approach in order to draw comparisons and to highlight tasks made easier by prototype-based programming.

Prototype-based Approach

We’ve selected Ruby as our target language, which affords us the option to use prototype-based programming. For our prototype-based approach, rather than creating a class for every possible type of employee, we’ll start with a single Employee object. This object will then be cloned and extended to support all of the employees classifications.

The code below defines a base employee object that has the common properties and operations of all employees. In addition, we define individual modules to represent each of the employee classifications.

 # initial employee object
 class Employee
   include Comparable
   
   attr_reader :name, :ssn
   attr_writer :name, :ssn
   
   def initialize(ssn, name)
     @name, @ssn = name, ssn
   end
   
   def key
     ssn
   end
   
   def <=>(other)
     self.name <=> other.name
   end
   
   def to_s()	
     self.name
   end
   
   # dump all initialized variables of this object
   def dump
     s = ""
     
     self.instance_variables.each do |v| 
       s += v.gsub(/^@(.+)/, "\\1: #{eval(v)}\n") 
     end 
     
     return s
   end
 end
 
 # provides manager properties and operations
 module Manager
   def direct_reports
     @direct_reports ||= []
   end
 end
 
 # provides full-time employee properties and operations
 module FullTime
   attr_reader :salary, :benefits, :vacation_bal
   attr_writer :salary, :benefits, :vacation_bal
   
   def recordVacation(date)
     date
   end
 end
 
 # provides temp-employee properties and operations
 module Temp
   attr_reader :location, :agency
   attr_writer :location, :agency
 end
 
 # provides intern properties and operations
 module Intern
   attr_reader :school, :term
   attr_writer :school, :term
 end
 

In contrast to the definition of the 16 classes needed for the class-based solution, we are able to get away with defining only 5 different classes (or modules).

Prototype-based Programming Advantage: Object-oriented systems with objects requiring numerous classifications can benefit by using prototype-based programming.

If n is the number of classifications for a particular type of object, then class-based programming requires the definition of 2^n classes to represent all possible objects. Alternatively, prototype-based programming requires the definition of only n classes (or modules) to represent all possible objects.

To drive this point home, consider if our requirements were later changed to add 1 more employee classification. Our prototype-based solution would need the definition of 1 more module whereas the class-based solution would require the definition of 16 new classes.

In prototype-based programming, the idea is to create subsequent objects based on an initial prototype. To facilitate this, we’ve created the singleton Employee System below which provides a method for creating new employee objects based on an existing employee object.

 require "singleton"
 
 # EmployeeSystem is hub for creating employees
 # only 1 version of the system exists
 class EmployeeSystem < Hash
   include Singleton
   
   DEFAULT_EMPLOYEE = Employee.new("000000000", "")
   
   # add employee to the collection
   def saveEmployee(e)
     self[e.key] = e
   end
   
   # create employee object based on default 
   # or existing  employee prototype
   def newEmployee(key = nil)
     if (key)
       e = self[key]
     end
     
     if (!e)
       e = EmployeeSystem::DEFAULT_EMPLOYEE
     end
     
     return e.clone()
   end
   
   # dump out the employee information
   def employeeReport()
     puts "\nEmployee Report"
     	
     self.values.sort.each do |e|
     puts "============================================\n"
     puts "Name: #{e}\n\n-----General Information--------\n#{e.dump}\n" 
   end
   
   puts "============================================\n\n"
   
 end

The EmployeeSystem provides the method newEmployee(key), which returns a prototype employee object based on either an existing employee or a default employee object. Note that the returned prototype is a clone of the requested employee object.

We now create a new employee object using the newEmployee method.

 # retrieve the default employee object to use a prototype
 e1 = EmployeeSystem.instance.newEmployee()
 
 # initialize the fields of this new employee
 e1.name = "Tom Smith"
 e1.ssn = "123123123"
 
 # extend this particular employee to be a full-time employee
 e1.extend(FullTime)
 
 # initialize the fields specific to full-time employees
 e1.salary = 50_000
 e1.benefits = "Private plane on the weekends"
 
 # save this new employee back to the employee database
 EmployeeSystem.instance.saveEmployee(e1)

Above we’ve extended our default employee prototype to create a new type of full-time employee.

Prototype-based Programming Advantage: Using prototype-based programming, we are able to treat any object as a prototype and therefore we can extend the object without having to create a new object. In class-based programming, we are committed to the functionality provided by the object at instantiation. If we later need to extend the functionality of the class-based object, we must instantiate a new class-based object that has the desired functionality and transfer state between the two objects.

Consider the exercise to promote an employee from a full-time employee to a full-time manager. In our prototype-based solution, we simply extend the FullTime employee object to have the functionality of a Manager. In our class-based solution, we must instantiate a new FullTimeManager object and transfer state from the existing FullTime employee object.

At this point, we have two employee objects that can act as a prototype for a new employee. In this next step we’ll create another employee object, but this time we’ll use the employee we just created as the prototype.

 # create a new employee based on the Tom Smith prototype
 e2 = EmployeeSystem.instance.newEmployee("123123123")
 
 # initialize the fields of this new employee
 e2.name = "Mia Marie"
 e2.ssn = "456456456"
 
 # initialize the fields specific to full-time employees
 # Note: we didn't need to extend this employee to be a full-time
 e2.salary = 100_000
 
 # extend this particular employee to be a Manager
 e2.extend(Manager)
 
 # initialize the fields specific to Managers
 # Tom Smith reports to Mia Marie
 e2.direct_reports << e1
 
 # save this new employee back to the employee database
 EmployeeSystem.instance.saveEmployee(e2)
 

In the above snipped of code, we created a new full-time employee based on the prototype of an existing full-time employee. Notice for this newest employee, we didn’t initialize the benefits field. This is because this information was already initialized within our prototype and is the desired value for our new employee.

Prototype-based Programming Advantage: Using prototype-based programming, we simplified our ability to provide default data and functionality for newly created objects. This simplification reduces the amount of code and logic needed to initialize new objects. We have similar functionality in class-based programming by setting default values, but not to the extent of prototype-based programming. Because in class-based programming we are creating classes in advance to represent multiple objects, we are less inclined to create separate classes to represent a subtle difference between objects.

Consider the exercise of ABC Trucks wanting to provide different benefits to the employees in NY and those employees in NC. We are not likely to create another type of employee sub-class for this subtle difference (doing so would require an additional 16 classes!). As a result, the initialization of the benefits field would have to occur after instantiation, and if that logic must be external to the class than it may end up existing in multiple places. In our prototype-based solution however, we could maintain a hash table that has the subtly different objects that we can use as prototypes for creating new objects.

The last section within the above code further extends the full-time employee to be a manager and assigns them a direct report. As mentioned prior, extending our full-time employee to now be a full-time manager is considerably easier than it would have been in our class-based solution.

To round out our example, we run the report for the Employee System so that we can review the internals of these objects.

 # display a report of our employees
 EmployeeSystem.instance.employeeReport()
 Employee Report
 ============================================
 Name: Mia Marie
 
 -----General Information--------
 benefits: Private plane on the weekends
 salary: 100000
 name: Mia Marie
 ssn: 456456456
 direct_reports: Tom Smith
 
 ============================================
 Name: Tom Smith
 
 -----General Information--------
 benefits: Private plane on the weekends
 salary: 50000
 name: Tom Smith
 ssn: 123123123
 
 ============================================

Conclusion

In this article we have provided a brief overview of prototype-based programming along with an example of its use in the real world. Our example highlighted some advantages of prototype-based programming over class-based programming for solving problems of certain object-oriented systems. Despite the advantages highlighted and the fact that prototype-based programming is gaining in popularity [1], class-based programming is still more widely used [3]. In closing, we recommend readers stay informed on the growing appeal of prototype-based programming and consider embracing a language like Ruby that may offer the best of both worlds.

Related Reading

References

  1. Wikipedia: Prototype-based programming
  2. Softpanoroma: Prototype Based Object-Oriented
  3. TIOBE Software: TIOBE Programming Community Index for May 2008