In an activity where the designers look for logical solutions to solve a problem, using objects needs basic understanding on OO. Any person writing code should know the basic OOAD to ensure that they follow basic programming design of OO – Object Orientation. This article would help developers to understand the basics of OOAD by referring the real time objects [Pictures].
In the development process, unless developers code the objects with basic knowledge on OOAD, the output will take procedural form, as if technical writer typing a pseudo-code. In many cases, it happens in projects. Nowadays, non IT graduates joining companies start coding for real time projects in few weeks with basic coding guidelines got from tutor/mentor. Many tutor/mentor/leads training these rookies in project never tell about the OO basics.
Let us Discuss OOAD
We will discuss OOAD by dividing into the below sections:
- Thumbnails principles of the object oriented design
- OO Design Quality Metrics
Object-Oriented System (OOS)
- An object-oriented system is composed of objects
- Behavior of the system is achieved through collaboration between these objects
- State of the system is the combined state of all the objects in it
- Collaboration between objects involves them sending messages to each other.
- Exact semantics of message sending between objects varies depending on what kind of system is being modeled.
- By “Invoking a method"
- By Sending data via a socket
Object-Oriented Analysis (OOA)
Object-Oriented Design (OOD)
Thumbnails-principles of the Object Oriented Design
Single Responsibility Principle
- A class should have a single responsibility:
- it does it all,
- does it well, and
- does it only.
- A class should have one, and only one, reason to change.
- Each responsibility should be a separate class, because each responsibility is an axis of change.
- If a change to the business rules causes a class to change, then a change to the database schema, GUI, report format, or any other segment of the system should not force that class to change
Rule of thumb
- Unless description of a class is in 25 words or less, with mouseof "and" or "or" may actually have more than one class.
- Classes, interfaces, functions, etc. all become large and bloated when they're trying to do too many things.
- To avoid bloat and confusion, and ensure that code is truly simple (not just quick to hack out), we have to practice Code Normalization, which seems to be a variation on
OnceAndOnlyOnce and also
DoTheSimplestThingThatCouldPossiblyWork. This is part of
- Software entities (classes, modules, etc.) should be open for extension, but closed for modification.
- In other words (in an ideal world...), you should never need to change existing code or classes: All new functionality can be added by adding new subclasses and overriding methods, or by reusing existing code through delegation.
- This prevents you from introducing new bugs in existing code. If you never change it, you can't break it.
Using Abstract Class, Class Implemented with Interfaces
Liskov Substitution Principle- LSP
- Derived classes must be usable through the base class interface without the need for the user to know the difference.
- "An instance of a derived should be able to replace any instance of its superclass"
- The use of hierarchy is an important component in object-oriented design. Hierarchy allows the use of type families, in which higher level supertypes capture the behavior that all of their subtypes have in common. For this methodology to be effective, it is necessary to have a clear understanding of how subtypes and supertypes are related.
- "objects of the subtype ought to behave the same as those of the supertype as far as anyone or any program using supertype objects can tell".
- Because if not, then class hierarchies would be a mess. Mess being that whenever a subclass instance was passed as parameter to any method, strange behavior would occur.
- Because if not, unit tests for the superclass would never succeed for the subclass
Interface Segregation Principle
- Many client specific interfaces are better than one general purpose interface
- The dependency of one class to another one should depend on the smallest possible interface
Dependency Inversion Principle
- Details should depend upon abstractions. Abstractions should not depend upon details.
- "The modules that implement a high level policy should not depend on the modules that implement the low level policies, but rather, they should depend on some well-defined interfaces. It stems from the realization that we must reverse the direction of these dependencies to avoid rigidity, fragility and immobility.
- Avoid designs which are:
- Rigid (Hard to change due to dependencies. Especially since dependencies are transitive.)
- Fragile (Changes cause unexpected bugs.)
- Immobile (Difficult to reuse due to implicit dependence on current application code.)
Principles of package cohesion
- Reuse/Release Equivalency Principle: The granule of reuse is the same as the granule of release. Only components that are released through a tracking system can be effectively reused.
- Common Closure Principle: Classes that change together, belong together.
- Common Reuse Principle: Classes that aren't reused together should not be grouped together.
Principles of Package Coupling
- The Acyclic Dependencies Principle: The dependency structure for released components must be a directed acyclic graph. There can be no cycles.
- The Stable Dependencies Principle: Dependencies between released categories must run in the direction of stability. The dependee must be more stable than the depender.
- The Stable Abstractions Principle: The more stable a class category is, the more it must consist of
abstract classes. A completely stable category should consist of nothing but
OOD Guidelines –(Design Rules for Best Designs)
During the design process, as we go from requirement and use-case to a system component, each component must satisfy that requirement, without affecting other requirements. Following are steps to avoid Design hazard:
- A subclass is coupled to its super-class in terms of attributes & methods
- High inheritance coupling is desirable
- Each specialization class should not inherit lots of unrelated & unneeded methods & attributes
Coupling Types and Degree
Cohesion (interaction within a single object or swcomponent)
- Reflects the ’single-purposeness’ of an object
- Method cohesion
- A method should carry only one function. Carrying multiple functions is undesirable.
Rules for Identifying Bad Design
OO Design Quality Metrics
Metrics (To measure the quality of an object-oriented design)
Interdependence (between the subsystems)
- Highinterdependent tend to be rigid, un-reusable , hard to maintain and cascade changes in dependent modules
- Collaboration of subsystems need interdependence
- Support communications within the design
- Isolate reusable elements from non-reusable elements, and
- Block the propagation of change due to maintenance
- Decide ability of design to survive change, or to be reused
- Fragile on single change
- “Good Dependency” is a dependency upon something that is very stable
- “Bad Dependency” is a dependency upon something that is instable
- Most stable classes of all, are classes that are both Independent and Responsible. Such classes have no reason to change, and lots of reasons not to change.
Class Categories: the granule of Reuse and Release
It is seldom that a class can be reused in isolation.
“Class Category” - A Class Category (hereinafter referred to as simply a category) is a group of highly cohesive classes that obey the following three rules:
- Classes within a category are closed together against any force of change. If one class must change, all of the classes within the category are likely to change.
- Classes within a category are reused together. Strongly interdependent and cannot be separated from each other. Thus if any attempt is made to reuse one class within the category, all the other classes must be reused with it.
- Classes within a category share some common function or achieve some common goal.
Three rules are listed in order of their importance. Rule 3 can be sacrificed for rule 2 which can, in turn, be sacrificed for rule 1.
The authors must provide releases of their categories and identify them with release numbers so that reusers can be assured that they can have access to versions of the category that will not be changed.
Responsibility, Independence and Stability of a category can be measured by counting the dependencies that interact with that category.
- Ca : Afferent Couplings : The number of classes outside this category that depend upon classes within this category
- Ce : Efferent Couplings: The number of classes inside this category that depend upon classes outside this categories
- I : Instability : (Ce ÷ (Ca+Ce)) : This metric has the range [0,1]
- I=0 indicates a maximally stable category
- I=1 indicates a maximally instable category
- Highly stable categories depend upon nothing
- Instable categories should not be
abstract, they should be concrete
- Desirably portion of the design to be flexible enough to withstand significant amount of change
Hope you got an interesting and easier understanding on OOAD.
- 24th April, 2011: Initial post