Notes: Embrace Factories
Presented by Rob Gonda.
An object lifecycle: Gets created, runs a pseudo-constructor. Gets initialized (Convention in CF is to use an init() method). Use methods/functions. No deconstructor, is just cleaned in garbage collections.
Problems: Object creation, relationships/wiring, manageability/moving objects, cohesion/loose coupling, unit testing.
An object factory is responsible for creating objects. Lets you centralize the path and dependencies for creating objects. All objects depend on the factory. It is passed to all objects. Objects request the factory for instances of other objects. So you might have Application.Factory. It is a singleton (only exists once in your app) that all other objects will reference.
The init() constructor of an object should have the factory as the argument it takes in. It can then ask the factory whenever it needs a new object.
The factory will basically just accept an argument describing the type of object it should return. Its code will then call the CreateObject() command and return the appropriate object. Remember, each object should always receive a factory as the argument. So even the factory should pass itself (this) when instantiating the object:
What's the next step? Inversion of Control (IoC). One type of control is Dependency Injection (DI). This enables an object to automagically know about the other objects that it needs to know about and communicate with. In other words, your object's code doesn't have to instantiate objects through the factory itself. It will happen automagically.
To do this, the object's init() constructor will no longer receive the factory, instead it will receive arguments containing all the objects it needs to use. But now what about when one object requires the other, but the other requires the first one? Object A requires Object B, but Object B requires Object A. They will constantly be calling each other in an endless loop. To fix this, don't init() them right away. Then use setter functions in the object instead.
ColdSpring solves the same problems as Spring. It is an IoC framework for CFCs that allows constructors and setters to have DI. It borrows the XML syntax from Spring, which is nice. It supports polymorphism. Perfect for Unit testing: Swap dependencies per abstract classes-based on interfaces. Also enables us to use our objects for multiple interfaces--Ajax, Flex, MVC, etc. This may require a facade, but the facade would be very thin and easy to write.
Autowiring in ColdSpring is even easier. It will introspect your objects and automatically pass settings and utils arguments if those arguments and methods exist in the functions and constructors. Doing this, though, means that those dependencies aren't documented. Even though they're happening, you never know for sure if they're happening because they are omitted. It would be better documentation to just put the wiring into the XML.
Other ColdSpring perks: AOP, front controller framework integration (with Mach II, Model Glue, Coldbox). Can also automate the Flash Remoting code generation and mapping.

June 30th, 2007 at 11:49 am
Nice notes; glad you enjoyed it.