Back To Basics

Here the other day, I got the question: ”How do I become a good developer? (OOP)”…

My reply…… Know your patterns!

It’s hard to write a blog post on basic object design and OOP without writing about the analysis aspect of OOP. Even still, I do not explain about Use case analysis, Domain models etc. even though these are equally important for the development process.

When starting to develop applications, nobody has all the ideas in their heads at first. It’s a combination of experience and knowledge of the basic patterns that make the application come to life. The more experience the developer has, the more of the “design” goes on by reflex and inside the head, and thus faster. Just a little note here: The fact that the design comes by reflex and goes on inside the head of the developer is also a downfall! If you’re not able to document the process of your work, you have failed in designing it properly! The software you’re designing should be documented to an extend that another developer can pick up the code and develop on it further with easy understanding of what is going on. That’s my humble opinion.

There are many details to developing, and in this blog post I don’t go into detail about the Unified Process, Scrum or any other iterative analysis & design development processes, even though these processes are at the heart of Object Oriented Programming. Actually, to be a good developer, the first question you need to answer is – What is Object Oriented Programming? And thereafter you can throw yourself at object design patterns.

There are many ways to answer what OOP is, but here is my version:

OOP is a way to create an abstraction of real life, a way to model objects so that the software is maintainable and manageable. You do this to be able to divide complexity into smaller pieces to make a better overview. E.g. If you are working on an airplane, then you model the necessary pieces only to be able to have a better overview. There is no need to model the outside of the plane, if the software only revolves around the inside of the plane.

This is done by following the three fundamental pillars of OOP:

  1. Encapsulation
  2. Inheritance
  3. Polymorphism

Encapsulation – A way to hide complex functionality from other objects, and that way it is also used to protect data and methods/functions in a class from being accessed. E.g. If a person walks up to an elevator and pushes the button to get to another floor, then that person is shielded from the “physical” things such as cables, cogs etc. and from the “software” things such as algorithms etc.

Inheritance – Enhances code reuse, by letting a programmer inherit from a class, and further build upon this class in own code. E.g. A developer made a class called Animal, and you want to utilize the functionality of this class, but still define your own functionality. You could then inherit from Animal into your own Dog class, and utilize the functionality inside Animal, while further defining your own in the Dog class. This also forms the basis for polymorphism.

Polymorphism - Makes it possible to access objects of different types through one reference variable. This makes that the same method/function name can have different implementations.

This is not necessarily adequate but it is a step in the right direction, and I urge you to read more about the pillars of OOP.

Basic patterns of object design

Now we enter the realm of object design, and it is here we find some basic patterns that assist the developer in creating an application that lends itself to the pillars of OOP, and makes the design strong and maintainable. Please keep in mind that these patterns are the basic of OOP so there’s no magic going on here. I’ll start by listing some of the patterns and follow up with a short explanation and a question you should ask yourself when applying the relevant pattern.

  • Creator
  • Information Expert (Expert)
  • Low Coupling
  • Controller
  • High Cohesion

There are more than mentioned above, but the listed patterns provide the stepping stones for object design. Patterns I won’t mention here are:

  • Polymorphism
  • MVC (Model View Component) *
  • Pure Fabrication
  • Indirection
  • Protected Variations

* When you follow the basic of the mentioned pattern principles, you should end up with the result of the MVC pattern.

When an understanding of the six mentioned patterns are in place, I urge you to read up on the last basic patterns. There might be more basic patterns out there, but the before mentioned are the ones I feel are necessary to understand object design.

The nine patterns listed are all part of the “GRASP Pattern” Which stands for General Responsibility Assignment Software Patterns. I know that it should be called “GRAS Patterns” but the emphasis is on the importance of the developer does “GRASP” the concept and therefore the name.

Creator

The most common thing in software development is the creation of objects, and here there are some principles surrounding who should have the responsibility of creating the object.

Question: Who should be responsible for creating a new instance of the class?

Answer: Let class Two create class One if:

  • Class Two contains Class One or Compositely Aggregates Class One **
  • Class Two “records” Class One
  • Class Two uses Class One to a large extend
  • Class Two contains the initializing data for Class One (Which makes it an Information Expert in regards to creating Class One)

If more bullets fit, go for the first – Contains or Compositely Aggregates.

E.g. when having to create a chess game, which object should create the chess-piece instance, ChessBoard class or Dice class? Well, the ChessBoard and ChessPiece classes have a Compositly Aggregates relationship, and therefore ChessBoard would be best.

** Composition: Imagine that you have a Chess board (Composite) which contains Chess-Pieces (Parts) then the Chess-board (Composite) is always responsible for creation and deletion of its Chess-Pieces (parts). An instance of the part (Chess-Piece) belongs to only one composite (Chess-board) instance at a time. And last but not least, the part (Chess-Piece) must always belong to a composite (Chess-board), meaning that cannot exist a Chess-Piece if there is no Chess-board. This is the core meaning of Composition.

Information Expert

When developing software, there may be thousands of classes that require thousands of responsibilities to be fulfilled. These responsibilities should be assigned to make the code easier to understand, maintainable and lend itself towards code reuse.

Question: What is the principle of assigning responsibilities to objects?

Answer: Assign the responsibility to the class that has the Information necessary to fulfill the responsibility.

The important thing here is to start out by clearly stating the responsibility! E.g. who should be responsible for knowing the total amount of chess-pieces?

Do note that this could involve many classes in order to get the information needed. E.g.

Design Class

Responsibility

Sale

Knows sale total

SalesLineItem

Knows line item subtotal

ProductDescription

Knows product price

To fulfill the responsibility of knowing the sale’s total you need to assign responsibility across several classes, which is also known as partial Information Experts collaboration.

Low Coupling

In development of OO applications it is as mentioned before important to have low dependencies among the objects, so that changes to an object doesn’t effect a long range of objects, and to enhance the ability of code reuse. Low Coupling is a way to “measure” how strong one object is depended (has knowledge of or relies) on other object. High Coupling is very undesirable because it forces local changes due to changes in related classes, makes code reuse almost impossible due to the high degree of dependency, and it makes the code harder to understand. All of this strives directly against the pillars of OOP.

Question: How to support low dependencies, low impact on changes and high code reuse

Answer: Make sure to assign responsibilities so that coupling is low, and always use this principle to consider alternatives.

one

Above image shows BookStoreRegister creating both BookStoreSale and Payment. But in reality there is no need for BookStoreRegister to have any knowledge of Payment.

two

Instead, using the principle of Low Coupling, let BookStoreSale have the knowledge of a payment, and minimize the dependencies among the objects.

Controller

This is a very comprehensive pattern principle, and I will only briefly describe it, but encourage you to read more elsewhere.

A controller - sometimes also referred to as a Facade – is the first object after the UI and is responsible for receiving or handling operations (input events). The overall meaning with this principle lies in, that the GUI classes should not have any knowledge of the data handling classes in the system (and the classes should not have any dependencies on the GUI classes. In short, you should be able to apply new GUI classes to a system without affecting the data handling classes.

Question: What first object after the UI layer should receive and coordinate (forward messages) a system operation?

Answer: The responsibility should be appointed to a class of one of the following choices:

  • It is a model of the overall “system”, or a “root object”.
  • It represents a use case scenario.

Often you would invent a class especially for the purpose, and they are often identified by the name ending on Handler (or Session for web development). (IMAGE THREE)

three

The job of this Controller class is not to handle the events, but merely to foreward the messages to the correct classes. Usually there are several controller classes in a system, and controller classes are often grouped to forward messages to multiple objects at a time. Just be aware of bloated controllers!

When talking about controller pattern principles, there are some things you should dig deeper into that I will not go into here:

  • Boundary objects
  • Entity objects
  • Command patterns
  • Pure Fabrication

High Cohesion

When designing objects, High Cohesion is a measure of how focused the responsibilities are within an object (keep it simple stupid). A class shouldn’t do too many unrelated things, or do too much work! This would yield low cohesion, which makes the classes; hard to understand, hard to reuse, hard to maintain, and make them dependent and highly affected to changes elsewhere in the system.

Question: How to keep objects focused, understandable and maintainable?

Answer: Assign responsibility to honor High Cohesion.

This pattern principle is highly affected by the before mentioned patterns, but in general the aim should be on yielding Low Coupling and High Cohesion when designing these objects.

The patterns listed in this blog post are only a small corner of the heart of OOP. But it should give the basic knowledge of object design. This blog post is only intended as an appetizer towards OOP and object design, and does not provide full justice to the subject. Please use this post as a short appetizer and go explore more on this fascinating subject.

I can recommend this book for reading - Object Oriented Software Engineering Using UML, Patterns, and Java - written by Bernd Bruegge & Allen H. Dutoit.

Currently rated 1.5 by 16 people

  • Currently 1.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: AllanJP
Posted on: 11/3/2010 at 3:36 PM
Categories: Programming | Basics
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed