Defining Interfaces
When designing components, it's frequently useful to define a template for anyone passing components to general functions. For example, you might create a function that takes as an argument an instance of a cast or crew member of a movie and calls a method named getResume to get a copy of the crew member's resume as a query, and another method named showPersonHTML that shows the crew member's name and information in an HTML display.
When requesting several implementations of this function to implement different types of cast members, actors, directors, producers, and so on, you might want these components to each do everything differently—you don't want them to inherit from a common parent, but they all have to implement a minimum set of functionality to meet the requirements of the system.
The definition of functions without actual implementation is a special type of component definition called an interface. An interface is basically a contract between a component and a system. You define an interface in a file with an extension of .cfc, but instead of enclosing the component with cfcomponent tags, you use a new–for–ColdFusion 8 tag called cfinterface. Any component that implements the interface must contain all the methods defined in it, or the system will display an error.
Listing 27.4 contains an interface for the component just described.
Listing 27.4. iCastCrew.cfc—An Interface
<cfinterface hint="cast or crewmember interface"> <cffunction name="getResume" access="public" returntype="query" hint="return resume as query"> </cffunction> <cffunction name="showPersonHTML" access="public" returntype="string" hint="show person information as HTML"> <cfargument name="detail" type="boolean" required="no" default="true" hint="show detailed information"> </cffunction> </cfinterface>
Introspection and inheritance (via the extends attribute of cfinterface) can be used with interfaces the same way as with components. Figure 27.3 shows the introspection when you open iCastCrew.cfc in a browser.
Figure 27.3 Component introspection.
To make sure that a component implements an interface, you use the implements keyword in the cfcomponent tag; for example, to make the director an implementation of iCastCrew, you would change the first line to:
<cfcomponent displayName="Movie Director" extends="person" implements="iCastCrew">
If you ran this code, you would get the error shown in Figure 27.4, since the director component is missing some of the functions defined in the interface.
Figure 27.4 Interface error.