Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


AOP, IoC, and OO Design Patterns Without Frameworks
Finding the right balance

I'd like to share some of the design highlights of a large-scale content distributing system I worked on a while back. Some of the highlights may seem trivial; some may be a little more complicated. To me, software design is a matter of finding a balance between applying available technologies and fulfilling real-world requirements and constraints. The goal of design is always to ensure both the runtime and development-time quality of the software.

I'll be using two of the components from the project, Scheduling Management Component (SMC) and the Data Access Layer (DAL), for purposes of illustration. The function of SMC is to monitor the database and detect any newly added or updated content, and schedule that content for delivery based on some business logics. The DAL, as its name implies, provides data access services.

Extensibility by OOP Patterns and Principles
In the early design phase of SMC, we quickly lay out some of the candidate classes, as well as the relationships among them. In UML notation, class details are omitted at this stage. Figure 1 shows some of the major classes. The classes are by no means final, and neither are the relationships. We're trying, however, to capture the business requirements as much as possible.

We've designed the Schedule-Manager class as the façade of this component. It exposes external APIs. Other components that need to interact with SMC do so through this class. ScheduleManager is also in charge of managing the lifecycles of classes inside SMC.

One of the business requirements is that the first production release of the software won't support clustered deployment, but it will in later releases. One of the keys to supporting clustering is managing the states of the component instances deployed across the clustered nodes so that they're always in sync. Keeping this in mind, we decide to centralize the cluster-sensitive states of all the SMC classes into one class rather than having each class manage its own states. This results in a SchedulingContext class. This class knows how to save and retrieve various states of the component. When the time to support the cluster comes along, instead of having to open up each class and make changes, all we have to do is change the SchedulingContext class - that modifyies the way this class accesses states so that all the clustered instances share the same states, virtually or physically.

The UML diagram in Figure 2 shows some major classes after introducing the SchedulingContext class.

One issue we immediately notice with this design is the tight coupling between the SchedulingContext class and the classes that depend on it. As you can see, quite a number of classes depend on the SchedulingContext class. If we have to change the SchedulingContext class for any reasons (fixing bugs, adding new business features, switching to other application server, etc.), chances are we also have to make changes to the dependent classes.

Following OO best practices, interfaces are good at promoting loose coupling. In fact, it's always a good idea to code to interfaces rather than concrete classes (another simple yet powerful OO principle). The solution is simple enough - we abstract the scheduling context by making SchedulingContext an interface. We also want this interface's client to be unaware of the actual implementation, and the GoF Abstract Factory Pattern does the job.

The design of the Scheduling Context is shown in Figure 3. When it comes time to support clustering, we can do it with little programming. It makes it a lot easier to maintain the software after it goes into production. We also avoid vendor lock-in by shielding the cluster-sensitive implementation, which is likely to be vendor-specific.

Another consequence of moving the states of an individual class into SchedulingContext is that we can now design other stateless classes, which is good because:

  • A stateless class is thread-safe, avoiding potential issues in a multithreading environment (which SMC is)
  • Generally speaking, stateless objects scale better
  • Stateless classes are easier to maintain

Note that, at this point, ScheduleManager and SchedulingContent are acting together as the "container" of the other classes in the sense that:

  • The ScheduleManager class intercepts all client calls to the component
  • The ScheduleManager class manages the lifecycles of other classes
  • The SchedulingContext interface provides a gateway to access component states

This is intended and, as you'll see later, we'll use the container-like feature of these two classes more in our design.

Decoupling with IoC Pattern
So far, everything is pretty simple and straightforward. What else can we do to make the design better?

With the current design, unit testing isn't a trivial task. Let's take the FNDTaskPuller class as an example. Listing 1 shows the simplified version of this class. For demonstration purposes, let's assume this class has a business method, someBizMethod().

To test this class, we'd create a test class similar to the one shown in Listing 2.

What's the problem with this code? We're testing SchedulingContextSimpleImpl (which is the concrete class of SchedulingContext) indirectly. But we really mean to test the FNDTaskPuller class. This isn't right. As we all know a unit test should never go outside of its own class boundary.

Furthermore, it's hard to control the states of the SchedulingContextSimpleImpl in order to test the different behaviors of FNDTaskPuller class.

In practice, a common technique to overcome this kind of tight coupling is using mock objects, which can assist in separating unit tests. Mock objects themselves, however, require extra coding efforts. This extra coding effort can be significant, buggy, and cause maintenance problems. What more? Developers have to replace mock objects with real classes at deployment.

The reason for this problem is the way we acquire the reference to the SchedulingContext object in the FNDTaskPuller class. In this case, the FNDTaskPuller class is asking for a reference to a SchedulingContext object. Explicitly.

To get around this, we need to change the way we obtain an object reference. This is where Inversion of Control (IoC) comes into play.

With IoC, objects obtain references to their dependent objects passively. The IoC container literally "injects" the dependency into the classes.

Now, we need an IoC container for our design to wire the objects. We have the choice of using an existing container product or building our own. Normally in-house framework building is considered a bad practice because of its complexity and inefficiency. However, we decided to do it anyway after carefully figuring out what we really needed. Some of the reasons are:

  • We don't intend to build a framework that supports complete IoC features. Rather, our goal is to provide a feasible solution to our immediate problem: loosening up the coupling between SchedulingContext and other classes. At this point, some simple dependency wiring functions will do the trick.
  • The team didn't have enough experience with third-party containers when we started development, and the project timeline was a tight learning curve.
  • The team had to use some legacy code and worried that it would require some architectural modifications to integrate third-party containers with the legacy codes.
  • It's a good starting point for developers to get their feet wet on IoC concepts and implementation.

Our solution was to embed the simple dependency wiring functions in the ScheduleManager class, which, as mentioned, was already acting as the SMC "container." It also made sense to embed the IoC functions in this class. Because of the simplicity of construction injection, we refactored all the classes depending on the SchedulingContext so that they were ready for constructor injection. Listing 3 gives the FNDTaskPuller class as an example.

All we have to do in the ScheduleManager class is to instantiate a SchedulingContext object and assign it to classes that need a reference to it. If, some time in the future, a full IoC container is needed, we can just modify the ScheduleManager class.

Taking Care of Scattered Code
While designing the data access layer, we foresaw that there would be a lot of scattered "plumping" code - code that doesn't do anything related to business functions. They are only here to fulfill middleware functions: JNDI lookup, JDBC resource management, exception handling, etc. This code will spread into almost all data access objects (DAOs) and, in most cases, this code is identical method to method. We all hate scattered code because it's a maintenance nightmare, is error-prone, and makes code hard to understand.

List 2 is an example of a how we would have implemented our data access methods without AOP.

In Listing 4, only one line of the code is actually "doing something." The rest is just "plumping" code. When "plumping" code starts leaking into your application, chances are you'll find yourself hunting down all the application code when requirements change.

There's one thing we can do. While OOP makes software design modular, AOP makes code modular. And modularity is good.

Once again, we faced the choice of using an existing AOP framework or building our own. We decided not to use any of these frameworks for the same reason why we didn't use a IoC container. Instead, we separate the concerns programmatically in our code. Although this is not the most elegant, cleanest way, it's the fastest, which, in our case, is a big gain.

To separate the cross-cutting concerns from the DAOs, we came up with the following class design:

  • DAO classes. These are classes that implement data access functions. There can be an arbitrary number of DAO classes, and they're POJOs.
  • DAOFactory is the advice class. It implements the cross-cutting concerns. It also defines pointcuts, in our case, all DAO methods. It does so by handing out proxy objects of the corresponding DAO classes.


About Jinsong Yang
Jinsong Yang is a senior application engineer at Warnerbros. Advanced Digital Services, and is a Sun Certified Enterprise Architect. He has devoted the last six-plus years to designing and integrating large-scale Java EE applications. He holds an MS in computer science from UCLA.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Enterprise Open Source Magazine Latest Stories . . .
Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP). The...
With Cloud Expo 2012 New York (10th Cloud Expo) just four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have technical and st...
AMD said late Tuesday that its chief sales officer Emilio Ghilardi had left the company and that CEO and president Rory Read is going to do his job while a replacement is sought. AMD didn’t say why Ghilardi left but it’s assumed Read wants his own people. Read is relatively new to th...
During the lifespan of M3 (Monitis Monitor Manager) there has always been something lacking – timers. M3 execution procedure was outlined in this previous article. The execution mentioned in the latter was a one-time-execution, whereas server monitoring requires periodic invocati...
Red Hat is putting its bought-in Gluster scale-out NAS storage technology, acquired in October, on the Amazon cloud. It’s styled Red Hat Virtual Storage Appliance for Amazon Web Services and other clouds are supposed to follow in short order.
A new episode of the screencast series is now available at the OpenNebula YouTube Channel. This screencast demonstrates the new easily-customizable self-service portal for cloud consumers. Its aim is to offer a simplified access to shared infrastructure for non-IT end users. The scree...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON Featured Whitepapers
ADS BY GOOGLE