what Object-Oriented Programming

Object-Oriented Programming
Dr.NaveenBansal Profile Pic
Published Date:25-10-2017
Your Website URL(Optional)
C H A P T E R 18 ■ ■ ■ Object-Oriented Programming: Why Bother? by Brian Kotek Unless you’ve been living under a rock, you’ve heard about the increasing focus on object-oriented programming (OOP) in the ColdFusion world. With the advent of ColdFusion Components (CFCs) in ColdFusion MX 6, and the constant improvement to CFCs in every version of ColdFusion since, OOP has not only become possible for ColdFusion developers, but is rapidly becoming the de facto standard for building applications. Why is this? And if you haven’t drunk the OOP Kool-Aid yet, why should you care? In this article, I’ll start with a brief overview of the fundamentals of OOP. Then I will focus on some reasons for taking the time to learn about it. OOP Fundamentals I’ll try to keep the jargon to a minimum, but unfortunately, a few ideas simply must be covered before any real discussion of OOP can take place. To begin with, object-oriented programming should probably be called class-oriented programming. When you build an OO application, you start by creating classes. Think of classes as blueprints for objects. Consider the schematics for a BMW 650i. The schematics are generic and apply to any BMW 650i that could exist. The schematics can be compared to a class in an OO application. You can equate constructing a real, individual—and gorgeous—650i from those schematics to invoking (or instantiating) an object. In ColdFusion, CFCs take the place of classes. You may write the code for a CFC called Car, but it isn’t actually very useful until you use CreateObject() to create an actual, individual instance of your Car CFC. Now you have an object that can actually do something Objects contain data and behavior, and an OO application does its work by having objects send messages to each other. The big three elements of OOP are inheritance, polymorphism, and encapsulation. 213 CHAPTER 18 ■ OBJECT-ORIENTED PROGRAMMING: WHY BOTHER? Inheritance Inheritance is what you have when an object (the child object) extends or takes on the properties of another object (also known as the parent object). Inheritance allows you to create a hierarchy of objects that begin with very general things and progress to very specific things. For example, you might create an object called Product, and within it you might have very general data and behavior that applies to any type of product — data like productName or behavior like calculatePrice().With the Product class definition as your base, you could then create a more specific child object such as DownloadableProduct, which would extend Product. DownloadableProduct might be an MP3 file or a piece of software, and it might have data and behavior specific to it, such as fileSize. The crucial thing to understand is that DownloadableProduct inherits the data and behavior of its parent object Product. This eliminates a great deal of code duplication, because anything common to all of your products can be coded once in Product, and it will be inherited by all objects that extend Product. Polymorphism Polymorphism is primarily a side effect of inheritance (in some OO languages, it is possible to gain polymorphism in other ways, but since ColdFusion doesn’t support these other ways, I won’t complicate the discussion). It sounds fancy, but all it really means is that you can treat child objects that extend a base object just like the base object itself. To make this clearer, let’s continue with the Product object example. All objects that extend our Product object can respond to the message calculatePrice(), because calculatePrice() is defined in the Product. This means that, from the standpoint of other objects, it doesn’t matter which child of the Product class they are dealing with—a DownloadableProduct or a PhysicalProduct. They can call calculatePrice() on either one. DownloadableProduct and PhysicalProduct are said to be polymorphic, because from the point of view of any objects that need to interact with them, they both behave the same way. To put it another way, other objects only need to know that they are dealing with a Product. Which specific kind of product they are actually interacting with is completely hidden. Encapsulation The idea of hiding information from the rest of the system forms the third, and in my opinion, the most important, element of OOP: encapsulation. Encapsulation comes in many forms. Traditionally, encapsulation refers to hiding the internal implementation of an object from external objects. In our example, the way a Product handles the message calculatePrice() is hidden from the outside world. We might start with something simple, such as an internal price variable, and when calculatePrice() is called, the object just returns the numeric price variable. But because we’ve hidden the formula by which a Product determines its price behind the calculatePrice() message, we are free to change it. As our business grows, the simple price variable might be replaced with a much more complex series of calculations involving discounts or tiered pricing for larger customers. In other words, when things are encapsulated, they are hidden. And when things are hidden, they can be changed with minimal impact on the rest of the system. As long as Products keep responding to calculatePrice() by returning a number, the internal way in which a Product actually determines its price can be changed as often as necessary. This is the power of encapsulation. However, encapsulation actually goes far beyond merely hiding the internal implementation of an object. We already touched on another demonstration of encapsulation when we talked about polymorphism. Because all of our Products can respond to calculatePrice(), the specific kind of 214 CHAPTER 18 ■ OBJECT-ORIENTED PROGRAMMING: WHY BOTHER? product the system is dealing with is hidden. All of the child objects of Product are hidden behind the base Product object. If the rest of the system only knows about the base Product object, we are free to add or remove specific kinds of products at will. In essence, any time you are hiding information from the rest of the system, you are leveraging encapsulation. It may take a while to fully wrap your head around this fundamental element of OOP. In traditional OO languages like Java, it is possible to encapsulate object creation, different sets of rules, and entire families of objects. Encapsulation forms the basis of most of the design patterns that are employed when creating well-designed OO systems. So What? I’ve talked about the fundamental elements of OOP, but why should we ColdFusion developers care? OOP is hard to learn, and it can add complexity to our applications. So why should we bother? The most common reason cited for using OOP is flexibility. OOP systems are designed to be easy to change. We all know change will happen. Most of the effort in a software project is not actually in building it, but in maintaining it. By encapsulating things that are subject to variation, OOP helps make it easier to cope with change. I believe this is true, but it is deceptively difficult to prove. Couldn’t a well-designed procedural system be made to handle change? Sure it could. Constructs like CFCs give us some helpful tools to manage change, and it is certainly possible to build flexible systems without OOP. I would argue that it is riskier and takes much more care to do so, but no one can deny that it is possible. In my opinion, the most overpowering reason to learn OOP is your career. Whether you agree or disagree that OOP systems are more flexible than procedural ones is irrelevant. As far as the software development industry is concerned, this debate is already over. OOP has won. Someday, a different approach to software design may come along, but objects are going to rule the field for many years to come. Developers who choose to cling to procedural development will find themselves increasingly marginalized. If you want to continue to be a viable software developer, you simply must learn OOP. ColdFusion is a wonderful language for learning OOP. Procedural coders can easily begin using CFCs. They can first be leveraged in small ways, and over time, they can become the foundation for entire applications. Though ColdFusion is a loosely typed language that doesn’t offer every OOP feature, all of the essential elements are available, as they are in Java. CFCs allow us to begin thinking in an OO way. They are very capable OOP constructs that can be used with large and complex applications. And the beauty of ColdFusion is that if or when it is needed, we can use the underlying Java platform to perform OOP feats that ColdFusion alone cannot. We’ve really have the best of both worlds: a rapid language with good OOP capabilities in ColdFusion Markup Language (CFML), and the underlying power and complexity of Java if we really need it. That sounds like a sweet spot to me. Where Do I Start? I hope this overview of OOP helps fuel your desire to learn more about it. Not only is it now a career necessity, but once you “click” with OOP, it really does make it easier to manage change. And, dare I say it, planning and building OOP-based applications is actually fun There are many blogs and articles out there that can help you get started, as well as dedicated mailing lists like CFCDev (http://groups.google.com/group/cfcdev). I also recommend reading as much as you can on the subject in books such as the following: 215 CHAPTER 18 ■ OBJECT-ORIENTED PROGRAMMING: WHY BOTHER? • Object Technology: A Manager's Guide by David A. Taylor (Addison-Wesley Professional, 1997) • Head First Object-Oriented Analysis and Design by Brett D. McLaughlin, Gary Pollice, and David West (O'Reilly, 2006) • Fundamentals of Object-Oriented Design in UML by Meilir Page-Jones (Addison- Wesley Professional, 1999) With all of these resources at your fingertips, there’s never been a better time to take on the challenge. 216 C H A P T E R 19 ■ ■ ■ The Object-Oriented Lexicon by Hal Helms Learning object-oriented programming brings a whole slew of concepts and terminology that many ColdFusion developers are unprepared for. When we did the object-oriented and frameworks issue (Fusion Authority Quarterly Update Volume 1, Issue 2), I asked Hal Helms to write a lexicon as an easy reference. This was probably the hardest chapter in the whole book to write, and it caused great contention between members of our staff due to the differing philosophical opinions on various items. Many of the definitions here are based on Java, the 500-pound gorilla of object-oriented programming (OOP). To apply them to ColdFusion, you may need to go beyond the definitions or limit their scope. This lexicon is meant to give you a basic understanding of the terminology, not to bring you the dogmatic “truth.” abstract class: A superclass that is not meant to be instantiated. Abstract classes can have real methods and properties that will be used by their subclasses. Languages that implement the concept of abstract classes usually provide a mechanism for ensuring that they cannot be instantiated; however, ColdFusion does not provide such a mechanism. abstraction: The process of removing details of something in order to reduce it to a set of essential characteristics. By simplifying the thing being modeled, the programmer reduces the original’s complexity (without sacrificing the original’s essential correctness, we hope). Abstraction is a concept used in many OO techniques, such as abstract classes, base classes, and interfaces. aggregation: A design in which a class holds objects as instance variables. For example, a Department class might hold an array of Employee objects as well as a Manager object (see Figure 19-1). Aggregation often increases the flexibility of a design as it allows for polymorphic variations, which nonobject types do not. You could, for example, provide a subclass of Employee to the Department class with no ill effects (see Liskoff Substitution Principle). 217 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON Figure 19-1. Department aggregates Employee and Manager API (application programming interface): Implements the principle of information-hiding by providing a public, well-defined, stable set of methods that expose the intended functionality of a class. APIs can be written on the small scale (e.g., a class’s public methods) and the large scale (e.g., a published API for an entire application composed of many classes). argument: A value passed to a method. base class: A class that is extended by other classes; also called a superclass. (See also inheritance.) class: A type specification, or blueprint, used to instantiate objects. (Contrast with the abstract class, which cannot be used to instantiate objects.) Classes typically have methods and instance variables. ColdFusion refers to classes as components (CFCs). class variable: A variable shared by all instances of a class. For every class instance, the value of the variable is the same. If one instance changes the value of this variable, the variable's value will be changed for all instances. For example, a class defining a 2010 Mercedes SL-550 might have a carsRegistered variable that tracks the number of these cars registered. All instances of this class will have the same value for this variable. component: See class. composition: A stronger form of aggregation in which the class cannot exist without its composite parts. A Triangle class would be composed of three individual Line objects (see Figure 19-2); remove any of these Line objects, and the Triangle object is incoherent. The compositing class often handles the instantiation of composite parts itself. Figure 19-2. Triangle is composed of Line 218 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON constructor: A special method responsible for object creation. To get around the lack of true constructors in ColdFusion, a best practice is to provide an init method that programmers agree to call when creating objects, as in this example: cfset hal = CreateObject('component', 'ColdFusionProgrammer').init() Constructors, like other methods, can take arguments. (See “Tipical Charlie— How Do I Call Thee, CFC?" in Fusion Authority Quarterly Update Volume 1, Issue 2 for more on object instantiation.) design pattern: A time-tested architectural solution to a recurring problem. The term was coined by Christopher Alexander, a building architect, and was adopted by the Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides) in their seminal work, Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994). There are often several design patterns for a single recurring problem. The choice of design pattern depends largely on the context of the problem and the trade-offs involved in choosing one design pattern over another. Used properly, design patterns allow the architect to adopt best-practice solutions while avoiding short-term fixes that might have pitfalls. domain model: The set of classes (and/or interfaces) that model a business or organization. Domain models are, to a large degree, independent of any specific application. Domain models are commonly expressed in Unified Modeling Language (UML) diagrams. dynamic typing: A feature of a language in which a variable’s (data) type is determined at runtime. Ruby, Smalltalk, and ColdFusion are examples of dynamically typed languages. Dynamic typing is sometimes referred to as weak typing. Dynamically typed languages are not type-safe. (Contrast with static typing.) encapsulation: The architectural practice of designing components such that their public functionality is exposed only through an API, rather than through direct manipulation of the component’s internals. Such information-hiding is key to the nature of OOP. A class is an example of encapsulation—its internals are hidden, and desired functionality is exposed through public methods. On a larger scale, design patterns such as Facade are also based on the idea of encapsulation, where an entire subsystem of functionality is hidden behind a single API. Encapsulation makes writing code easier. Team members need to know only the component’s API and not its internal representation. Encapsulation also makes maintaining code easier, as a component’s implementation details may undergo significant changes without affecting other parts of a program that make use of the encapsulated component. information-hiding: Closely related to encapsulation, the principle that a component’s implementation should be hidden, allowing the designer to expose functionality through an API. 219 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON inheritance: A mechanism whereby a more specific class borrows the methods and variables from a more general class. For example, a Vehicle class may define certain methods and instance variables common to all vehicle types. That base class might then be extended by more specific types of vehicles, such as Car and Motorcycle, which automatically inherit Vehicle’s methods and properties. We say that the Vehicle class is a superclass to Car and Motorcycle. It could also be said that Car and Motorcycle are subclasses to Vehicle. Language designers must choose between offering single inheritance (where a class can extend only one other class) and multiple inheritance (where a class can extend many classes). Multiple inheritance has proven problematic and has fallen into disuse. Interfaces provide many of the advantages of multiple inheritance without the drawbacks. Inheritance is a powerful but overused aspect of OOP. In their book, Design Patterns: Elements of Reusable Object-Oriented Software, the authors advise architects to “prefer composition to inheritance.” (See also base class, superclass, subclass, and interface.) init: A method used as a best-practice work-around for lack of true constructors in ColdFusion components. instance variable: Also known as a property, a variable defined by a class as belonging to a particular instance of that class. While all instances of a class have these variables, the value of these variables may be different for each instance. For example, all members of the Vehicle class may have a vin variable, but each Vehicle object will have a different value for this variable. Contrast with class variable. instantiation: The process of creating an object from a class. Objects are, therefore, also called class instances. In ColdFusion, instantiation is done with the CreateObject function, the cfinvoke tag, or the NEW operator (in ColdFusion 9). interface: (1) The set of method signatures associated with a type. The type’s interface provides a specification for these methods, but not the implementation. (2) In some statically typed languages (such as Java and C), a language construct that defines one or more methods and their arguments but does not include their implementation or instance variables and cannot be instantiated. Classes can implement interfaces, thereby gaining the advantage of multiple typing without the problems associated with multiple inheritance. Liskoff Substitution Principle: Formulated by Barbara Liskoff, a principle that states that a language should ensure that a subtype can always be safely substituted for a more generic type. For example, a ColdFusionProgrammer class that extends a Programmer class can safely be passed to any method expecting a Programmer (e.g., as an argument). The Liskoff Substitution Principle guarantees polymorphism. (See also inheritance.) message-passing: The idea that an object performs its functions by being sent a message. In most OO languages, this phrase is identical to “calling a method on the object.” 220 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON method: A service provided by an object. In ColdFusion, methods are implemented with the cffunction tag or the function keyword (in cfscript). Methods can take arguments. In some languages, methods can be called directly on a class, rather than on an object (see static methods). Methods can, but need not, return a value to their callers. object: A particular instantiation of a class. overloading, method: A mechanism afforded by some OO languages (such as Java and C) that allows multiple implementations of the same-named method, but with different method signatures. The language compiler determines which implementation to call based on the unique combination of argument types. Constructors can also be overloaded in supporting languages. Dynamically typed languages, like ColdFusion, do not support method overloading. The following is a Java example showing constructor overloading: public class VehicleManager( public Vehicle getVehicle(int vin) // return vehicle based on vehicle identification number public Vehicle getVehicle(String tag) // return vehicle based on tag overriding, method: A mechanism whereby a subclass redefines the meaning of a same-named method in a superclass. The following is a ColdFusion example showing method overriding: cfcomponent displayName="Programmer" cffunction name="program" access="public" cfreturn "Generic programming" /cffunction /cfcomponent cfcomponent displayName = "ColdFusionProgrammer" extends="Programmer" cffunction name="program" access="public" cfreturn "ColdFusion programming" /cffunction /cfcomponent cfset hal = CreateObject('component', 'ColdFusionProgrammer') cfoutputhal.program()/cfoutput The code shown here outputs the string “ColdFusion programming.” ColdFusion supports method overriding, but not method overloading. 221 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON polymorphism: The ability of objects belonging to different types to respond to method calls of methods of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not need to know the exact type of the object in advance, so this behavior can be implemented at runtime (this is called late binding or dynamic binding). The following adds another class, AjaxProgrammer, to the example shown for method overriding: cfcomponent displayName = "AjaxProgrammer" extends="Programmer" cffunction name = "program" access = "public" cfreturn "Ajax programming" /cffunction /cfcomponent The following creates three objects: cfset joe = CreateObject('component', 'Programmer') cfset hal = CreateObject('component', 'ColdFusionProgrammer') cfset mike = CreateObject('component', 'AjaxProgrammer') Finally, the same method can be called on each of these objects: cfoutput joe.program() produces "Generic programming" hal.program() produces "ColdFusion programming" mike.program() produces "Ajax programming" /cfoutput The same method call produces different results for each of the objects in a polymorphic language. (See overriding, method.) properties: See instance variable. In ColdFusion, anything in a component's Variables scope and This scope is a property of the component. static method: Also called a class method, in languages such as Java, a method that can be called on a class rather than an object. The following is a Java example calling a static method: Integer.parseInt("4"); The parseInt method is a static method to the Integer class (rather than to an instance of the class). 222 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON static typing: A language mechanism where variables are declared to be of a specific type at design time. Statically typed languages (e.g., Java and C) check for type safety during the compilation phase. The term static typing is often used interchangeably with strong typing, although there are subtle differences between the two. subclass: A class that extends another class. (See also inheritance). subtype: A type that is a more specific version of another type. In ColdFusion, subclasses are synonymous with subtypes. In languages with interfaces, all subclasses are subtypes, but not all subtypes are subclasses. For example, an HourlyPayStrategy class may implement the PayStrategy interface, but not extend any class (see Figure 19-3). HourlyPayStrategy is, therefore, a subtype of PayStrategy, but is not a subclass. (See also inheritance and interface.) Figure 19-3. HourlyPayStrategy implements PayStrategy interface superclass: A class that is extended by another class; also called a base class. (See also inheritance.) supertype: A type that is a more generic version of another type. In ColdFusion, superclasses are synonymous with supertypes. In languages with interfaces, all superclasses are supertypes, but not all supertypes are superclasses. For example, ColdFusionProgrammer may extend Programmer, making ColdFusionProgrammer both a subclass and a subtype of Programmer (see Figure 19-4). (See also subtype and inheritance.) Figure 19-4. ColdFusionProgrammer extends Programmer class 223 CHAPTER 19 ■ THE OBJECT-ORIENTED LEXICON type (data type): In non-OO languages, the kind of information a variable can hold. In OO languages, types are more closely associated with the methods that can be called on a variable. type promotion: The mechanism whereby polymorphic languages can treat a subtype as a supertype. Assume a method, x, that expects an argument of type Y. Further assume a class, Z, that extends Y. If an object of type, Z, is sent to the method, x, it will be type-promoted to type Y. In Figure 19-5, an object of type, ErrorsAndOmissionsPolicy, can be sent to any method expecting either a CommercialInsurancePolicy or an InsurancePolicy. Similarly, an object of type, CommercialInsurancePolicy, can be sent to any method expecting an InsurancePolicy object. Types can be promoted automatically, but they cannot be demoted (e.g., you could not send a CommercialInsurancePolicy object to a method expecting an ErrorsAndOmissionsPolicy). (See also Liskoff Substitution Principle and inheritance.) Figure 19-5. ErrorsAndOmissionsPolicy extends CommercialInsurancePolicy, which extends InsurancePolicy type safety: In common usage, indicates the assurance that no type mismatching will occur. If, for example, a method advertises that it accepts an argument of type, X, a language is said to be type-safe if it can ensure, prior to runtime, that only variables of type X (or type-promotable to type X) will be passed to that method. (See also type, subtype, supertype, and Liskoff Substitution Principle.) UML (Unified Modeling Language): An Object Modeling Group (OMG) standard object modeling and type specification language. The UML consists of 13 different diagram types, the most common of which is the Class diagram. UML is currently at version 2.0. ■ Note Special thanks to Sean Corfield and Michael Dinowitz for their insights and corrections. 224 C H A P T E R 20 ■ ■ ■ Design Patterns: Exposing the Service Layer by Peter Bell Peter Bell is known in the community for his focus on meta programming, code generation and domain specific modeling. However this article is focused on application architecture - specifically some design considerations when creating a domain model that can be accessed by multiple view technologies such as HTML, AJAX and Flex. As web technology changes, developers may wish to add new front-end interfaces, such as an Ajax call, a Flex front-end or a SOAP or RESTful API, to an existing application. However, they often find that their application’s existing architecture does not easily adapt to the change, and that mistakes they have made in setting up that architecture are compounded when the application has multiple front ends. Here are some ideas on designing web applications that support multiple front-ends so that when you need to add new ways of accessing your information like an AJAX request or a Flex front-end, you won’t have to re-architect your entire application. Model-View-Controller (MVC) Hopefully, you are already breaking your application into Model, View and Controller concerns. The model is the meat of the application. It consists of business objects containing all of the key business rules for your application, which you may want to expose to your AJAX, Flex or web service calls. Views are responsible for displaying a snapshot of the model in HTML. For example, your views might display a list of users or a form for adding a new product to your store. The controller is responsible for taking web requests from users, combining the values of the Form and URL scopes with any cookie or session data, calling methods within the model and passing any resulting data to be displayed by the view template or passing the data back as an XML or JSON packet if it is a request from an AJAX call. It is often useful to create a collection of Service or Manager components to act as an interface for interacting with the model. These components provide an easy way to access the functionality that relates to the business objects. For example, UserService.cfc might have methods that return a list of users and delete a user from the system. 225 CHAPTER 20 ■ DESIGN PATTERNS: EXPOSING THE SERVICE LAYER There are two approaches to designing this service layer: • Design the services based on business functions or groups of business objects. For example, DiscussionGroupService would manage the topics, threads and comments within a discussion group. • Create one service class for every business object, so that a discussion group application would contain TopicService, ThreadService and CommentService, for handling interactions with the three different objects. The first approach can often create a cleaner, more intuitive interface. However, I typically just generate one service class for every business object, effectively treating it as a repository for the kind of class methods that you might put in your business objects if you were programming in Java. This second approach may not create an ideal architecture, but it allows for much easier and more consistent code generation and can create “good enough” applications in much less time. Whichever approach you take, you will typically have a collection of service CFCs acting as the interface to access your model. Your controller methods will call methods on those CFCs to tell the model what to do and/or to retrieve information from the model. The model will often return rich business objects for your view templates to display. For example, if you have a article.list controller action, the details of the syntax will vary with the framework you are using, but it will probably look something like Listing 20-1. Listing 20-1. A Controller Method Calling the Model public void list( event ) event.setValue( "articleList" , ArticleService.getAll() ); This works well when you just use a single HTML front-end interface. When you start to support multiple front ends, things get a little more complicated for three reasons: • Firstly, not all front end interfaces support sessions, so you have to do a little more work to implement security if you’re not limited to HTML requests. • Secondly, you need to handle the return of XML or JSON data • Thirdly, you might need to make sure that your various front end interfaces are sharing data correctly so if you update a setting using Flex, that is reflected immediately for visitors to the HTML version of your site. Let’s look at each of those issues in turn. Handling Sessions The first issue you run into is session handling. Let’s take a simple example. Some web applications have an administrative interface that allows for the management of pages in the site, usually through a page secured by authentication. An administrative user logs in, and for the rest of the session you can identify the administrative user by a unique key stored in the Session scope - often his or her user ID. Listing 20- 2 illustrates the concept. 226 CHAPTER 20 ■ DESIGN PATTERNS: EXPOSING THE SERVICE LAYER Listing 20-2. Standard Code Allowing User to Delete a Page public string function deletePage( pageId ) if ( structKeyExists( session, "userId" ) ) redirectTo( "/login" ); else var user = UserService.getbyId( session.userId ); if ( user.isAllowedTo( "Page", "delete" ) ) return PageService.delete( pageId ); else return "permission denied"; ; ; ; The problem with handling requests from multiple front ends is that not all of them provide access to a usable Session scope. Just looking for session.userID between requests won’t always work, so you need to roll your own way to persist state between requests. In practice, this is pretty easy to do. Create a unique session ID using the createUUID() function when a user authenticates, then return that UUID. Add it to an object cached within Application scope, associating the session to a given user ID. Then require a UUID for all method calls that need to be secured, comparing the UUID against the session object, which also handles avoiding duplicate keys and killing sessions after a time-out period. So, if a site user wanted to delete a page, as in Listing 20-2, there would be two method calls required. First, he’d need to authenticate using his credentials (often a username and password) to get a valid session key, as shown in Listing 20-3. Then he’d have to pass that session key, as shown in Listing 20-4. Listing 20-3. Getting a Valid Session Key validateSiteUser( string username, string password ) var siteUser = UserService.getValidatedUser( username, password ); if ( siteUser.exists() ) return siteUser.getSessionUUID(); else return "Invalid credentials"; ; Listing 20-4. Passing a Session Key deletePage( pageId, sessionUUID ) // Load the user var siteUser = UserService.getbySessionUUID( sessionUUID ); // Validate session key if ( siteUser.isValidSiteUser() ) // Validate security 227 CHAPTER 20 ■ DESIGN PATTERNS: EXPOSING THE SERVICE LAYER if ( siteUser.isAllowedTo( "Page", "delete" ) PageService.delete( pageId ); return "Page deleted"; else return "Permission denied"; ; else return "Please authenticate"; ; You do need to remember that all of your remote requests need to pass the session UUID every time they call a service method. Also, all of your remote methods must understand a “session expired” error code, so that they know to re-authenticate the user, either by asking for user input or by passing stored credentials the user previously entered into the remote system. Returning Data There are two issues to address when returning data. The first is to return the right format such as XML or JSON and the other is to handle any business logic relating to formatting (such as prepending monetary values with a sign or formatting dates in a locale appropriate way). Regarding business logic, please see Chapter 32, “Separating Layout from Logic,” where I address the importance of having methods within your business objects to handle any formatting that needs to be applied irrespective of the front-end interface being used. Obviously you don’t want to have methods on the business object returning HTML specific markup such as strongHello world/strong, but you may well want to have a product.displayPrice() method that returns the price to two decimal places with a sign (e.g. “95.99”) or an event.displayStartDate() method that returns the start date of an event in the appropriate locale for the end user. In terms of the overall format, you can either use a .cfm template to create the output or you can write a script to generate it. Let’s imagine that we are trying to return an XML packet containing information on a list of product objects. Listing 20-5 shows an example of how we could do that using a .cfm template: Listing 20-5. productXMLdisplay.cfm productList cfoutput query="productList" product name="Name" title="Title" / /cfoutput /productList Listing 20-6 shows an example that does the same thing as a script through string concatenation— this would be part of the product object (or more likely a base class the product object extends or a utility class that it delegates to internally) so you could call product.asXML() to return an XML representation of the product object. 228 CHAPTER 20 ■ DESIGN PATTERNS: EXPOSING THE SERVICE LAYER Listing 20-6. product.asXML() public string function asXml( ) var XMLString = "product "; var propertyNameList = "name,title"; var i = 0; var propertyName = ""; for ( i=1; i lte listLen( propertyNameList ); i++ ) propertyName = listGetAt( propertyNameList ), i ); XMLString = XMLString & ‘propertyName="get( propertyName )" ’; return XMLString & "/"; Accessing the Application Providing they are calling the same ColdFusion application, your various front-end interfaces will share the same application scope. However, depending on your application architecture, you might also need to make sure that if you are using a Dependency Injection framework such as LightWire or ColdSpring, it is also shared between the various front end interfaces. The solution to this is fairly straightforward. If you are rolling your own framework, make sure that the beanFactory is saved in the application scope so both your remote and HTML applications get their beans by calling application.beanFactory(beanName). If you are using a framework, check the framework documentation for how to handle remote service calls. Conclusion When we first move from writing simple applications to enforcing a Model-View-Controller separation, it is easy to make mistakes in the exact interfaces between the model, view and controller. As you start to develop applications with multiple front-ends, you will find those mistakes become problematic very quickly. Hopefully the ideas above will help you to jump-start your development of applications capable of supporting multiple front end interfaces. 229 C H A P T E R 21 ■ ■ ■ Beans and DAOs and Gateways, Oh My by Sean Corfield When you decide to incorporate object-oriented programming and design patterns into your ColdFusion toolbox, the most confusing set of concepts is the whole notion of “beans and DAOs and gateways and services.” It seems like so much work just to do something that you used to do with a couple of tags – and everyone seems to have strong, and differing, opinions on how best to implement these concepts. In this article, I’m going to try to demystify why we might want to introduce a number of layers into our applications and then review the options available to us, along with some pros and cons. My hope is that after reading this article you’ll feel less intimidated by the terminology and less worried about making the wrong decision about how to structure your application. A Four-Layer Cake The simplest way to write an application is just to mix all the code together on a page-by-page basis. We’ve all done it, and I think we all know that it can lead to duplicated code and, ultimately, to an unmaintainable mess as the application grows. Few people disagree with the idea that it’s a good thing to separate out database code, business logic code, and presentation code. The core principles behind Fusebox addressed this by using file naming conventions to emphasize the separation into qry files (for database queries), act files (for actions – business logic) and dsp files (for display / presentation code). This is essentially the same principle as the Model-View-Controller design pattern, although that focuses on separating presentation code, application control code, and “everything else.” 231 CHAPTER 21 ■ BEANS AND DAOS AND GATEWAYS, OH MY As we adopt object-oriented principles, we start to represent concepts in our applications using ColdFusion Components (CFCs). We are told that encapsulation is a good idea, so we write CFCs that have getXyz() and setXyz() methods to provide access to our xyz properties. Following the common Java terminology, we refer to these as beans. Then we have to deal with getting that data in and out of the database, and we need to decide what to do with our application’s logic. What we end up with is a somewhat inevitable series of layers in our applications, as shown in Figure 21-1. Figure 21-1. Four Layer Cake Each layer has a pretty clearly defined purpose: • Presentation – The HTML shown to the user, along with the minimal code necessary to display data and loop over sets of data. • Control – The logic that routes requests (links and form submissions), interacts with the model (business logic), and selects the appropriate views (presentation) to display. • Business Logic – This is (or should be) the core of your application, containing all of your business objects and the operations they can perform or have performed on them. • Database Access – This contains all of the SQL operations necessary to get your business objects’ data in and out of the database. This approach allows us to change our presentation layer or to refactor and optimize the database without changing the core of our application. It also makes our business logic more testable, since we don’t have to deal with either the database or the user interface in our testing and can therefore more easily automate our testing. The layered approach often allows us to reuse more of our code across multiple projects because it leads to code that has fewer dependencies on its environment. 232

Advise: Why You Wasting Money in Costly SEO Tools, Use World's Best Free SEO Tool Ubersuggest.