NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used.
I noticed that there is very little talk about patterns and ColdFusion so I decided to talk a little.
First allow me to clarify that patterns are not solid rules, they are just suggestions on how to deal with common problems. You can combine different patterns as well to modify a pattern to fit your needs.
For the purpose of this lesson, lets assume that you are working for a company that develop pet simulators; also, lets assume that you work in a team together with many developers.
You company wish to create a dog simulator which allows us show different type of dogs and dog species.
Originally, we could have use standard Object Oriented techniques and created on Dog super-class from which each dog species inherit the basic functions:
In ColdFusion, your code would similar to the following (I am only writing the super-class and sub-classes):
<!--- Dog.cfc ---> <cfcomponent name="Dog"> <cffunction name="bark"> <!--- Your code ---> </cffunction> <cffunction name="run"> <!--- Your code ---> </cffunction> </cfcomponent>
<!--- ChihuahuaDog.cfc ---> <cfcomponent name="ChihuahuaDog" extends="Dog"> <cffunction name="display"> <!--- Your code ---> </cffunction> </cfcomponent>
Now this is a super-class and subclasses as an example that the rest of programmers are going to be adding different species of dogs.
Out of the blue, one of the managers come with the idea to add a new functionality: jump();
So you say to yourself that you only need to add a jump method to the Dog class then all the different dogs will inherit this function.
Everything goes well until until one of the managers approach you in a very aggressive matter. This manager is angry at you because when presenting the demo of the software he finish doing a fool of himself. The reason was that someone requested to add a ceramic dog. When the manager was presenting the software, ceramic dogs where jumping everywhere when they are not supposed to be able to jump in the first place! In order work, when you added the extra function, you were adding a behavior that should be applied to some sub-classes.
So you think that you could just override the jump() method in in the ToyDog subclass that way you don’t have to worry about it.
However, the ceramic dog cannot bark nor run either. So you do the same as you did with the jump() function. Later on, someone decided that they need to add a toy dog which cannot run, but it can bark, jump, and grow its eyes! You are starting to realize that in any moment someone may decided to add some type of dog that you were not thinking that could exist. Perhaps using inheritance was not great idea after all!
So following the previous idea would result in a maintenance nightmare. The more type and species your company keeps adding, the more maintenance is required; therefore, a new idea shows up in your head: “How about using interfaces?”
|Think about interfaces as an standard that when establish everyone must follow.
A construction, for example, follow different standards and many constructions are different one from the other with different requirements. For some things, they may share similarities, but for others, they can be different. While many constructions may share the fact that they use cement for their base, the wall could be build from a different material which must follow an establish standard.
If this example doesn’t help you, please leave a comment and I will try to come up with something else.
By using interfaces, you could take out those functions such as bark(), run() and jump() that may not we usable and leave those functions that will be use the more sure. In that way when a dog is supposed to jump, then you can implement the interface and have have the jump method.
Think that interface allow you do define behaviors for your classes.
In ColdFusion, we can use interfaces, for example:
The following is the InterfaceBarking.cfc file:
<cfinterface name="InterfaceBarking" hint="Defines the a barking interface for a dog."> <cffunction name="bark" access="public" returntype="any" output="false" hint="Allows the dog to bark."> </cffunction> </cfinterface>
Now the ChihuahuaDog.cfc may look like the follow:
<!--- ChihuahuaDog.cfc ---> <cfcomponent name="ChihuahuaDog" extends="Dog" Implements="InterfaceBarking"> <cffunction name="display"> <!--- Your code ---> </cffunction> <cffunction name="bark"> <!--- Your code ---> </cffunction> </cfcomponent>
Extends points to the parent class (super-class) and Implements points to the interface
At this point is good to introduce a design principle so we can remember in the future:
|First identify which aspect of the program may vary and separate them from the rest that will stay the same.|
In other words, in order to not affect the rest of your code, take those components that variate and encapsulate them. In this way, you don’t produce unpredicted behaviors. Also, this introduce us to another design principle:
|Do not program the implementation but the interface instead.|