官术网_书友最值得收藏!

The basic data object concept

Now we create the function for assigning the encapsulated variables of the object when it is created. We are now ready to write the next version of the calling page. We are only going to change two things on that page. We will change the line where we were creating a second recordset to a call to the method for performing the assigning of the internal variable values in the object. Then we will change our content section of the code to use the object getters to pull the encapsulated variable values. The highlighted rows are the ones changed.

<!--- Example: 2_6.cfm --->
<!--- Processing --->
<cfparam name="url.id" default="0">
<cfscript>
objProduct = createObject("component","product_2").init();
rsProducts = objProduct.getRecordset();
objProduct.load(url.id); 
</cfscript>
<!--- Content --->
<ul><cfoutput query="rsProducts">
<li><a href="?id=#rsProducts.id#">#rsProducts.name#</a> </li></cfoutput>
</ul>
<cfif objProduct.get_name() NEQ ""> 
<cfoutput>
<table>
<tr>
<th>Product</th>
<td>#objProduct.get_name()#</td> 
</tr>
<tr>
<th>Description</th>
<td>#objProduct.get_description()#</td> 
</tr>
<tr>
<th>Price</th>
<td>#dollarFormat(objProduct.get_price())#</td> 
</tr>
</table>
</cfoutput>
</cfif>

What we are doing is very good for making it easier and easier to separate processing from markup. We are using the same object to do our processing and returning data for displaying our output on the markup content section of the page. This is a great way to reuse things over and over.

One of the goals of objects is to maximize code reuse. What we are about to do is known as "refactoring" our object. We are going to take what we have and make it simpler. Right now, we have a bunch of getters and setters. Every new data-focused object is going to have unique getters and setters. What this means is that the interface on this object is not very portable. What will we do when we build our shopping cart? The item object will have a different interface than the product item. It is not always possible to match the interfaces so they have common methods and arguments. Yet, in pragmatic terms it is usually better to do things that way.

Let's take our getters and setters and move them all to one getter and one setter. The getter can retrieve all the hidden attributes and the setter would be able to do the same thing. Since we are not setting any values at this time, we will leave those as they are until later. The principle is the same. We will remove all of the getter functions and save the new CFC as product_3.cfm for this exercise. Add the new get() method to the top of the getter and setter section. We can also see in our code that we use arguments.attribute to check if a variable exists and if so pull it. If a false field is requested, then we return an empty field in this case, rather than an error.

<!--- Getter and Setter Methods --->
<cffunction name="get" access="public" output="false">
<cfargument name="attribute" required="true">
<cfset var myReturn = "">
<cfif structKeyExists(variables.attributes,arguments.attribute)>
<cfreturn variables.attributes[arguments.attribute] />
<cfelse>
<cfreturn "">
</cfif>
</cffunction>

Now we need to modify or create another version of the calling page. Don't forget that we just created a new object, so we need to make sure the calling page is creating an instance of the correct object class. Change that class to product_3 now. Then change the variable methods from the current getters such as #objProduct.get_name()# to code like #objProduct.get('name')#. The difference seems to be minor. Yet the portability of this object has just increased. We are still able to have protected variables, but we now have much more versatile object classes. Again, this is just the start of how much power we can build in. Hey, we have to start somewhere before we can arrive at any destination, right?

<!--- Example: 2_7.cfm --->
<!--- Processing --->
<cfparam name="url.id" default="0">
<cfscript>
objProduct = createObject("component","product_3").init(); 
rsProducts = objProduct.getRecordset();
objProduct.load(url.id);
</cfscript>
<!--- Content --->
<ul><cfoutput query="rsProducts">
<li>
<a href="?id=#rsProducts.id#">#rsProducts.name#</a>
</li></cfoutput>
</ul>
<cfif objProduct.get('name') NEQ ""> 
<cfoutput>
<table>
<tr>
<th>Product</th>
<td>#objProduct.get('name')#</td> 
</tr>
<tr>
<th>Description</th>
<td>#objProduct.get('description')#</td> 
</tr>
<tr>
<th>Price</th>
<td>#dollarFormat(objProduct.get('price'))#</td> 
</tr>
</table>
</cfoutput>
</cfif>

Now we have achieved about as simple an object as we need to show different aspects of working with objects. Let's deal with a couple of things that we have not talked about to wrap things up.

主站蜘蛛池模板: 青岛市| 南宫市| 西安市| 安达市| 太仓市| 玉门市| 恩施市| 溧水县| 香格里拉县| 甘洛县| 常宁市| 介休市| 平武县| 通州市| 托克逊县| 喜德县| 晋中市| 西乌珠穆沁旗| 天津市| 汉寿县| 中卫市| 和静县| 石台县| 石景山区| 中方县| 呈贡县| 冕宁县| 易门县| 崇州市| 台南县| 哈密市| 锦屏县| 林周县| 浪卡子县| 石泉县| 张掖市| 确山县| 潮安县| 武汉市| 平阳县| 保定市|