advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

Tutorials : Fine-tuning Abstraction :

Fine-tuning Abstraction

by Samudra Gupta

In the past two articles about application design, I explained three vital design techniques: the Open-Closed Principle, Liskov’s Substitution Principle, and the Dependency Inversion Principle. These principles address the creation of a more flexible design level capable of withstanding the growing pressure of scalability.

In discussing those principles we arrived at design solutions that are based on abstraction. Thus, one of the salient features of a well-designed system is the abstract coupling of different objects interacting with each other. A few points about abstraction remain to be discussed.

Namely:

  • To what level should abstraction take place?
  • When is the correct level achieved?

I'll try to answer these questions utilizing the Composite Reuse Principle and the Interface Segregation Principle.

Composite Reuse Principle

The Composite Reuse Principle (CRP) is a source of never-ending debate amongst designers. The basic idea of this principle is to favor composition over inheritance as a way of achieving polymorphism.

Polymorphism, in Object Oriented terminology, means that any particular class can exist as multiple distinct sub-classes (sub-types). The following is an example of polymorphism:

abstract class Animal {
  abstract void talk();
}

Class Dog extends Animal {
  public void talk() {
    System.out.println("Scooby dooby Doo");
  }
}

Class Cat extends Animal {
  public void talk() {
    System.out.println("Meow....");
  }
}


Animal is the super class, and it can exist in the form of either a Dog or a Cat. When objects exist in the real world, they exhibit some behavior to the external world. Thus, the Dog and Cat objects expose the behavior of talking and, as they talk differently, they are polymorphic.

The above example demonstrates how polymorphism can easily be achieved with inheritance. However, inheritance based polymorphism often is ineffective, as an explosion of subtypes may cause the system to run out of flexibility. Take a look at the following example:

Imagine that you have been assigned the task of designing a payroll system for an organization. As Christmas is near, your first job is to make some provision for employee bonus payments . The company has three types of employees: Permanent, Temporary and Part-time.

In your initial design, you have considered each employee to be a polymorph of the base type Employee. You have also determined that the bonus for all employees is calculated in a similar manner and defined the calculateBonus() method in the Employee class. The other operations, such as leave and insurance premium calculations, are specific to the type of Employee. Thus those methods are declared as abstract in the super class and provided the implementation in the specific Employee classes. The initial design is shown in Figure 1.


Figure 1: The initial Employee class hierarchy

Later, the project manager changed the rate at which part-time employee bonuses should be calculated. To accomplish that, simply override the calculateBonus() method in the PartTime class.

The manager is impressed. Then he asks that the company consultants get bonuses, calculated at the same rate as part-time employees.

  • You could create a new class called Consultant and make it a sub-class of PartTime to inherit the calculateBonus() implementation. However, this causes a problem with the class hierarchy, because Consultants are also Employees. The class hierarchy will always say that Consultants are part time employees, which they aren't. In addition, if on a future date, the Consultant receives a Permanent employee bonus, the hierarchy will not withstand the change.
  • Another possibility would be to override the calculateBonus() method in the Consultant class, and copy the same implementation of PartTime class there. However, duplicate code is not the reusability we desire.

The original class structure is highly limiting when new parameters are added. Lets now examine the following solution and explanation.

To date, we've made a fundamental assumption that the bonus calculation is a frozen arithmetic function and pushed it to the super class. In reality, the calculation of bonus can change algorithms more frequently, and each type of employee can have a unique bonus calculation algorithm. Inheritance is only applicable in the context of a generalized relationship where the sub-type is a super-type. Or, in other words, there is an ISA relationship. In Liskov’s Substitution Principle, the main criterion for the ISA relationship is whether the sub-class exposes the same behavior as the super-class. Each time one has to override the methods from the super class, one violates this principle and the super-class becomes a specialized version of the sub-class rather than a generalized version of the sub-class. Further, each time that occurs one runs the risk of having the same problem we are faced with in the previous example.

The elegant solution is to define an abstract BonusCalculator and attach the appropriate BonusCalculator instance to each Employee instance. The following design depicts the proposed solution (Figure 2):


Figure 2: The CRP based Employee class hierarchy

The diagram above demonstrates that the BonusCalculator is a composite of all the different Employee classes, and thus an extremely flexible polymorphism has been achieved. The algorithm can be changed at any time for bonus calculation by attaching a different implementation of the BonusCalculator to any of the Employee objects.

This is where Composition is a superior choice. Inheritance ties you to a particular implementation or forces you to give up the original idea of generalization by having to constantly override the super-class methods in each sub-class. This is, however, not exactly a limitation of inheritance but more of an issue with how the inheritance is applied. As you gain experience, you will find that utilizing CRP is a safer approach.


Samudra Gupta has six years of Java related application development experience. He has been involved in various research based projects in Java including e-commerece based and application design and development projects. He is based in the United Kingdom. In his freetime, he is a columnist in different Java Magazines and Journals and loves to play contract bridge.

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

XML error: undefined entity at line 19
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

Linux Vendors Head to the Cloud in Search of Cash
iPhone 3GS: Overheating Fears, OS Update Nears
PostgreSQL 8.4 Revs Up Database Admin, Security
PHP 5.3 Accelerates PHP
Sun Releases NetBeans 6.7 IDE for Java, PHP
Why Firefox Doesn't Take Google Chrome Features
First Major PHP Update in Years Coming Soon
Red Hat CEO Calls on Oracle to Keep Java Open
Google Widens AdSense for iPhone, Android Apps
Eclipse Galileo Releases 33 Open Source Projects

A Taste of JavaFX for the Uninitiated
A Guide to Caching and Compression for High Performance Web Applications
How User-Centered Design Can Put User Stories in Proper Context
Explore C# 4's New Dynamic Types and Named/Optional Parameters
Enterprise Architecture: The Journey Begins Here, Part 2
Create a Syslog Sender/Receiver Using the MS Winsock Control
AMD CodeAnalyst Helps Developers Optimize and Tune Applications
Securing Microsoft's Cloud Infrastructure
Introducing the Azure Services Platform
An Introduction to Microsoft .NET Services for Developers

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs