Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Object Oreinted Approach in Coldfusion

1,911 views

Published on

introduces the OOPs in CF and mentions the advantages of OOPs.
Problems faced in OOPs and managing Components using Coldspring.

Published in: Technology, Education
  • Be the first to comment

Object Oreinted Approach in Coldfusion

  1. 2. <ul><li>Procedural Code Vs Object Oriented CF code </li></ul><ul><li>Object Oriented approach in CF </li></ul><ul><li>Why OOPs? </li></ul><ul><li>Types of components </li></ul><ul><li>Complexities in Object Oriented approach </li></ul><ul><li>Introduce Factories. </li></ul><ul><li>Problems addressed and not addressed by factories </li></ul><ul><li>Introduce CodlSpring framework . </li></ul><ul><li>Initialization and dependency handled by Coldspring </li></ul><ul><li>Summary </li></ul>
  2. 3. <ul><li>Procedural </li></ul><ul><ul><li><CFINCLUDE> tags </li></ul></ul><ul><ul><li>Coldfusion Custom tags </li></ul></ul><ul><ul><li>User defined Function </li></ul></ul><ul><ul><li>Implemented using FuseBox 3.1 framework in VE </li></ul></ul><ul><li>Object Oriented </li></ul><ul><ul><li>CFC – ColdFusion Components </li></ul></ul><ul><ul><ul><li><CFCOMPONENT>, <CFINVOKE>, <CFOBJECT> </li></ul></ul></ul><ul><ul><li>Implemented using FuseBox 4.1 framework in VE </li></ul></ul>
  3. 4. <ul><li>Implementing OOPs in CF </li></ul><ul><li>CFC - <CFCOMPONENT> </li></ul><ul><li>Functions - <CFFUNCTION>, <CFARGUMENT>, <CFRETURN> </li></ul><ul><li>Object Instance - <CFINVOKE>, <CFINVOKEARGUMENT>, <CFOBJECT>, createObject(), init() </li></ul><ul><li>Properties - <CFPROPERTY> </li></ul>
  4. 5. <ul><li>Represents Real world objects and therefore gives a lot of meaning to the code. </li></ul><ul><li>High Reusability </li></ul><ul><li>Easy Maintenance </li></ul><ul><li>Isolation of different layers (User Interface, Business Logic, Data) </li></ul>
  5. 6. <ul><li>People, Place, Things </li></ul><ul><ul><li>Represent real world stuff </li></ul></ul><ul><ul><li>Related objects are created as and when needed </li></ul></ul><ul><ul><li>Usually core to the business model </li></ul></ul><ul><li>Services and Infrastructure </li></ul><ul><ul><li>Represent concepts and processes </li></ul></ul><ul><ul><li>Related objects are often other services and infrastructure </li></ul></ul><ul><ul><ul><li>Data Access Objects, Data source objects </li></ul></ul></ul><ul><ul><li>Usually created at application startup </li></ul></ul>
  6. 7. <ul><li>Problems in Object Creation: </li></ul><ul><li>createObject(), <cfobject>, <cfinvoke> all require “pathnames” to CFCs </li></ul><ul><li>Code is littered with hardcoded strings specifying locations of CFCs </li></ul><ul><li>Hard to move CFCs around or swap out one implementation (CFC) for another </li></ul><ul><li>Hard to unit test code because you can't easily substitute a “mock” CFC for the full object </li></ul>Inside your controller code: <cfset var dsn = createObject( “component”, “ cfcs.datasource” ).init( “testdb” ) > <cfset variables.dao = createObject( “component”, “ cfcs.mysql.dao” ).init( dsn ) >
  7. 8. <ul><li>Problems with Dependencies </li></ul><ul><li>If the controller needs the data access object and the data access object needs the datasource object, how do you create/ initialize them? </li></ul><ul><li>Create datasource object </li></ul><ul><li>Create data access object and initialize with datasource object </li></ul><ul><li>But whose responsibility should this be? </li></ul>
  8. 9. <ul><li>A factory “makes things” </li></ul><ul><li>A factory object makes objects </li></ul><ul><li>Move hardcoded paths into the factory object – only one place to make changes now. </li></ul><ul><li>Factory knows about dependencies </li></ul><ul><li>Rest of your code depends on the factory object </li></ul><ul><li>“ Factory Method”Pattern </li></ul>Inside your factory: <cffunction name=“getDatasource”> <cfreturn createObject( “component”, “ cfcs.datasource” ) .init( “testdb” ) > </cffunction> <cffunction name= “getDAO”> <cfreturn createObject( “component”, “ cfcs.mysql.dao” ) .init( getDatasource() ) </cffunction> <ul><li>Inside your controller code: </li></ul><ul><li><cfset variables.dao = myFactory.getDAO() > </li></ul><ul><li>Where does myFactory come from? </li></ul><ul><li>Passed into controller? </li></ul><ul><li>Created by controller? </li></ul><ul><li>Or use application.factory instead? </li></ul><ul><li>Factory created during application initialization: </li></ul><ul><li><cfset application.factory = createObject( “component”, </li></ul><ul><li>“ cfcs.factory” ).init() > </li></ul>
  9. 10. <ul><li>Problems Addressed </li></ul><ul><li>No hardcoded paths in application code </li></ul><ul><li>Can move CFCs (or change implementation) by changing only </li></ul><ul><li>the factory code </li></ul><ul><li>Some initialization can be handled by the factory </li></ul><ul><li>But where does it get the initialization data? </li></ul><ul><li>Problems Not Addressed </li></ul><ul><li>Unit testing /mocks mean changing the factory code all the time </li></ul><ul><li>Factory needs to know dependencies </li></ul><ul><li>Initialization is still a pain: </li></ul><ul><li>-Factory can be passed the initialization data </li></ul><ul><li>-Factory can contain the initialization data </li></ul><ul><li>- Factory can load data fromsomewhere... (hmm, con!g !les!) </li></ul><ul><li>-Factory can pass back uninitialized objects (bad!) </li></ul>
  10. 11. <ul><li>A testing factory and a regular factory </li></ul><ul><li>Lots of duplicated code </li></ul><ul><li>Have to change code to test different parts of the application </li></ul><ul><li>Can also solve the multiple database support problem(a data </li></ul><ul><li>Access object factory for MS SQL,MySQL, Oracle...) </li></ul><ul><li>“ Abstract Factory”Pattern </li></ul><ul><li>Multiple factories with the same API </li></ul>Selecting factories at startup: <cfif dbType is “mysql”> <cfset application.factory =createObject( “component”,“cfcs.mysqlfactory” ) .init() > <cfelse> <cfset application.factory = createObject( “component”, “ cfcs.oraclefactory” ) .init() > </cfif>
  11. 12. <ul><li>Problems Addressed </li></ul><ul><li>Ability to create different sets of objects – swapping implementations, unit testing (sort of) </li></ul><ul><li>Problems Not Addressed </li></ul><ul><li>Initialization – partially solved but it's still ugly </li></ul><ul><li>Dependencies – still hardcoded, still has complex initialization issues </li></ul>
  12. 13. <ul><li>Instead of trying to handcode each factory and managing all of the dependencies and initializations, why not use a generic </li></ul><ul><li>factory? </li></ul><ul><li>ChiliBeans </li></ul><ul><li>- Included with Model-Glue </li></ul><ul><li>- Effectively deprecated </li></ul><ul><li>ColdSpring </li></ul><ul><li>- Muchmore than just a factory </li></ul>
  13. 14. <ul><li>A container to manage your CFCs </li></ul><ul><li>http://coldspringframework.org/ </li></ul><ul><li>XML configuration file specifies: </li></ul><ul><ul><li>CFC pathnames and type names </li></ul></ul><ul><ul><li>Initialization (via constructors or setters) </li></ul></ul><ul><ul><li>Dependencies </li></ul></ul><ul><li>Ask ColdSpring for “foo”and get a fully initialized, resolved object of the appropriate type </li></ul>
  14. 15. <ul><li>Problems Addressed </li></ul><ul><li>No hardcoded paths in application code </li></ul><ul><li>Can move CFCs or change implementation just by changing XML declarations </li></ul><ul><li>All initialization handled </li></ul><ul><li>All dependencies managed </li></ul><ul><li>Create different objects </li></ul><ul><ul><li>By swapping XML !le or just changing the XML declarations </li></ul></ul>
  15. 16. Datasource CFC (abbreviated) 􀀀 <cfcomponent> <cffunction name=“init”> <cfargument name=“name”> <cfset variables.name = arguments.name> <cfreturn this> </cffunction> <cffunction name=“getName”> <cfreturn variables.name> </cffunction> </cfcomponent> DAO CFC (abbreviated) 􀀀 <cfcomponent> <cffunction name=“init”> <cfargument name=“dsn”> <cfset variables.dsn = arguments.dsn> <cfreturn this> </cffunction> <cffunction name=“getDSN”> <cfreturn variables.dsn> </cffunction> </cfcomponent> Application Initialization <cfset application.cs = createObject(“component”,“coldspring.beans.DefaultXmlFactory”).init() > <cfset application.cs.loadBeans(expandPath(“cs.xml”)) > Application Code <cfset dao = application.cs.getBean(“dao”) > Returns a fully initialized data access object <cfset dsn = dao.getDSN() > ColdSpring resolved the dependency and created (and initialized) the datasource bean first, then created the data access object bean and initialized it with the datasource bean.
  16. 17. <ul><li>XML Con!guration </li></ul><ul><li><beans> </li></ul><ul><li><bean id=“dao” type=“cfcs.mysql.dao”> </li></ul><ul><li><constructor-arg name=“dsn”> </li></ul><ul><li><bean type=“cfcs.datasource”> </li></ul><ul><li><constructor-arg name=“name”> </li></ul><ul><li><value>testdb</value> </li></ul><ul><li></constructor-arg> </li></ul><ul><li></bean> </li></ul><ul><li></constructor-arg> </li></ul><ul><li></bean> </li></ul><ul><li></beans> </li></ul>XML Examined (1) <bean id=“dao” type=“cfcs.mysql.dao”> Specifies that “dao” resolves to cfcs.mysql.dao type – can easily change to cfcs.oracle.dao etc <constructor-arg name=“dsn”> Specifies a constructor argument – ColdSpring creates the argument value (a bean) and passes it into the constructor automatically Could use <property> instead and ColdSpring would call setXxx()method to set the property XML Examined (2) <bean type=“cfcs.datasource”> Unnamed object passed to“dao” constructor <constructor-arg name=“name”> Specifies constructor argument for this datasource bean <value>testdb</value> Specifies the (string) value passed to the constructor: obj.init(name=“testdb”)

×