Object-Oriented Design Heuristics: Alexandre Bergel Abergel@dcc - Uchile.cl 24/05/2011
Object-Oriented Design Heuristics: Alexandre Bergel Abergel@dcc - Uchile.cl 24/05/2011
Design Heuristics
Alexandre Bergel
abergel@dcc.uchile.cl
24/05/2011
Source
978-0201633856
Java 1.6
Pharo 1.0
Goal of this lecture
the attributes of its class (usually static) and values for those
attributes (usually dynamic)
Piece of code extracted from the JDK 1.6. The class DefaultCaret belongs to the package
javax.swing.text. It contains 15 public attributes
Handler
DefaultCaret
We will make heavy use of visualization along the semester. Visualizing software is a very handy
and intuitive mechanism for getting a quantitative and qualitative impression about a system.
Class blueprint is a visualization that shows class internal. A class is represented as a box. Each
box is composed of 5 part. Each part correspond to some particular elements that composes the
class. From left to right: constructors, public methods, private methods, variable accessors and
mutators (get and set methods), attributes.
Blue edges represent methods invocations. Cyan edges represent variable accesses.
Access to public variables
Handler
DefaultCaret
The class DefaultCaret contains 15 public attributes. These attributes are accessed by other
classes. Handler for example. This shows a poor programming style. Never make field public or
package visible.
One may argue that for optimization reason, it may be preferable to have public variables instead
of accessors. It was true some time ago when virtual machines and compiler were not that
sophisticated. Today, making variable public is hardly considered as an efficient way to optimize
your program.
How to hide data?
number of number of
lines of code methods
We can see another visualization, called System complexity. This visualization is about class
hierarchies. Each class is represented as a box, shaped with three metrics: number of variables,
number of methods and number of lines of code.
The hierarchy represented here is PLAF, the pluggable look and feel of Java. You can notice the
irregularity of the hierarchies, which probably hide some missing functionalities.
javax.swing.plaf.basic.BasicTreeUI
1636 lines of code
49 variables
131 methods
JTable
2691 LOC
185 methods
44 attributes
We can merely observe the two biggest classes of Swing: JComponent and JTable.
However, we should not blame their developers. The root of a graphical user interface framework
is inherently complex and difficult to implement. To convince yourself, have a look at the root
class of any serious GUI framework.
A class should capture one and only one key abstraction
Example in ArgoUML
We can observe a class which has 2 public methods and many private methods. This class is quite
particular in the sense that its private methods are divided into two distinct groups. Each group of
private method is used by one public method.
/**
* The "standard" input stream. This stream is already
* open and ready to supply input data. Typically this stream
* corresponds to keyboard input or another input source specified by
java.lang.System is the perfect example. It offers methods ranging from writing on the standard
streams to copying arrays and managing security.
Note that the heuristic given before is also valid for packages. Consider the package java.util.
This package contains 229 classes, most of them are collections. But it also contains the classes
Data, JapaneseImperialCalendar, Locale, Random, XMLUtils and many more unrelated classes.
In the Pharo and Squeak Smalltalk languages, the class SystemDictionary is another example of a
god class.
SystemDictionary enables one to control the garbage collectors, streaming objects, accessing
classes, querying the systems. It has little to do with the notion of dictionary!
In application that consist of an object-oriented model interaction
with a user interface, the model should never be dependent on the
interface.
Have a look at the definition of the class nsDOMWindowUtils, which is central to the DOM
component of Mozilla.
This class has references to some graphical packages, which goes against the idea of having a
clean and modular DOM.
belong to
the core
In Mozilla:
dom/base/nsDOMWindowUtils.cpp
View Model
Model-view-controller
Controller
View Model
testing
anyone_in_room?() Occupancy
get_actual_temp?() Room
get_desired_temp() Desired Temp
Heat flow
Actual Temp
regulator
is_occupied() Occupancy
Room
do_you_need_heat?() Desired Temp
Heat flow
Actual Temp
regulator
Occupancy
call_buffer connector
call_buffer
connector
Container Button
Window Frame
JButton
...
@OOPSLA’89
“In Figure 2 an example of a class is given. Class Window is
described as a subclass of class Stream. ...”
“In Figure 2 an example of a class is given. Class Window is
described as a subclass of class Stream. ...”
... Link
LinkedList Process
Semaphore
CarManufacturer
Consider the inheritance hierarchy given on this slide. At first view the inheritance hierarchy looks
correct. GeneralMotors, Ford and Chrysler are all special types of car manufacturers. On second
thought, is GeneralMotors really a special type of car manufacturer? Or is it an example of a car
manufacturer? This is a classic error and it causes proliferation of classes.
how many GeneralMotors objects are there? Ford objects? Chrysler objects? The answer for all
three classes if one. In this case they should have been objects.
Keep in mind that not all derived classes that have only one instance in your system are
manifestations of this error, but many will be.
It should be illegal for a derived class to override a base class
method with a NOP method, that is, a method that does nothing
Dog wag_tail() {...}
Consider a class Dog. The behaviors that all Dogs know how to carry out is bark, chase_cats and
wag_tail. Consider that we want to have a dog that does not wag its tail, let’s say DogNoWag. This
new class is exactly like a Dog except it doesn’t know how to wag its tail. A solution could be to
have DogNoWag inherit from Dog and override the wag_tail method with an empty method (NOP).
Dog wag_tail() {...}
What is model-view-controller?
http://creativecommons.org/licenses/by-sa/2.5
Attribution-ShareAlike 2.5
You are free:
• to copy, distribute, display, and perform the work
• to make derivative works
• to make commercial use of the work
Attribution. You must attribute the work in the manner specified by the author or licensor.
!
Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting
work only under a license identical to this one.
• For any reuse or distribution, you must make clear to others the license terms of this work.
• Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.