|By Peter Bell||
|November 9, 2006 01:00 PM EST||
One of the first things that you encounter when moving to object-oriented (OO) programming are beans. Beans are simple representations of a business object (like a user or a product) that hide all of the information stored in the bean behind methods (functions) for getting and setting the information (called, unsurprisingly, getters and setters).
Typically, if you want to display a product view screen, you'll get the product information from the database, load the resulting query recordset into a bean and then, instead of displaying the variables from the query, call the methods from the bean. In the past your product view may have looked like this:
$#Price#<br /><br />
With a bean, the product view will change to the following:
$#Product.get("Price")#<br /><br />
The only difference is that you are calling a "get" method that hides (encapsulates) the way the title and the price are retrieved, but this small difference can have a big impact on the maintainability of your code. (The sharp eyed among you will have noticed that I'm using a generic getter. The sidebar explains why this might be a good idea for you to consider).
Object-oriented programming is all about writing more maintainable code. Many Object Oriented patterns take longer to code initially than a traditional procedural approach, but they are easier to maintain. Given that we tend to spend much more time maintaining than developing applications, this is usually a worthwhile trade-off.
The benefit of encapsulating business object attributes behind getters and setters is that if the logic required to calculate (or save) the attribute changes, you only have to change the code in one place. Let's say that the product price is calculated based on a sale price. In the past you might have put that logic right into the product view:
$<cfif SalePrice>#SalePrice#<cfelse>#Price#</cfif><br /><br />
The problem is, there may also be a product list screen, a product search results screen, and the cart and checkout may also need to know the price of a product, so if you changed the way you calculated the price, you would have to remember to make that change in five places. Even worse, there is the risk that you might forget to update one of the screens, so products displayed on the search screen would display a different price than when added to the basket.
With getters and setters encapsulating the logic, there would be no change at all to the display screens. They would still be:
$#Product.get("Price")#<br /><br />
The only difference is that you would change the getPrice() custom method within the product object to be something like:
<cffunction name="getPrice" returntype="numeric" access="public"
output="no" hint="I return the price to display and charge for the product">
<cfset var Local = structNew()>
<cfset Local.ReturnValue = variables.get("SalePrice")>
<cfset Local.ReturnValue = variables.Price>
So, encapsulation of getters and setters using beans is a key element of Object Oriented programming, and it is a best practice that most OO developers would use most of the time. So, what happens when we have more than one user or product or article?
The Performance Problem
In Java, this would be easy. You would take your recordset, use it to create a collection of objects (one for each record), and you would still have all of the benefits of encapsulated getting and setting of properties. Unfortunately, in ColdFusion, object creation is expensive (in terms of performance). Creating a large number of objects as part of every page load can substantially affect the performance of a ColdFusion script.
Because of this, a lot of ColdFusion developers currently use recordsets for displaying their lists, losing all of the benefits of encapsulation. If they want to change the way the price is calculated for a product list, they either need to push back the price calculation onto the database; write a script in their service object to loop through the query implementing any custom data transformations; or replicate their business logic all over their list screens.
Introducing the Iterating Business Object
The iterating business object (IBO) is a simple solution to the problem of encapsulating access to getters and setters for recordsets without sacrificing performance. It is implemented as a base class that your business objects can extend. As well as providing generic getters and setters, it can also load itself with a query, and it provides a basic set of iterating methods (first(), next(), and isLast()) for looping through the recordset.
The IBO allows you to get all of the benefits of encapsulated getting and setting of attributes - whether you are working with a single object or a collection of them. It also allows you to use exactly the same code for both your single objects and object collections. For example, it really doesn't matter whether you are viewing a single product on a product detail page or a list of products matching a search query. If you want to display the price for the product, you want to use the same business logic to calculate it in both cases. With an IBO, you always load the same object up with the results from your query, and you can maintain all of your getter and setter calculations in that one object. In addition, you are only instantiating a single object per page view, so the performance hit is nominal. You can see the code for a simple IBO in Listing 1.
Using the Iterating Business Object
When you are using the IBO to display a single record, it is exactly the same as using a bean:
$#Product.get("Price")#<br /><br />
If you want to display a list of records, it is almost as easy. You take the same basic display code and just wrap it with a loop based on the iterating methods of the object:
<cfloop condition="NOT #Product.isLast()#">
$#Product.get("Price")#<br /><br />
Improving the Object
Previously I showed an example of a custom getter for calculating the price of a product. If there was a sale price, it displayed that, otherwise it just accessed the variables scope to get the price. Well, that works for a single record, but if there are multiple records (as with the IBO), the actual code to access a particular record would be more like:
<cfset Local.ReturnValue = variables.Data[variables.IteratorCount].Price>
Where the variables.IteratorCount is a pointer to the current record within the recordset being displayed. This isn't "wrong", but over time all of the custom methods would have to include this code, and if I ever decided to change the structure of the data storage within the variables scope, all of those methods would have to be rewritten.
To encapsulate that change, I added one more pair of generic methods to the base IBO: access() and mutate(). Accessors and mutators are alternate terms for getters and setters, but these methods are private and are only to be used by the customer getters and setters to access the underlying data structure, so if I ever wished to change the structure, I would only have to change those two methods. Below is simplified code for the access() method (the full code is available in Listing 1):
<cffunction name="access" returntype="any" access="private" output="no"
hint="I encapsulate access to the attribute values within this object,
accepting an attribute name and returning the appropriate attribute value.">
<cfargument name="AttributeName" type="string" required="yes"
hint="I am the name of the attribute to return the value for">
<cfset var Local = structNew()>
<cfset Local.ReturnValue = variables.Data[variables.IteratorCount][arguments.AttributeName] >
With this in place, we can now simplify the data access in the custom methods to just:
<cfset Local.ReturnValue = variables.access("Price")>
I have used the IBO on a number of production projects over the last couple of months. One project in particular required almost daily changes to the (very complex) object model as we continually added new attributes and changed the rules for calculating existing attributes. I found the application extremely easy to maintain and it is now in production, powering over 20 different sites and performing very well under load.
If you don't have any calculations for getting or setting any of your object attributes and really don't expect any in the future, any kind of encapsulation is overkill, and you would be better just to display using recordsets and cfoutput - for one record or for many. If you do have calculated fields, give the IBO a try and see how it works for your projects.
|Peter Bell 01/02/07 07:19:46 PM EST|
Good catch! That was indeed a little messy and is something I plan to clean up later this month. if you're interested, I'll be reposting code on my Blog. I'm probably going to use isDone(), but will take a little time to look at some other iterators to see what syntax is most popular.
|Michael Long 11/26/06 07:49:10 PM EST|
Could just be me, but I'd expect a function named "isLast" to return true if I'm actually on the last record. Which would in turn lead to an off-by-one error, as the loop would terminate early.
Better, perhaps, would be isEOF, or isDone, either of which would be true if the current record count is greater than the actual record count.
@ThingsExpo has been named the Top 5 Most Influential M2M Brand by Onalytica in the ‘Machine to Machine: Top 100 Influencers and Brands.' Onalytica analyzed the online debate on M2M by looking at over 85,000 tweets to provide the most influential individuals and brands that drive the discussion. According to Onalytica the "analysis showed a very engaged community with a lot of interactive tweets. The M2M discussion seems to be more fragmented and driven by some of the major brands present in the...
Oct. 23, 2016 11:30 AM EDT Reads: 11,308
In the next forty months – just over three years – businesses will undergo extraordinary changes. The exponential growth of digitization and machine learning will see a step function change in how businesses create value, satisfy customers, and outperform their competition. In the next forty months companies will take the actions that will see them get to the next level of the game called Capitalism. Or they won’t – game over. The winners of today and tomorrow think differently, follow different...
Oct. 23, 2016 11:00 AM EDT Reads: 924
In an era of historic innovation fueled by unprecedented access to data and technology, the low cost and risk of entering new markets has leveled the playing field for business. Today, any ambitious innovator can easily introduce a new application or product that can reinvent business models and transform the client experience. In their Day 2 Keynote at 19th Cloud Expo, Mercer Rowe, IBM Vice President of Strategic Alliances, and Raejeanne Skillern, Intel Vice President of Data Center Group and ...
Oct. 23, 2016 10:30 AM EDT Reads: 1,445
More and more brands have jumped on the IoT bandwagon. We have an excess of wearables – activity trackers, smartwatches, smart glasses and sneakers, and more that track seemingly endless datapoints. However, most consumers have no idea what “IoT” means. Creating more wearables that track data shouldn't be the aim of brands; delivering meaningful, tangible relevance to their users should be. We're in a period in which the IoT pendulum is still swinging. Initially, it swung toward "smart for smar...
Oct. 23, 2016 09:45 AM EDT Reads: 783
Virgil consists of an open-source encryption library, which implements Cryptographic Message Syntax (CMS) and Elliptic Curve Integrated Encryption Scheme (ECIES) (including RSA schema), a Key Management API, and a cloud-based Key Management Service (Virgil Keys). The Virgil Keys Service consists of a public key service and a private key escrow service.
Oct. 23, 2016 09:45 AM EDT Reads: 1,013
The Internet of Things (IoT), in all its myriad manifestations, has great potential. Much of that potential comes from the evolving data management and analytic (DMA) technologies and processes that allow us to gain insight from all of the IoT data that can be generated and gathered. This potential may never be met as those data sets are tied to specific industry verticals and single markets, with no clear way to use IoT data and sensor analytics to fulfill the hype being given the IoT today.
Oct. 23, 2016 09:45 AM EDT Reads: 2,482
Data is the fuel that drives the machine learning algorithmic engines and ultimately provides the business value. In his session at Cloud Expo, Ed Featherston, a director and senior enterprise architect at Collaborative Consulting, will discuss the key considerations around quality, volume, timeliness, and pedigree that must be dealt with in order to properly fuel that engine.
Oct. 23, 2016 09:30 AM EDT Reads: 3,811
What happens when the different parts of a vehicle become smarter than the vehicle itself? As we move toward the era of smart everything, hundreds of entities in a vehicle that communicate with each other, the vehicle and external systems create a need for identity orchestration so that all entities work as a conglomerate. Much like an orchestra without a conductor, without the ability to secure, control, and connect the link between a vehicle’s head unit, devices, and systems and to manage the ...
Oct. 23, 2016 08:30 AM EDT Reads: 1,337
The best way to leverage your Cloud Expo presence as a sponsor and exhibitor is to plan your news announcements around our events. The press covering Cloud Expo and @ThingsExpo will have access to these releases and will amplify your news announcements. More than two dozen Cloud companies either set deals at our shows or have announced their mergers and acquisitions at Cloud Expo. Product announcements during our show provide your company with the most reach through our targeted audiences.
Oct. 23, 2016 08:15 AM EDT Reads: 4,429
Machine Learning helps make complex systems more efficient. By applying advanced Machine Learning techniques such as Cognitive Fingerprinting, wind project operators can utilize these tools to learn from collected data, detect regular patterns, and optimize their own operations. In his session at 18th Cloud Expo, Stuart Gillen, Director of Business Development at SparkCognition, discussed how research has demonstrated the value of Machine Learning in delivering next generation analytics to impr...
Oct. 23, 2016 08:00 AM EDT Reads: 5,676
@ThingsExpo has been named the Top 5 Most Influential Internet of Things Brand by Onalytica in the ‘The Internet of Things Landscape 2015: Top 100 Individuals and Brands.' Onalytica analyzed Twitter conversations around the #IoT debate to uncover the most influential brands and individuals driving the conversation. Onalytica captured data from 56,224 users. The PageRank based methodology they use to extract influencers on a particular topic (tweets mentioning #InternetofThings or #IoT in this ...
Oct. 23, 2016 08:00 AM EDT Reads: 8,325
For basic one-to-one voice or video calling solutions, WebRTC has proven to be a very powerful technology. Although WebRTC’s core functionality is to provide secure, real-time p2p media streaming, leveraging native platform features and server-side components brings up new communication capabilities for web and native mobile applications, allowing for advanced multi-user use cases such as video broadcasting, conferencing, and media recording.
Oct. 23, 2016 07:00 AM EDT Reads: 4,104
Amazon has gradually rolled out parts of its IoT offerings, but these are just the tip of the iceberg. In addition to optimizing their backend AWS offerings, Amazon is laying the ground work to be a major force in IoT - especially in the connected home and office. In his session at @ThingsExpo, Chris Kocher, founder and managing director of Grey Heron, explained how Amazon is extending its reach to become a major force in IoT by building on its dominant cloud IoT platform, its Dash Button strat...
Oct. 23, 2016 06:30 AM EDT Reads: 4,747
SYS-CON Events announced today that SoftNet Solutions will exhibit at the 19th International Cloud Expo, which will take place on November 1–3, 2016, at the Santa Clara Convention Center in Santa Clara, CA. SoftNet Solutions specializes in Enterprise Solutions for Hadoop and Big Data. It offers customers the most open, robust, and value-conscious portfolio of solutions, services, and tools for the shortest route to success with Big Data. The unique differentiator is the ability to architect and ...
Oct. 23, 2016 06:00 AM EDT Reads: 703
A critical component of any IoT project is what to do with all the data being generated. This data needs to be captured, processed, structured, and stored in a way to facilitate different kinds of queries. Traditional data warehouse and analytical systems are mature technologies that can be used to handle certain kinds of queries, but they are not always well suited to many problems, particularly when there is a need for real-time insights.
Oct. 23, 2016 05:30 AM EDT Reads: 3,925
DevOps is being widely accepted (if not fully adopted) as essential in enterprise IT. But as Enterprise DevOps gains maturity, expands scope, and increases velocity, the need for data-driven decisions across teams becomes more acute. DevOps teams in any modern business must wrangle the ‘digital exhaust’ from the delivery toolchain, "pervasive" and "cognitive" computing, APIs and services, mobile devices and applications, the Internet of Things, and now even blockchain. In this power panel at @...
Oct. 23, 2016 05:15 AM EDT Reads: 1,836
One of biggest questions about Big Data is “How do we harness all that information for business use quickly and effectively?” Geographic Information Systems (GIS) or spatial technology is about more than making maps, but adding critical context and meaning to data of all types, coming from all different channels – even sensors. In his session at @ThingsExpo, William (Bill) Meehan, director of utility solutions for Esri, will take a closer look at the current state of spatial technology and ar...
Oct. 23, 2016 03:45 AM EDT Reads: 1,698
Everyone knows that truly innovative companies learn as they go along, pushing boundaries in response to market changes and demands. What's more of a mystery is how to balance innovation on a fresh platform built from scratch with the legacy tech stack, product suite and customers that continue to serve as the business' foundation. In his General Session at 19th Cloud Expo, Michael Chambliss, Head of Engineering at ReadyTalk, will discuss why and how ReadyTalk diverted from healthy revenue an...
Oct. 23, 2016 03:30 AM EDT Reads: 2,955
SYS-CON Media announced today that @WebRTCSummit Blog, the largest WebRTC resource in the world, has been launched. @WebRTCSummit Blog offers top articles, news stories, and blog posts from the world's well-known experts and guarantees better exposure for its authors than any other publication. @WebRTCSummit Blog can be bookmarked ▸ Here @WebRTCSummit conference site can be bookmarked ▸ Here
Oct. 23, 2016 02:30 AM EDT Reads: 9,659
SYS-CON Events announced today that Streamlyzer will exhibit at the 19th International Cloud Expo, which will take place on November 1–3, 2016, at the Santa Clara Convention Center in Santa Clara, CA. Streamlyzer is a powerful analytics for video streaming service that enables video streaming providers to monitor and analyze QoE (Quality-of-Experience) from end-user devices in real time.
Oct. 23, 2016 02:30 AM EDT Reads: 942