Skip to content

CFC Primer Part 4: Encapsulation and Information Hiding

thofrey edited this page Apr 1, 2014 · 8 revisions

By Matt Woodward (matt at mach-ii.com)

Table of Contents

  1. Encapsulation and Information Hiding
  2. Next parts of this primer

Encapsulation and Information Hiding

Encapsulation and information hiding are two very important concepts of object-oriented programming. Both of these are available to CFML developers by using CFCs in an OO fashion.

In its simplest sense, encapsulation refers to bundling together, into a single component, both data as well as the methods that operate on that data.

A related but slightly different concept is information hiding, which refers to hiding the inner workings or implementation details of functionality within software components from other components in the application. If the inner workings of a particular method in an object change, the rest of the system should not even be aware that the change has occurred, as long as the arguments passed to the method and the data type returned from the method do not change. This stable, unchanging external interface is critical to the stability and flexibility of an OO application.

Let's look at a couple of examples of information hiding to illustrate how this works within the context of a CFC. First, let's add a getAge() method to the Person CFC. Another component calling this method should not need to know how the age is calculated; it only needs to know that the Person CFC has a getAge() method that returns the person's age.

The getAge() method might look something like this:

    <cffunction name="getAge" access="public" output="false" returntype="numeric"
        hint="I return the age of the Person">
        <cfreturn dateDiff("y", getBirthdate(), now()) />
    </cffunction>

By wrapping the functionality to calculate the person's age in a <cffunction>, the implementation details (i.e., business logic) of this function are hidden to the caller. In this simple example, information hiding probably is not critical, but it is easy to see the power of hiding these details from the components calling this method. Since the Person CFC owns both its data and its behavior, the means to calculate the age could be changed at any time and a component calling the getAge() method would be none the wiser.

Now let's add a getSalary() method to the Person CFC (see below). This is sensitive data to which individuals should have limited access. Since the salary variable is in the CFC's variables scope, a component within the application wanting to retrieve this information needs to go through the getter method to access it. This gives developers the opportunity to add security to the getSalary() method by requiring the caller to pass in the current user's user type, for example.

In a real application, security responsibilities would likely fall elsewhere in the architecture (i.e., they would not exist directly in a single method in the Person CFC), but this example works well for illustrative purposes.

    <cffunction name="getSalary" access="public" output="false" returntype="numeric"
        hint="I return the Person's salary">
        <cfargument name="userType" type="string" required="true" />

        <cfif arguments.userType is not "manager">
            <cfthrow type="securityError" message="Security Violation"
                detail="You do not have permission to access the salary." />
        <cfelse>
            <cfreturn variables.salary />
        </cfif>
    </cffunction>

If the type of user that can access salary data were to change, or if the way in which the user type was determined within the getSalary method were to change, the rest of the application should not be aware of the change and should not break as a result of the change.

Building all CFCs in this way helps developers create systems that can be more easily maintained because a change to one piece of the application has little or no impact on any other part of the application.

Next parts of this primer

Clone this wiki locally