6.2. Three Laws of Objects

 <  Day Day Up  >  

Isaac Asimov proposed three laws for robots in his book, I, Robot . [*] Objects are a lot like robots. They are asked to perform certain operations with an expectation that those operations will be performed correctly. In addition to the maxims stated in the preceding section, you might consider the Three Laws of Objects. These laws can be applicable for a program as a whole, as well as for an individual object:

[*] They are: 1. A robot may not injure a human being, or, through inaction, allow a human being to come to harm; 2. A robot must obey orders given it by human beings, except where such orders would conflict with the First Law; and 3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.

  • An object shall do what its methods say it does

  • An object shall do no harm

  • An object shall notify its user if it is unable to perform a requested operation

Let us look at these laws in a little more detail:



An object shall do what its methods say it does

This law covers two concepts. The first is that a given method has a name that specifies what it does. This concept is covered in the guideline, "A Rose by Any Other Name Is Not a Rose." The second is that the method does what can be reasonably expected by that name . (This concept is also known as the "Principle of Least Surprises").

For example, what is the expectation for a method named "remove" versus one named "delete?" This dichotomy occurs in user interfaces as well as in collections. If a user " removes " an item from a collection (such as in CDDiscCollection ), should he reasonably expect that the item still exists or should he expect that it has been erased completely? If the user "deletes" an item, does that operation delete the item as well as remove it from the collection, or does it just remove it? The terminology of many user interfaces corresponds with the first alternative for each of these answers. Consistency suggests that the methods you write work the same way. [*]

[*] One reviewer suggested that keeping the meanings of words such as remove consistent across an application is difficult, especially in larger development groups. Local dialects make the consistent connotations of words difficult. A global dictionary can help but does not guarantee consistency.



An object shall do no harm

A long time ago, I reviewed a package that created a set of graphical user interface (GUI) widgets on the screen. When the program created a widget, the widget object read its configuration from a file. The system seemed to work OK, until more than 20 widgets were on the screen. Then no more widgets were created. The reason was that the widgets closed the configuration file only when they were destroyed . The limit that was set on my operating system at the time was that only 20 files could be opened simultaneously . Perhaps the package had been tested on a system with a much larger limit.

These objects did harm. They hogged resources unnecessarily. Typical advice to object-oriented designers suggests that one acquire resources in the constructor and release them in the destructor. However, an object also needs to live within its means. It should not do harm by holding onto resources longer than necessary. If an object is not destroyed for an uncertain period of time (such as objects in Java), it needs to provide a method (e.g., dispose( ) ) that can be called to release resources.

Suppose that the underlying implementation of CDDiscCollection used a database. If the constructor opened a connection to a database, the destructor should close that connection. [ ] Alternatively, CDDiscCollection might share a database connection with all the other collection classes.

[ ] One reviewer commented, "Doing no harm includes not inconveniencing or potentially sabotaging neighboring objects, or objects that might be about to move into our applications object community."



An object shall notify its user if it is unable to perform a requested operation

An object should not fail silently. If the caller has passed inappropriate parameters, or the needed resources are not available, the object should report its inability to complete the operation. Whether the signal is throwing an exception or returning an error value depends on the language facilities and the programming guidelines of the development group .

For example, if the add( ) method of CDDiscCollection finds that it is adding an existing item, it should generate an error, instead of silently replacing the item. According to a reviewer, "The amount of debugging time this simple practice can eliminate is hard to overestimate. The amount of time saved in looking for points of failure alone can be staggering. Once you get used to programming in this style, you might begin to feel like you are surrounded by protective pillows."

NEVER BE SILENT

If a method encounters an error, it should report it, not remain silent . [*]


[*] Herb Sutter and Andrei Alexandrescu cover this in C++ Coding Standards (Addison-Wesley Professional, 2004).

 <  Day Day Up  >  


Prefactoring
Prefactoring: Extreme Abstraction, Extreme Separation, Extreme Readability
ISBN: 0596008740
EAN: 2147483647
Year: 2005
Pages: 175
Authors: Ken Pugh

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net