spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / spring / 2 To page 1current pageTo page 3To page 4
[previous][next]

Technical Lead
Thomson Reuters (Markets) LLC
US-NY-New York

Justtechjobs.com Post A Job | Post A Resume
Developer News
Microsoft Shows Off Silverlight 4, IE9 Plans
Metasploit Expands Vulnerability Test Framework
HyperCard Reborn?


Spring in Action: A Spring Jump Start. Part 2

Who’s calling who?

The main problem so far with KnightOfTheRoundTable is with how it obtains a HolyGrailQuest. Whether it is instantiating a new HolyGrail instance or obtaining one via JNDI, each knight is responsible for getting its own quest (as shown in figure 1.2). Therefore, there is no way to test the knight class in isolation. As it

Figure 1.2 A knight is responsible for getting its own quest, through instantiation or some other means.

stands, every time you test KnightOfTheRoundTable, you will also indirectly test HolyGrailQuest.

What’s more, you have no way of telling HolyGrailQuest to behave differently (e.g., return null or throw a GrailNotFoundException) for different tests. What would help is if you could create a mock implementation of HolyGrailQuest that lets you decide how it behaves. But even if you were to create a mock implementation, KnightOfTheRoundTable still retrieves its own HolyGrailQuest, meaning you would have to make a change to KnightOfTheRoundTable to retrieve the mock quest for testing purposes (and then change it back for production).

Decoupling with interfaces

The problem, in a word, is coupling. At this point, KnightOfTheRoundTable is statically coupled to HolyGrailQuest. They’re handcuffed together in such a way that you can’t have a KnightOfTheRoundTable without also having a HolyGrailQuest. Coupling is a two-headed beast. On one hand, tightly coupled code is difficult to test, difficult to reuse, difficult to understand, and typically exhibits “whack-amole” bugs (i.e., fixing one bug results in the creation of one or more new bugs). On the other hand, completely uncoupled code doesn’t do anything. In order to do anything useful, classes need to know about each other somehow. Coupling is necessary, but it should be managed very carefully.

A common technique used to reduce coupling is to hide implementation details behind interfaces so that the actual implementation class can be swapped out without impacting the client class. For example, suppose you were to create a Quest interface:

Then, you change HolyGrailQuest to implement this interface. Also, notice that embark now returns an Object and throws a QuestException.

Also, the following method must also change in KnightOfTheRoundTable to be compatible with these Quest types:

Likewise, you could also have KnightOfTheRoundTable implement the following Knight interface:

Hiding your class’s implementation behind interfaces is certainly a step in the right direction. But where many developers fall short is in how they retrieve a Quest instance. For example, consider this possible change to KnightOfTheRoundTable:

Here the KnightOfTheRoundTable class embarks on a quest through the Quest interface. But, the knight still retrieves a specific type of Quest (here a HolyGrailQuest). This isn’t much better than before. A KnightOfTheRoundTable is stuck going only on quests for the Holy Grail and no other types of quest.

Giving and taking

The question you should be asking at this point is whether or not a knight should be responsible for obtaining a quest. Or, should a knight be given a quest to embark upon?

Consider the following change to KnightOfTheRoundTable:

Notice the difference? Compare figure 1.3 with figure 1.2 to see the difference in how a knight obtains its quest. Now the knight is given a quest instead of retrieving one itself. KnightOfTheRoundTable is no longer responsible for retrieving its own quests. And because it only knows about a quest through the Quest interface, you could give a knight any implementation of Quest you want. In a production system, maybe you would give it a HolyGrailQuest, but in a test case you would give it a mock implementation of Quest.

In a nutshell, that is what inversion of control is all about: the responsibility of coordinating collaboration between dependent objects is transferred away from the objects themselves. And that’s where lightweight container frameworks, such as Spring, come into play.

home / programming / spring / 2 To page 1current pageTo page 3To page 4
[previous][next]

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

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

webref The latest from WebReference.com Browse >
Rolling Out Your Own HTML Application Version Control · HTML 5: Client-side Storage · Working with Ajax Server Extensions
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Wi-Fi Product Watch, November 2009 · Chip Market Recovering From '08 Collapse · Low-Cost Tools to Kickstart Your New Business

Created: March 27, 2003
Revised: March 17, 2005

URL: http://webreference.com/programing/spring/2