Avoid Global Data
I have just started to read a new book titled The pragmatic programmer. I am quickly realizing why everyone has dubbed this book a must have for all programmers. I am only into the 2nd chapter but I already found something I would like to share with you. This may seem like a no brainer to most of you but to some beginners this is a very important lesson to building a reusable & scalable system.
So how and why would we avoid global data. Lets first examine what The Pragmatic programmer would tell us about global data.
Every time your code references global data, it ties itself into the other component that share that data. In general your code is easier to understand and maintain if you explicitly pass any required context into your modules. In object oriented applications, context is often passed as parameters to objects constructors.Basically what this tells us is that it is poor design to reference global data in our component when we can create a more maintainable & reusable component by passing that data as a parameter. We will look at some code below to see how this applies in our world.
Lets say for example that in our Application component we define some global data and place it into our application scope like so.
<cfset application.dbuser = "user">
<cfset application.dbpass = "pass">
This is code that we all have written at one time (or something similar) and there is nothing wrong with this code. Here is where our mistake is made. Lets say we create an Employee component and in the component we need to access our database. We need to know these parameters so beginners may have the desire to write the following code.
<cffunction name="getAll" access="public" returntype="query">
<cfset var local = "">
<cfquery name="local" datasource="#application.dsn#">
SELECT * FROM Employee
</cfquery>
<cfreturn local>
</cffunction>
</cfcomponent>
So your thinking to yourself what is wrong with that. It is maintainable because if our dsn changes for some reason we only have to change it in one place. You would be right but it also is not very reusable. The best answer is to stay away from global data and pass it into your component as an instance parameter. So how do we do that, simple lets look at the answer.
<cfset variables.dsn = "">
<cffunction name="init" access="public" returntype="Employee">
<cfargument name="dsn" type="string" required="true">
<cfset variables.dsn = arguments.dsn>
<cfreturn this>
</cffunction>
<cffunction name="getAll" access="public" returntype="query">
<cfset var local = "">
<cfquery name="local" datasource="#variables.dsn#">
SELECT * FROM Employee
</cfquery>
<cfreturn local>
</cffunction>
</cfcomponent>
This code makes our component maintainable and reusable. Now we could pass our global data into the component. The moral of the story kids, avoid global data in your components.
<cfset employees = empObj.getAll()>



