Kola Oyedeji

Subscribe to Kola Oyedeji: eMailAlertsEmail Alerts
Get Kola Oyedeji: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: ColdFusion on Ulitzer

CFDJ: Article

Don't Talk to Strangers!

ColdFusion components and the Law of Demeter

In these examples, the Person component "me" is returning the address component on which we then call the getPostCode function. The problem with this is that we have now coupled this code to two components. Say, for example, the address is now stored internally in a structure, not a component, and the getAddress function returns a structure instead of an Address object, we have to change this code. Similarly, if the address component method changes, perhaps the name of the getPostCode method is changed or the getPostCode method is removed completely, again we have to change this code.

Of course, changes to your public API will impact the code that uses it, but taking the time to think through your public API and how functionality is exposed will pay dividends down the road. Encapsulating the internals of your components prevents other code from being written based on these internals. This frees you to change the implementation of such components without breaking code that uses your component (provided the arguments and return values are the same). This also is the reason it's often recommended to not expose variables in the THIS scope.

Applying the Law of Demeter, instead of directly referencing the address component returned from the Person CFC, we add the following function to the Person component:

<cffunction name="getPostCode" returns="string" output="false" >
    <cfreturn variables.personsAddressCFC.getPostCode() />
</cffunction>

We then change our calling code to call this new method, which is really nothing more than a wrapper method delegating the call to the actual address component held in the variables scope of the component.

<cfset someGuy = createObject("component","Person") />
<cfset pc = someGuy.getPostCode() />

Now if we change how the address is stored in the person CFC, if we change it to a structure - and change the person getPostCode function:

<cffunction name="getPostCode" returns="string" output="false" >
    <cfreturn variables.personsAddressStruct.postCode />
</cffunction>

As you can see, following the Law of Demeter now shields the calling code from changes to the Address CFC. The address may be internally stored as a CFC, a struct, or a Java class, but the type makes no difference to the code calling the getPostCode function. As long as a string is still returned from the function as expected, this shields calling code from the impact of changes. We have minimized the scope of what needs to be changed so that code that now simply needs to get the postcode is not impacted by changes to the address component.

As with any design decision, there is a trade-off. One disadvantage of strictly applying the Law of Demeter is that you can end up with CFCs that contain many functions that do nothing more than delegate calls to other CFCs.

I hope that through these examples you can see that the Law of Demeter can help reduce the amount of dependencies between components in your applications. This ultimately leads to easier application maintenance.

References
www.ccs.neu.edu/research/demeter/papers/law-of-demeter/oopsla88-law-of-demeter.pdf
www.cmcrossroads.com/bradapp/docs/demeter-intro.html

More Stories By Kola Oyedeji

Kola Oyedeji is technical director of Vivid Lime, a London-based full services agency. Prior to that, he was a senior software developer for the Collinson Group, developing Enterprise Loyalty and Insurance Systems. Kola holds a BSc in Computer and Information systems. His blog is available at www.coolskool.blog-city.com.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.