Thursday, December 4, 2008

Be a good investigator

We use a machII framework around our application. We also use coldSpring to manage the relationships and instantiation of collaborating components in our domain.

A quick review, for my own brain too. Machii helps to organize large scale enterprise level applications and promotes OO design of the application, or at least promotes MVC design pattern. There is no denying that, Machii forces the separation of concerns between the presentation, control and (model)domain layers of the application. It also promotes OO design by using listeners, that do the requesting of data from the domain. It is possible to use Machii and listeners and still be using prodedural programming techniques, guity. Moving on.

The application in question consumes lots of complex data that is served up by the domain via services. This is in line with SOA type architecture. Services oriented architecture. The domain makes available services that the machii application listeners know about. The listeners have knowledge of services and can speak to them. The application does NOT KNOW ANYTHING about the domain or model layer that is providing or peristing the data that it needs.

Picture machii doing its job, housing the views and the events and the listeners, that know about services that speak to the data model layer. Whenever something happens in the application, an event is fired, the event has *commands that are part of it - like requests for data and calls to other listener funtions. The arguments or data provided during the event is passed along via the event to the listener who hands that off to a service. The service knows then what to do with it. Recall that the service HAS knowledge of who it is serving. The SOA architecture promotes the notion of the service as the SOCIAL beast in the equation. The service will have much of the bus. rules or logic contained within it. It does a lot of the heavy lifting or thinking for the other components in the domain. The service knows what do do in this situation or that situation, when this piece of data is missing or if a specific type of data is encountered.
Recall that a service probably has its own set of dependent components that must exist for it to do its job. A common occurance is a DAO or Gateway or persistence bean that the service relies on to do its job. If any of these other collaborating components does not exist, the service fails.
The SERVICES, being social, often need to know about other services, not about the other services collaborating entities, just the service itself. This need to know about each other had much to do with the birthing of ColdSpring. With, as the name implies, follows the concept of Spring in the Java world, which is a framwork that helps manage the complex relationships that exist between the collaborating entities in the domain.

ColdSpring "lifts" the knowledge of the collaborating entities out of the entities themselves and places them into a separate container. This is abstraction at its finest.

Tradoffs - there is always tradoffs when you use a framework, like machii or coldSpring. In the case of coldSpring, that is a slight performance overhead and the need to maintain a separate XML style document. A little complexity at first. The gain is a one stop place to create and manage the relationships that exist between your services, DOAs, Gateways.

We have two separate coldSpring xml files, one that is used by the application and another than is used by a sub- application. When i built the sub app, i originally had the domain components instantiating their own collaborating components, this is the natural way to build the app, not seeing the need for a framework initially, who needs it! Eventually, as the sub app grew in complexity and collaborating entities, the need became more clear. I created a new *bean building xml file (this is the container that holds all the bean definitions). The coldSpring configuration file consistes of bean definitions complete with references to dependent components. CS calls this dependency injection -this is usually reserved for those social services, who need to have their dependent DAOs and gateways and other services to work properly.

The problem

In my sub - app coldspring file, i named a bean the same as one that already existed in the root coldSpring config. file. Even though i pathed the bean in the sub app to a different component, it seemed to ignore the bean def. Seems if a beanname already exists in the current scope, it will not read the next. It could be a problem with how i am using the scope? -

The symptom

The problem reported as a failure to set an injection statement in # 2

1 - model.questions.QuestionService.cfc
2 - assessments.questions.QuestionService.cfc

The Diagnosis

I tried to path # 2 a little different, since I did not want to change the name of the service (this would require me to update the name in a couple other places), but was not successful.
The config file in the sub app was pathed to # 2 but when it tried to do its injection of a DAO, it was reporting the failure in relation to # 1.

The Test

I changed the name of the component in # 2 and updated that name in the appropriate places, a listener, another reference in the CS config file and a reference in another service that was using this and walla - problem gone, lesson learned.

Recall that when you are doing dependency injection in a bean definition in the CS config file, you need an equivently named funtion in the collaborating (injecting) component, with the letters set in from of it. In other words, if you have a service bean being in jected with a DAO, then the injecting DAO must have a setDAO funtion that allows the setting.

Like this - here is the bean defintion *minus the brackets that the blogger does not like

bean id="AssessmentQuestionService" class="assessments.model.QuestionService"
property name="QuestionDAO"
ref bean="QuestionDAO"
property
bean

Here is the function in the service that is being injected

cffunction name="setQuestionDAO" access="public" returntype="void"
cfargument name="QuestionDAO" type="assessments.model.QuestionDAO" required="Yes"
cfset variables.QuestionDAO = arguments.QuestionDAO
cffunction

This is a little intimedating at first, but trust the technology and the beauty of the design. It becomes more clear as to its power and purpose over time, when you add more things to the application and more relationships between collaborating entities.

Wednesday, November 5, 2008

Prototyping

Ive been working on some new functionality the past couple weeks, which is nice, since it has been awhile since our project has seen any new functionality. We used to use a process called FLIP, that Hal helms and Jeff Peters worked up awhile back, but the people, including the customers who were involved in this are gone, so i ended up thinking hard about what parts of that process worked and what parts could be left out. A re-cap of that analysis follows.

What works

Front end development first. That's a fine principle to follow while building new functionality. What is the new stuff supposed to be doing? How should it do it, what should the interface look like, what kind of functionalily should be present. All these things help the customer to see things that they are trying to describe. Put something in front of them and let them see it in context of the system where it will be used. I even heard one of my customers say "now that i can see it in place" the other day, more on that in a moment.

Don't think implementation, at least not the database or model domain. Anther one of our developers at the presentation was asking questions about implementation. This was the initial design and presenation of the design, there should be ZERO talk of implmentation. We are focusing on what they client wants!

Keep it light - do not attach the prototype to any real datam, fake it. Hard code stuff in view pages, do not query or instantiate objects in any way in the prototype. When i could myself starting to think these things, i kicked myself. This payed off immediately, since some of what i was prototyping was not needed, at least at this point.
Get it in front of the client, expect multiple iterations before they say "thats it". Make sure that you get the people who are interested or who should have a say involved early. I need to do that now. One of my customers was not present at the meeting. I need to get his input sooner than later.

I am prototyping the new code in the actual application, which required me to do a bit more work, that if i used the prototype toolkit that we used to use. But its work it.

Elicit feedback. In our previous prototyping cycles, we used a toolkit that allowed users to login and leave comments on each view page. That was moderatetly useful. Some of the customers understood what we were trying to do, but others did not get it and it was alot of work and a hassle. The prototype toolkit would get in the way of what they were trying to do and confuse things. They would leave comments on the wrong pages or the login would fail or something would go wrong.

Now, i am putting the new code in the actual application on my localhost and showing it to the group. My next step will be to put the revised content on our test server and give another presentation. The feedback, which is so important will be handled via email via me asserting things back to them and them clarifying. This is not perfect either, but is the way i am approaching.

I am thinking some implementation. The new functionality is a calendar that is showing release dates of critical information in our application. Naturally, AJAX comes to mind, since i do not want to have to reload the application every time the user clicks a new month or year. We just want to drill down into the data and update the calendar without reloading the application. Im thinking this, but not implementing, since i am not doing any drilling into the domain at this point. My prototype is using some javascript to automatically update the calendar when a select box is changed or a pre / next link is clicked, but no real AJAX yet.

I want to be sure the customer says, "that's it for the initial release of the calendar functionality". Then we can freeze things and i can implement the AJAX and other domain code.

Wednesday, October 15, 2008

Post mortem on major upgrade of application

Well, its october and we finally got all that re-factored code through our staging and production environments. It was a pretty big move. There were about 70 files to move around between the domain and presentation layers. About 10 were simply moved to a new location, away from the domain objects. this is a mach-ii application, which explicitly uses listeners. since the listeners are part of the application and not part of the domain, i felt it warrented to move away from the *model folder.

Some of the other components (cfcs) were moved from the model root into a specific folder that represented the object.

I updated coldSpring with new definitions to some of the objects and updated paths to existing objects, to their new locations.

I was also able to remove a couple object instantiations and use the coldSpring provided object reference. this simplifies a bit and removes a little memory overhead but more than that it cleans up and organized the code base better. I already had one new developer who is starting work on this application comment on how she likes the organization better, easier to find things etc.

I also ended up splitting up some presentation code into smaller more singular entities. Reuse in the presentation layer is overrated. I had a single view file that was responding to 4 different types of data, which was cool, but in the end, became too difficult to maintain. that reminded me of the fact that 75% of all programming or time that a developer spends is maintaining existing apps. To that end, creating additional view files for each subject is a tradeoff worth taking. The tradeoff is more code to maintain, but less complex, fewer dependencies. In the domain, i did the same thing. There was one of two functions that were responsible for getting lots of different variations of similar data. Again, this is good programming to think re-use and not have 40 different functions that are all doing similar stuff, but as time goes by, you start to appreciate the ease of maintenance - which is supported by more functions that do less or even a single thing. I can tell you that the trade off is worth it. I always appreciate it when i enter the domain into a gateway query that is very specific and not loaded down with 8 arguments, where 4 are required and 4 are not packed with lots of conditional code in case arguments are passed in....where if you make one small change you worry about effecting the other 10 instances of how this function is called.

Part of this move to staging then production also included the removal of deprecated files that were wither moved to a new location or re-factored.

As i said, i think about 70 new files were moved and about 25 were deprecated.

this move also included many updates to the central controller, where i was removing calls to old functions that had been re-factored or removed and updated paths to listeners, that are registered in the controller and removed references to view files that had been deprecated. view files are also referenced in the controller.

Thats it for now. What a move, really minor problems while moving - biggest issues where keeping the labels, thats how we manage deployment, current and on the tip version of files. I ended up missing a couple files, no label and did not move the tip of the label on a couple others. these problems only took a few minutes to correct. The most grueling part was when our testing general was looking real critically at the layout and recordsets of the views that i had re-factored that were being feed by re-factored queries.

Good experience. Looking forward to the next one, thought it be smaller.

Tuesday, September 2, 2008

model refactoring project continued

Im working on a small update to some core logic in one of my frequently visisted objects. A couple of the updates, including to the controller (this is a machii application) are requiring me to bring along some other changes i made a couple months ago and have been sitting waiting for something like this to come along. I could have made a branch in our source control software to deal with only the changes to the current project, but chose not to.

When i looked back at the changes i made a couple months back, i noticed the coldspring integration i had started. I had integrated a few components into the coldspring configuration file and injected them into their dependent service components. All good! I decided to integrate the current component and its dependent components too. I was pleasently surprised when it only took me about 15 minutes to do this work. Ive got my head around coldspring a bit now and new just what i wanted to do and why. The changes are listed below.

1 - identified the collobarating objects and gave them bean definitions in the config file
2 - identified the dependent object and gave it a bean definition.
3 - injected the two colloborating objects (components) into the dependent object
4 - added set methods for the collaborating components in the dependent object that - removed the init method in the service
6 - tweaked the colloborating components to not require a property on init, changed the default to no and provided a default value. If a value is passed, it will take it but does not require.

Each of these components are singletons, which are perfect for the coldspring container. They have no state and simply provided data that is kept in a related bean component. I caught myself trying to add the bean to the coldpring config. file, but stopped when i clued in to the bean is not a singleton, it has state that updates frequently. I ended up with a method in the service to the bean that checks to see is a session scoped var exists, if not, creates one and used it to update the bean during the user session.

Then i moved into part 2 of this operation

As i am looking at the service, i see where i should have put certain methods into the DAO not the Gateway. I think initially, i only had a gateway component, but as the requirements grew, so did the component. Now i have a DAO and am putting requests for a single rec or data item into it, while leaving the gateway as the aggregator or record sets.

Finally, im looking at this wiht object eyes

and seeing what can i move to the bean and keep the persistence stored in the bean.

Friday, August 29, 2008

Effective Developer habits

These are habits of effective developers. I gleaned a lot of this from the helms and peters podcast. I listened to this a couple years ago and again today. Really good stuff.

1 - Pursue professional growth. Always make time to attend conferences, trainings etc. Use the internet and its plethora of technical podcasts, articles, and blogs. There are so many skilled smart people who have been down the same path that you are on and have documented their experience.

2 - Think Google to help narrow down the search for related resources.

3 - Blog yourself. For me, its help A LOT to internalize things by writing them. Thats why this blog exist.

4 - Think user first. Do not let your vision take precedence over the user or client vision. Try to engage them as much as possible when gathering requirements.

5 - Prototype. If its a new product or functionality build the front end first. There is a lot of smart people who advocate for this "front to back development approach". Build the prototype, involve the client actively. We used to follow a process called FLIP, that emphasized the prototype first while iterating frequently with the customer until they say "thats it". There is no thought given to the implementation, language, DB or framework during the prototype. This process takes at least half of the entire product development life cycle.

6 - As a developer, do not assume superiority. Be amiable, supportive, encouraging. Believe that everyone who you come in contact with has something to offer.

7 - Think first, code second. Try to see the entire problem or big picture. Seek the birds eye view before starting coding or database development.

8 - Document. Not document your code, but code your documentation. Think hard about what is good documentation. Consider that someone else will be maintaining this code.

Thursday, August 28, 2008

Object oriented design

Today, I was listing to Hal Helms and Jeff Peters discuss object oriented design. They were talking about inheritance -vs- composition. The main point was how composition has a is favored over inheritance, is a. Ive been hearing this for awhile, but have not always understood, probably because its a little abstract, since im not doing much in the way of new object design or at least not with extending base classes.

One concept was that base classes are really not ever instantiated, but extended. This notion was further described this way:

A goal of class programming, remember this is the model layer, not the view of controller, is to create stable reusable objects where commonality is captured in a base class that can be inherited or extended by a more specific class. Another way to describe this base class is as a super class.

The goal is to allow base classed to be easily extended (composition) to incorporate new behavior without modifying existing code. This creates designs that are resilient to change and flexible enough to take on new functionality to meet changing requirements.

Design principle:
Classes should be open to extension and closed to modification.

These concepts where discussed around the context of the Decorator Pattern.

Remember, when you abstract the differences by composition, you are adding complexity to the application. Dont forget to think in terms of trade offs. Nothing is free, when you build more extensible code, classes, by following this excellent principle, you are adding more complexity to your logic. Only apply the "open closed" principle where needed.

Wednesday, August 27, 2008

ColdFusion Frameworks, coldbox, tarten, MG, fusebox, machii

Today, i came across a number of helpful/interesting podcasts, articles. First, the helms and peters podcast on Framework Shrink is both entertaining and informative. During this cast, fusebox, MG and machii are all praised, frameworks in general are praised and people who program willy nilly are not praised. They joke about the NMM (no methodology methodology) this is characterized by the developer who thinks they are too smart to have to use someone else ideas, why use a framework when i can solve the problem myself. This brings to mind the debate between Hal Helms and Simon Horwith. This was not so much a debate as a informative discussion about the pros and cons of frameworks. With a decided edge going to the wisdom of using solid solutions created by others that follow best practices and encourage solid design for large applications that are scalable, maintainable, predictable (thats what the use of frameworks provide).

I followed a thread to coldbox, another CF framework that lead to this discussion about the value of frameworks. Who is using coldbox.

There was a mention of Tarten, which i had not hear of before. Interesting, in my brief read, Tarten encourages a service oriented architecture, where the controller speaks only to a service that acts as a mediator to the bus. logic in the model.

This is the common thread through all of the frameworks that i have been into and out of the past few months. Each promotes the

tiered architecture
MVC design pattern to achieve separation of views and bus. logic via a controller
OO design
tight encapsulation
loose coupling
reuse of small singular type classes or objects or with CF, components
the use of a controller to coordinate/direct requests made by application
pushing of bus. logic into the model layer
use of XML style controller
preference for application to speak to the model via a service (tarten).

I also found this useful cf portal site.

I really liked this part of the conversation, quoting Luis Majano.

"Most major design patterns do apply to Coldfusion and decoupling and object oriented approaches are posible. Yes, they will make your application more complex, harder to grasp, and event WEIRD!! But that is the intent, to take your application to an Enterprise level. You can continue to build procedural code for certain applications, it doesn’t mean its bad. But for high availablity and enterprise applications, I would go with a framework. The flexibiliy and architectural extensibility that it will give you, cannot be found in other approaches. It will be hard to grasp and you might think, why do all this work, all these calls. Object Oriented architecture is not easy and you also have to note, that some complexity on these approaches, will make you sacrifice speed. But the benefits will be tremendous."

Wednesday, August 20, 2008

Frameworks, MG, Machii or Custom

I've been messing with MG the past couple days. I have a small application im working on, and decided to give MG a go. Things were going fine, it was taking me longer to solve the problem because i was learning the framework. This is ok, acceptable when learning a new framework. I spent a bit of time listening to podcasts, reading blogs and looking in the official Model-Glue documentation center. Once i turned the corner on getting the MG controller to set the args properly from the event - i was on my way. From this point, MG facilitating communication between my gui and model just fine.

It was about this time that i started to feel like it was a bit overkill, the framework is pretty light, lighter than machii, but i still was not feeling good about the use of it in this case. I just was not doing that much and felt like the overhead and increased complexity was not worth the cost. Like a big brick, the vision of a streamlined *custom framework hit me in the head. I could hear Simon Horwith whispering in my ear. So, i decided to scale back a bit. I used the index.cfm file to handle the bootstrapping and the rest of the setup work. It reminded me of the fusebox settings file, where application level variables and pointers are set up.

Index.cfm is now responsible for creating the object pointer into the service and also listens for actions (*events) such as insert, update or get. Thats about all this GUI is doing. Depending on which action is executed (listened for) i am calling the appropriate service method and passing along form or URL vars appropriately.

These are the following design principles adhered to:

*MVC design pattern
*separation of concerns (view just reacts to what is provided via the controller (index)
*encapsulation of bus. logic (all in CFCs)
*asynchronous calls, where helpful to user
*no SQL in the views (see above)
*safer from spammers and hackers, SQL is down stream protected by the service layer.
*no extra overhead (MG or Machii or Fusebox)
*intuitive - less complex

tradoffs

not as scalable as MG, Machii or fusebox

If the requirements dictate, and a more scalable framework becomes necessary, i can simply trade in the index.cfm with its event and listening responsibilities for a MG or MachII framework, where we can use an XML style central controller with specific listeners or messages. Since i put the bus. logic in the services and the database interactions in the DAO, Gateway - its a can of corn.

Thursday, August 14, 2008

Model Glue

I ran across a ModelGlue folder on our test server today. I have been hearing about MG for a couple years. An easy to use CF framework that promotes MVC. I decided to take a look. I found a read me file in a predictable location and opened it. It had excellent instructions about how to copy a certain folder into your web root, open a controller and change a couple properties in the xml config. file. I did all this, made a silly mistake and corrected it and had the sample RD site up and running in 20 minutes. Impressive. Not me, it.

I recall the setup and initial forays into fusebox and machii and neither was anywhere near as easy as this. Granted, it looks a lot like machii with the xml controller, events and such, but still, 20 minutes from start to end. I must say, i am impressed by how easy that was. I will have to give this a ride in the future.

I sent Joe Rinehart a note saying as much.

ModelGlue, coming to a theater near you.

AJAX - javascript little opps

I have been using a little AJAX technique in a couple places and was having two separate problems that i worked out.

First issue: i have 2 separate html divs that were being reloaded on the same page. The problem i was having is the second call that was informing the second div on the page was sacking the first. In other words, I had come like this calling two different jscript methods


function loadQuestionsStandards(assessmentID,category,type,level){
showStandards(category,type,level);
showQuestions(assessmentID);
}

Each function showStandards() and showQuestions() contains code like this

var url="views/filterQuestions.cfm?&assessmentID=" + AID + "&showAllQuestions=" + flag ;
oXmlHttp=GetHttpObject(updateQuestionList);
oXmlHttp.open("GET", url , true);

where updateQuestionList is the name of a layer in the page called by the url var.

The results of the second call to showQuestions was polulating both divs on the page. Finally, i changed the true property to false in the first method call and it worked.

In other words, the reload of the page only occured once, not twice and it correctly reloaded both layers. I did not find any help around this problem in the blogshere.

The second problem only showed itself in our production environment. Hmmmm, did not occur in our test or staging environments. That remains a puzzle to me. The problem was in the same line of code as the first problem.

oXmlHttp.open("GET", url , true);

When i was trying to solve the first problem, i changed the GET to POST for one of the functions and forgot to change it back. Probably forgot because it did not make a difference until it made it way to production, where it failed gracefully. I got a message back from the Jscript API, i presume, that said Length Required.

I was able to trace the problem back to a specific function where i had made this GET to POST change.

Moral of the story? not sure, but both of these issued had to do with the

oXmlHttp object.

Wednesday, August 13, 2008

CF Conversation

I listened to this podcast today. This interview highlighted a couple things that i have been into and out of in other blogs, podcasts about the CF community, perception of CF as a light weigh tool, frameworks etc.

CF has come along way, especially with the last couple of releases that make CF much more object like. I can see how CF has grown up over 10 years, from its initial release which really was alot like HTML with its tag based format. It was easy to use and easy to create dynamic content. CF excels at hiding much of the complexity of what it does in the tags. This results in users being able to *just do their work. In the past couple years, i have been working more in the architectural side of things than in the front, so i appreciate the emphasis on CFCs and OO techniques.

There is a perception that many of the CF developers, because of it ease of use, do not have the traditional CS type background and consequently are sloppy programmers who rely too much on frameworks. An interesting point. CF's own efficiency has spawned lots of programmers who otherwise may have never been programmers. Folks who only dealt with static content, layout and design had access to programmatic tools that were once exclusive territory of programmers.

There is the perception among programmers that the within the CF community, there is not enough emphasis or development integrating CF with other more mature back end solutions, like Java or PHP, for example. Andrew Powell is a guy who has been working to bridge that gap. This is a good ADOBE sponsored article around this type of integration. If CF is to continue its acceptance into the *big players sphere, it must play better with other technologies. Matt Woodward posts a helpful article around Java integration.

The discussion also talks about the proliferation of CF frameworks and despite the backing of the CF *elite, are overused and are a crutch to many CF programmers. Is there a perception in the CF community that if you are not using a framework, you should be? Hal Helms and Simon Horwith have this debate about frameworks.

The frameworks include, machii, coldBox, model glue, fusebox, coldSpring. Each of these were mentioned. There was a good discussion of trade offs and what that means.

For me, i started CFing without using any frameworks. In a perfect world, CFers would have a change to program without any *overhead of a framework. This aids in the understanding of variables, scopes, and other application wide settings and how the whole bootstrapping process occurs. The frameworks hide many of these concepts and could create a programmer who does not really get some of the crucial concepts behind the code. This could result in programmers who cannot program outside a given framework. I think the frameworks are very useful in some applications and perhaps a bit overkill in others. The size of the app is a big factor. I like the idea of a framework because it creates predictability in the application. This is important for the future of the application and as new people come into it to support it.

There was also some good discussion around the software life cycle. A good reminder that we should do our heavy lifting before we start programming and that we should not start the development in the database. FLIP was mentioned, since there was discussion of frameworks. I think i heard these numbers:

50% time gathering requirements and prototyping
30% implementing the prototype
20% testing and documenting

Was a mention that Flex has really become a popular prototyping tool.

ColdFusion Growing Up

I listened to a podcast today about something i have been reading in blogs a bit the past couple months. Old news to some, but new to me and important to understand the larger picture.

Once upon a time, ColdFusion was just a little player on the larger scene. the Allaire brothers created the initial taging language way back in 98,99? It is telling now that ColdFusion has 3 different rendering engines and a couple open source projects and is in discussion with educational groups for free liscensing and curriculum, to start offering as college curriculum.

There are 3 different organizations that are offering a ColdFusion rendering engine.

Adobe - with Coldfusion
Blue Dragon - new Atlanta
Railo

I was listening to this podcast today where they discussed Railo in detail and the need to have a standard CF rendering engine, since there are now multiple players. the idea of a CF core that was implemented by each engine with plugins or addons or lib functions or something like this to allow diff. additions by diff. engines.

Its all good - the maturation of a platform like ColdFusion.

Refactoring Bus. Logic

The past couple weeks have had me back into old problems. I had been in each of these holes before, but was back with new requirements. As i looked at both of the functions in the CFCs, i found myself struggling to add the new requirements because the way the functions were defined was not intuitive. In one case, i ended up refactoring the way the logic was working. I should say i separated the logic into two different queries and then used a union to join the result set if needed.

It took me a couple days of going into and out of this function before i was able to see the solution that i ended up using. I was talking to another developer about this and concluded that we need to see things in our own model to understand them before we can enhance something. I was temped at one time to create a new function and simply leave this one that way it was, but i fought that urge and eventually saw a cleaner way to solve the same problem. Be a technician, bot a demolition man. I added a comment in the function to the effect that i hoped the next time someone traveled down this path into this function, that the bus. logic would be clear to them.

Good code to me means clear code, not necessarily fewer lines or clever, but clear to the next person who may be coming into the code to try to enhance it.

The greatest threat to maintainable software? Complexity! Someone said that once.

Moral to the story. Be patience and if code smells, give yourself ample opportunity to re-factor the code in a way that does not smell, is easier to understand and enhance for the next Joe who comes along after you.

Blogs and Podcasts

As a developer, there are many ways to approach solving the problems that you encounter. One of the primary points i am making is where do we find inspiration and ideas for how to solve things. I have been making alot of rounds lately in the blog sphere. I cannot stress enough how much outstanding fodder is available in peoples blogs. Someone, Brian Hegeman, once encouraged me to use the blog sphere to find answers to questions but more than that to stretch my understanding of the bigger picture. I was not ready at that time, probably because i was too busy just trying to understand the code base i was working on, supporting ect. I was fortune enough to work with a couple guys who were very talented programmers/architects. There was much for me to learn.

I made a decision after the cf-objective conference this year to spend more time stretching my brain with other peoples perspectives and ideas. Over the past 3 months I have been almost daily going to blogs not looking for a specific answer to a problem, but just to listen in on some conversations. I also joined a couple specific groups, where the conversation is specific about a framework, machII and a model layer manager called ColdSpring. These are specific frameworks that the main application i support uses. As part of this blogging experience, i have created a public space trying to share the learning and organize some of the blogs i have visited.

I have found myself also listening to a few podcasts. Some people may prefer to read, but the podcasts are very useful and pretty focused on relevant topics for the ColdFusion developer. I have found that a couple different CF related podcasts have been around for a few years. Hal helms and Jeff Peters have been doing one for awhile as have Bryan Kaiser and Michael Kaynie. This format starts out discussing relevant CF related news, then typically has someone interviewed. In 2006 Matt WoodWard and Peter Ferrel of machii and CF fame started a podcast called ColdFusion Weekly.. The ColdFusion weekly has recently stopped creating new podcasts but a couple others have just began. CF conversations is more of a round-table interview format.

Here is a short list of topics that i have been plugging into the past couple weeks in various blogs and podcasts.

SQL injection and protection
Marketing CF
Creating more CF developers by giving CF away to educational institutions (ADOBE)
Creating an official curriculum for Universities to adopt
CFAJAX, built in ajax tags for CF8
Krugle.com - code search engine
FLEX -vs- AJAX debate
Framework or no-framework debate
Flex as the view layer, CF as the model layer, machii or model glue as controller

If you wanna be a developer, then pull your head out of the hole and embrace the blog sphere that has so much to offer.

Tuesday, July 29, 2008

AJAX mussings

Today, I spent the better part of the day following a path i had previously blazed, AJAXing. I was looking at a specific request that my user made regarding a form that needed a little new functionality. I knew i had used AJAX techniques previously. This is a form with a lot of filtering option and a lot of data, idea for AJAX or asynchronous communication. This form needs to be able to make requests and have the data update without having to load the entire form or page again. I am also maintaining a lot of state in the page, so keeping previous selection is important.

It took me awhile to get my head back around how the AJAX was working, which told me i had not really internalized it that well, so here goes a little blogging on how it works, at least how i am using it.

I have a container.cfm page that has html controls in it. The controls i am using are select lists and radio buttons. I have javascript method calls i am making on the clicking of these controls, also on the loading of the page, to handle initial state. The controls call the jscript method and pass a parameter or two. The jscript method used some fancy schmancy script reload a portion of the page, which includes a call to the server (db) via a oXmlHttp request. That code looks like this

function showQuestionsForItemMapping(AID, flag){
//alert('in ' + AID + flag);
var url="views/filterQuestions.cfm?&assessmentID=" + AID + "&onlyNotMapped=" + flag ;
//alert(url);
oXmlHttp=GetHttpObject(stateChangedQuestions);
oXmlHttp.open("GET", url , true);
oXmlHttp.send(null);
}
function stateChangedQuestions(){
if (oXmlHttp.readyState==4 || oXmlHttp.readyState=="complete"){
document.getElementById("questionsToMap").innerHTML=oXmlHttp.responseText;
}

In the example, the jscript method showQuestionsForItemMapping() is called from a container.cfm page that has a
named questionsToMap, which is where the results of the page processing display. Notice the file views/filterQuestions.cfm is called and processes with new parameters passed in from the container file. The URL, which is set to the filerQuestion.cfm page is reloaded via the cool oXmlHttp.open line and then the stateChangedQuestions() method is called and the questionsToMap div is repopulated. Sweet stuff - a little more complex than if you are reloading the entire page with an http request or reloading the entire event in a machii framework, but worth the responsiveness improvement.

There is lots of sample AJAX like code avail, but the key thing to get is that you can access the back end of your application and get refreshed query data without reloading the entire page. This results in a significant improvement in the responsiveness of the form.

I had to draw a picture on a piece of paper earlier this am when i was struggling to get my head back around this. I ended up drawing something like a container with a couple div tags included in each. With arrows indicating that the div tag include stuff was populated with the container and its link off to an external jscript file.

This also helped me to understand better the nature of asynchronous call -vs- a synchronous call. Flex too uses the asynchronous model with ActionScript rather than javascript to communicate with the server.

Monday, July 28, 2008

Refactoring MVC

I am continuing work refactoring a fairly large amount of code. Initially, i added ColdSpring to manage the model objects relationships, dependencies etc. As i moved toward completion of this work, i started looking more closely at a couple of the DAOs and Gateways that i had rewired. I noticed a bit of code left over from the initial incarnations of these components. These components have been around a long time and are used in the *main application differently than in this *sub application. I thought it a good idea to create a components and store them within the model path of the sub application, rather than in a more generic /org. path. I copied the components from the /org. path, rewired their init() methods, actually removed them since ColdSpring is now managing them, and removed a good deal of the existing functions that were needed in the main app but not the sub app, and added a couple new methods that were previously in a cfm that i was including. I could have continued to add more methods to the existing old bloated cfcs in the /org path, but decided for a clean break. As i was refactoring today, it felt like the right decision.

I have a couple view pages that are using AJAX techniques, so the event context or que is not reloading - so i had the lookup code in a cfm file. I moved that code into the respective Gateways (one for item mapping, the other for assessment questions). I added methods to their respective services and called the services from the view page, using the object pointer provided by the ColdSpring framework.

I need to figure out how to direct the AJAX calls via the machii framework - so i could use the listeners to get the updated request sets. I don't think this is possible, since we are not and do not want to reload the entire event framework on each of the requests - thats the gain provided by AJAX. So, i use the ColdSpring provided pointer and call the service directly from the view page without reloading the event que. This is still not perfect, but moves the SQL back into the gateway where it belongs and allows me to reuse that code if i swap out the current view with another, say a swf.

Wednesday, July 23, 2008

I stumbled across a blog today...

Written by a former co-worker. Turns out he wrote the blog application using machii. As i dug down into the application, i was pleased to see so many best practices in play. Just a few:

the application uses filers and plugins wisely, uses event-args in view pages, this creates a single point of edit - so we always know where to find variables defined in view pages in the event that is including the event.

view, controller(s) tightly coupled, along with the plugin and filter CFCs - they are part of the application.

A sub application to handle administration duties.

The model layer contains the listeners, which i prefer to store in a separate physical folder - since they are part of the application, not part of the model. The *entities modeled in the application are organized by entity folder with a bean, manager (i would have used service) DAO and Gateway in each folder. One of the entity folders did not contain a bean, so the developer was not blindly following the 4:1 design pattern, thats a good thing. He could have had combined service or manager responsibility for a couple of the entity managers. They are similar and both are a little light.

The listeners seem to be only passing control along to its respective manager, while the managers are instantiating their dependent DAO and Gateway objects. There is no ColdSpring or other model manager at play. As a consequence, the collaborating components have knowledge of each other sprinkled in to each other. Listeners are instantiating managers, managers instantiating DAOs, Gateways and other managers.

Listeners are referencing controller properties to pass along as args to managers. If a model manager was in play, it would be doing this, promoting lesser coupling between the listener and manager (application and model).

Objects treated as objects, passing by reference. The DAO is passed in a reference to its bean and uses it when updating the database.

Filters with configure methods, like listeners, they use configure not init for initialization and reference controller properties, since the filters, plugins and listeners are all registered in the controller - they all can access the properties. One difference is listeners extend listeners, filters extend filters and plugins extend plugins, all different parts of the machii framework. Remember to think of the plugins as cross cutting - or needed across all events in the application. In the plugin configure method, there is a UDF object created that is called in the pre-process of each event to get a tick count - what a geek. Interesting too that the developer stored the UDF.cfc with the views?

Remember each non-correlation table *should have its own bean to represent a record from the table when that record is in play. That bean should contain its own validation logic, avoiding the lean bean syndrome. A gateway to aggregate larger number of records from the table and a manager to handle requests of the bean, DAO or gateway.

In summary, lots of abstraction and encapsulation - promoting reuse and ease of maintenance.

Wednesday, July 16, 2008

ColdSpring OO design refactoring

Today, i begin a minor - major rework of a piece of software that i created about a year ago. The primary areas where i intend to do this work is in the model layer of the application. I plan to re-factor code by moving bus. logic further down stream into the bus object bean. I actually need to use that too, i am not really using the bean to do the CRUD work.

I plan to use ColdSpring to create the bus object, the service and its dependencies and to tweak the controller to use the service where necessary. I will tweak the service to utilize the CRUD methods in a more pure OO implementation. This means passing around the reference to the bus object and using it when performing the CRUD operations. The refactoring in the service, DAO and Gateway will include removing init methods, since ColdSpring will be handling the creation, initialization and dependencies. As a result, the knowledge of the collaborating entities will be lifted from the collaborators and placed in an abstract container, ColdSpring. This again promotes reuse of the tighly cohesive objects with little coupling. The coupling is abstracted away.

The results of this refactoring will not be evident on the user side, there will not be any changes to the GUI, probably a bit to the API, but the actual changes to the application front end will come later.

I will check back in with progress later.

Hi level steps:

1 - create a new services configuration file in the sub app for the objects to be created and managed in the assessments subapp.

2 - plug coldspring into the machii controller

3 - point the plugin at the services file

4 - add the objects to the services file

5 - modify the objects added to the services file, removing the knowledge of each other, remove the init methods. Create setter methods in services, so dependency injection references will work! Remember to name the setter method the same as the injecting method, like setBeanName. For objects that have init() methods left, DAOs, Gateways, Utils, if instantiating from CS, pass in required parameters using CS provided tool, $varname. For now, i decided to not require the parameter and gave it a default value, this way, i can simply add the parameter in the CS container at any point and it will just work!

b - other things i needed to clean up in prepping objects for CS and OO purity included; removing extends from two of the objects, these are old from years ago, i copied into my application space and noticed they were extending listeners, opps - i noticed a bunch of extra methods after i had created and dumped the bean, when i looked more closely, i noticed that the objects (assessmentDAO, assessmentGateway) where extending the listners - that was a mistake and highlights the fact that these two objects have sat out in space and not be used. One of the objects was not returning itself either.

6 - I currently have the bootstrapping code in the index.cfm file in the root of the sub-application. I wanted to follow the best practice from CF objective machii training where we would use Application.cfc and load all the bootstrapper code in it, and leave a empty index.cfm file. I tried that and had problems, and was not willing to look further into it.

7 - I also spend time in the listeners, removing object creation code from the configure method. Im still not totally clear what the best practices are for referencing bootstrapper variables created pointing to the coldspring created objects from within the machii listeners. I am currently using variables.amanager = application.CSBeanFactory.getBean("beanName");.

Wednesday, July 9, 2008

Java Coldfusion Spring Coldspring

I was reading Brian Kotek blog today and came across posting about CF objective - in his post he mentioned Andy Powell session about using a Java Model and a CF controller and view. I just happened to listen to the podcast on this the other day, it was a CF weekly podcast from 2008 with Andy, Matt and Peter. The valuable grok?

Coldfusion and Java are becoming more and more interchangeable - not competing, eachother, but integrating better. CF is still the faster way to go from a-z and has better integration with stuff like Flex and other tools.

CF has frameworks specific to it, like machii, Coldspring, Transfer.

Java has frameworks too, lots of them, notably, struts, Ruby, Spring.

CF = ColdSpring to manage model
Java = Spring to manage model

Another interesting point from Joe Rinehart regarding coldfusion, java, html and flex.

"As I've been moving away from doing HTML UI's, my perspective on CF has changed a good deal. While I think ColdFusion is top-notch for doing HTML UIs and the whole view/controller side of the equation, modeling applications in CFCs has become both a hassle (typing them kills me now that I'm used to other languages) and a liability (they're _still_ not terribly performant in comparison to raw Java, where I can still go dynamic via Groovy). Because a good deal of my work is now in Flex, I have less and less of a reason to use ColdFusion unless I need to render HTML - at which point it's simply the best tool for the job and definitely worth its price a few times over."

ORM transfer

I'm reading a post by Brian Kotek today and came across a link to another blog about ORM. I have been hearing about ORMs for a long time, i recall when Tracy Logan, a former co-worked and extremely talented programmer, brought this up a couple years ago. Something about Transfer automatically generating cfcs for you and basic SQL. My initial reaction was defensive "why would i want a program that does my job for me? - thats my job". I suspect that is a typical reaction when one does not really understand something, disparage it since you do not understand it. Anyway, I have heard other coldfusion developers talking about ORMs in the past but it has remained to me an abstract concept.

Today, when i when to this Transfer ORM site, i was ready to listen. The high level statement about developing OO web applications was very succinct.

"When developing an Object Oriented web based application, it is normal to have a database with relational tables and a series of objects that represent that data."

First off, i did not know that Transfer was written for ColdFusion, i learned that ORM means "Object Relational Mappers". It may be that until now, my OO skills where lacking and i was not ready to see this for what it is. It may also be that i am currently not doing much new development, most is refactoring. I will take the same approach i have regarding OO design, machii, coldspring, design patterns - slow and in small bits. I think too that once you have *struggled with CFC plumbing in DAOs and Gateways and experienced enough create, edit, delete, read method writing including the tedious SQL then you are ready to see this type of tool as an asset.

Just the intangible gain of having worked with an ORM is valuable. There is always something to glean when trying new technologies.

Tuesday, July 8, 2008

Refactoring, OO design, abstraction

I came across a blog today that informed my understanding a bit...here is the

The author speaks of good OO principles regarding model design. He specifies 4 layers or tiers, with the service tier as the primary that the controller speaks to. He talked about the problem that occurs when one dogmatically applies the 4:1 ratio, a service, bus. object, DAO and gateway for every entity in the model. This is what Sean Corfield also said to me about avoiding the anti - pattern.

Its real hard to see this at first, when you are simply trying to get your head around why you need all these tiers and specialized objects in the first place. Eventually, this stuff begins to sink in and you state to see the beauty of the OO designed model, then you can start to consider that sometimes you don't need a specific service for each bus. entity. In fact, you probably do not and a single service could serve like minded objects. This could also be true around DAO's and Gateways. Use the 4:1 approach as a guideline, not a dogmatic rule.

I read a good Hal Helms article yesterday about the workings of an OO designed model and how its really a bunch of little encapsulated objects collaborating with each other as needed to get the work done. Think of an ant hill and how each ant has its own special little thing it does, when looking at it from ground level, its very intimidating, trying to figure out who is doing what, but lift up a few feet, take a more global view and you can see the entire orchestra of work.

Another good point was the refactoring that occurs as you work through a model over time. He describes his experience this way, I started seeing logic in my controller that belonged in the model, so i would move it into the service layer. Then i would see the logic in the service layer really belonging to the bus. object, so i would move it into there. His definition of refactoring then sounded like pushing logic further downstream, where it belonged creating rich bus. objects that took care of themselves and leaner service entities that took care of calling other objects and directing traffic with a smaller amount of bus. logic. Its totally legit to have bus. logic in the service, since the service is part of the model layer, while listeners in frameworks should not have bus. logic, since they are part of the application, but alot of that logic really should be in the bus. objects.

Then he went on to talk about the abstraction of the service layer into a base or super service object that could handle calls to like methods across similar services. This is applying the principle of if its the same, then pull it out of the two places and put into a single place and use it as a base. This abstract service would then be extended by the concrete services with the ability to override the base method if needed. This is good, but does add a bit more complexity in the base class.

I also listed to a podcast today about CF and Java working together, which reminded me that CF is still not a pure OO language, its like an OO language, this technique of basing and extending is very much a core OO principle.

Finally, the author discussed the use of ORMs like transfer to automate the creation of the bus. objects - relieving the pain of having to do the plumbing of each of those objects. This reminded me of previous readings about programs like reactor that would do a reverse engineering and read the database and create sub. object stubs for tables int he DB., hopefully skipping over association tables. This stubbing likely includes an init method that sets the tables cols to some value and creates getter and setter methods for each.

Monday, July 7, 2008

Problem solving Coldspring

I had been experiencing a little problem with my ColdSpring code. It took me three attempts to see what the problem was. I had been coldspringing a couple services in our main application, meaning i was removing the object creation code from the services, and placing in the ColdSpring container. The trend chart has a service, DAO and Gateway object. The trend chart also uses questions from assessment exams - the question object has its own service, bean, DAO, and Gateway. The trend chart service has a dependency on all three of these other objects or collaborators, trendDAO, trendGateway and QuestionService.

I first created the 'beans' for the question then for the trend chart. Then i wired up the questionService with a reference to the questionGateway and the trendService with the trendDAO, trendGateway and questionService.

Once the wiring was done, i went about setting up the service objects to allow them to be injected . Starting with the questionService, i added a setQuestionGateway method - thats the object that the questionService is dependent upon and the services file is trying to inject during the questionService creation. Then i added three setter methods to the trendService, setTrendDAO, setTrendGateway and setQuestionService - these three dependent objects are injected when the trendService is created.

Once this was completed, i was getting an annoying init() method error in my trendService object upon creation...hmmmm. I looked at this over a couple days, tried messing with the services file definition and with the depend objects but to no avail. After my vacation, i opened the offending trendService file and almost immediatly saw that my service was extending a the listener class. Opps! - The service does not extend a listner class, its not a listener. Once i removed that, it exposed another small error, which was a pathing problem to one of the dependent cfcs. Now thats its cleared up, its so obvious and reminds me to not be careless with cutting and pasting and typing.

Finally, once the wiring was working, i removed the init() method from both of the service objects, i had commented them out during this phase - since all the initialization is not handled by ColdSpring. Thats the payoff - there is less coupling and knowledge sprinkling between the collaborators.

Moving on to ColdSpring ize more objects....

Monday, June 23, 2008

programming problem solving

I have been working on my little developers application, with the intention of implementing pure OO techniques and coldSpring. I am also implementing machii framework version1.6. I will start to exploit the new machii features later in this process. For now, its more about proper modeling of classes or components. Keeping things where they belong. I mean keeping the model layer agnostic of the application that is using it, keeping bus logic in the service or model layer. Keeping validation logic in the beans, avoiding anemic bean syndrome.

Initially, i put the object creation code in the service for its dependent dao and gateway objects, got that working, then plugged coldSpring into the machii framework, ensured that was ok by creating the pointer object into the coldSpring bean factory (the CS black box). Once that worked, i added the acual bean creation code to the services.xml file (thats the one cs consumes to read your component definitions. I defined the service, DAO and Gateway components in the services xml file, with the DOA and Gateway as ref. objects within the services object. I then added the setxxx methods to the service object and finally removed the code from the init method in the service.

Once that was working, yea! I ran across a blog where someone mentioned creating a utility debugger and using it to dump from within a cfscript block. I probably read something like this before, but i was not ready to grok it. Now, i groked it. I set up a utility cfc and registered it in the coldSpring container (services.xml) and referenced it from the bootstrapper object, Application.cfc. I created a application scope on it, so i could reference it from any objects in the model. Ive used it a couple times already, and find it very useful. Brilliant!

Think of coldSpring as an attachment to the model layer. At application start, there has to be some instruction that says reference and scope the beans that are defined by the coldSpring framework in the services.xml file. This does create a thin layer of coupling between the application and the model layer, but its contained to a single bootstrapper object that has the knowledge of the coldspring framework.

Think abstraction. The more abstraction, the better. Abstraction = less knowledge of the collaborating entities. There will always be some coupling, but it is favored to reduce that coupling to its purest form.

Tuesday, June 17, 2008

framework OO design debugging

I got my developer app working today. This is my new app. that is utilizing pure OO techniques. It is still a shift for me, as i struggle, i see this more. Think in terms of objects, encapsulated objects, that contain their own data. Pass around a reference to this object, rather than passing along pieces of data by value. How does the object serve the application? Does the object know anything about what application is using it (lets hope not). Let the object take care of itself, keeping its own state and not reaching out to other objects (loosely coupled).

Its not ok to create just tiered applications anymore. I am thinking now more about objects and their state, relationships and bus. logic (which object should it belong, bean, service, DAO/Gateway) and even if i need a bean or service for an object. Could the entity be served by an existing object. I *should have less services than actual beans, as the application progresses. Its ok to start with the 4:1 (entity in your domain has bean, service, DAO, Gateway) - but this is a guide,not a rule! As Sean Corfield said, dont create an anti- pattern.

Anther problem i was running intois the mach-ii framework masking the errors (that i created first in my listener, then in my service, then in my DAO). The experience of stepping through the event flow is always valuable, but the framework was not helping by reporting a very unhelpful message. Is the framework really to blame for masking my mistakes? I think without a framework, i would have at least had a better path to follow regarding where CF was failing (in the listener, service, DAO/Gateway or somewhere else.

Anyway, i have worked my way through the problem. I have a listener that is handing off to a service. The service method requires a struct(listener passing in event.getArgs() ), takes the arguments passed in and calls a private method in the service that instantiates a new object and used the setter methods on that object to update with the arguments passed in from the listener. When the private method is complete creating and updating the object, it passes it back to the main method, who then calls the DAO to it its work. The resulting object reference passed back by the helper method is used as an arg to the DAO. Passing by reference, not value.

This is a big leap for me. I am not passing around a bunch of data, but rather an object reference that is resp. for keeping its own data. Object = encapsulation of its own methods AND its own data.

Im still not sure if my service is real smart, but i am passing by reference now. In my DAO create method, i will keep the validation logic around the actual SQL insert. This is keeping with the fat bus. ready object (non anemic).

Saturday, June 14, 2008

Design Patters (official)

Gleaning from Sean Corfield presentation.

Pattern: Composite View
A composite view is a view that includes other views

Patterns have four parts:
• Name - the common vocabulary
• Problem - “forces” that determine when the
pattern is applicable
• Solution - a template for solving the problem
• Consequences - “pros and cons”

APPLICATION / onApplicationStart()
is a singleton pattern (once entity accessible from one place)

problem (trade off) is breaks encapsulation when object x needs to reference some application scoped variable. A solution is to use something like CS, that injects object X at instantion with the application scoped variable (which is no longer application scoped at this point).

A common problem

I have components that make up my user
security logic but I don't want to expose them to
other code, in case I want to change how its implemented.

Create a new component that has a simple
API that calls the security components.

Think in terms of trade / offs (pros and cons) a pattern has both!
For example

Application code no longer needs to know about the
internals of your security system (+)

Application code can still get at the “low-level”
components if it needs to (+/-)

Some redundancy of methods between the API and
the underlying components (-)


Pattern - Facade ( common very helpful)
Problem - as a subsystem grows, it becomes more
complex with a large number of smaller objects

Solution - introduce a single component that
provides a simple API to the set of components
within the subsystem

Consequences - shields clients from the inside of the
subsystem, reducing complexity and coupling; does
not prevent access to subsystem if needed

Often only one instance of a facade is needed(singleton)

Pattern Name: Front Controller
- like fusebox or machii or global index, each of these frameworks is a front controller pattern.

Problem - need to apply consistent logic across all
requests in an application (security, layout etc)

Solution - route all requests through a single file that
decides how to process the request

Singleton and Facade refer to objects, most design patterns are focused on OO design

Consequences - centralized control, easy to change
how requests are handled in a consistent manner,
moves logic out of individual pages into controller
(which can become complex)

cfinterface specifies the methods a component provides (API) but not how they behave. cfcomponent *implements* the interface to specify the behavior. An interface can have many implementations. But duck typing is more powerful and appropriate for
ColdFusion - onMissingMethod() lets you implement any methods dynamically.

-- Sean Corfield

However, this is starting at the wrong end. When you
learn patterns by focusing on the solutions they
present, it makes it hard to determine the situations in
which a pattern applies. This only tells us what to do
but not when to use it or why to do it.”
-- Alan Shalloway

Creational patterns
Abstract Factory, Builder, Factory Method,
Prototype, Singleton
Structural patterns
Adapter, Bridge, Composite, Decorator, Facade,
Flyweight, Proxy
Behavioral patterns
Chain of Responsibility, Command, Interpreter,
Iterator, Mediator, Memento, Observer, State,
Strategy, Template Method, Visitor

Frameworks are designed to solve common problems
• Application frameworks usually implement several patterns
• Front Controller - everything goes through index.cfm
• Model-View-Controller - segregation of the presentation and
business tiers

ColdSpring
• Chain of Responsibility - each “aspect” calls methods on the next
“aspect” until the underlying business object is reached
• Identity Map - cache of objects accessed by “id” (bean name)
• Proxy - same API as your business objects but intercepts method
calls to execute before, after or around “advice”

Friday, June 13, 2008

MachII 1.5

When we upgrade our machii framework code to version 1.5 (released a year ago) there are several changes to note.

First, our existing code should not be effected. Although when i tried this briefly a couple weeks ago, i had a problem with one of the application controllers that was using a .dot notation in the event names. For example; in one of our sub-app controllers, most of the event names look like this;

event-handler event="somename.somethingelse.somethingelse" access="..."/

I have posted this question in the machii google group to see if any known problems with this notation exist.

Also, i have been running across the concept of a "bootstrapper" file or process in a number of blogs recently. The bootstrapper is the start-up routine or file that is responsible for doing application startup configuration. In the old school, no framework world, this would be the index.cfm file. I used to call this the driver, from my days as a procedural programmer. CF also has long supported the notion of an Application.cfm file, work done here has the application scope. With machii, there is the concept of the Application.cfc file and the index.cfm file. Prior to version 1.5 or machii, there was often setup code in the index.cfm file, including the include of the actual framework. In mach1.5, this goes away and no code lives in the index.cfm file, it all goes in the Application.cfc, which is actually extending the machii framework.

When we upgrade the machii framework code to 1.5, we will have to be careful to move that important bootstrapper info from the index.cfm file to the Application.cfc file.

When looking critically at this new bootstrapper file, think in terms of these areas:

application wide properties
machII specific properties
public functions, like
onRequestStart

Once this is done, we should not have too many other issues, then we can start taking advantage of the new 1.5 features, like the include functionality, that will allow us to break up the controllers into smaller pieces.

Where to put listeners and model code

I ran across a blog discussion today about best practices regarding locations of mach-ii listeners -vs- model code.

A summary.

Listeners are not part of your model layer, so keep them separate from the model code.

Put listeners into a /listeners folder.

Put model code in a /model folder.

In the model layer, some suggested organizing the cfcs like this:

/model/Beans
/model/Services
/model/DOA
/model/Gateway

This is know as grouping by functionality.

Most of the expert opinion (Matt Woodward, Peter Farrell) favored this approach for the model layer.

/model/busObject/

where the bean, service, DAO and Gateway objects were grouped by type. Since these objects comprise the abstract concept of a package, store them as a package. This seems more intuitive, as other programmers come into the application, they will take the approach of what bus objects are there and see what pieces of that package exist.

This is a quote from P Farrell "Otherwise, you are breaking objects into
directories based on object type (pattern/functionality of the object)
instead of the object's purpose (having to do with "user" stuff). This
is counter-intuitive as a developer would have to scan through a
"beans", "gateways", "services" and "daos" directories to see if the
User (bean) has a corresponding service, dao, gateway, etc.. Much
easier (and it makes more sense in the long run) to group by object
group instead of object type (pattern/function). "

Wednesday, June 11, 2008

A ColdSpring conversation between Mex and Lex

A hypothetical conversation between, a lesser experienced developer, Lex, and a more experienced developer Mex.

Lex, "what the heck is coldspring?"

Mex, "a framework that helps manage the model layer of your application"

Lex, "whats a model layer"

Mex, "the part of your programming that contains the bus. logic used in the program"

Lex, "how do i know if i have a model layer? and what is the bus. logic"

Mex, "does your application follow the MVC design pattern?"

Lex, "whats MVC?"

Mex, "a way of building your application so the view code is separated from the database and bus. logic code"

Lex, "i think we follow that, i have only really worked on the view side, thats coldfusion .cfm files, right?"

Mex, "yes, cfm files are usually a big part of the view layer, if your using ColdFusion. The model layer which contains your bus. logic are stored in coldFusion files called CFCs. The CFCs are the classes, like in Java."

Lex, "so what does ColdSpring do again?"

Mex, "Coldspring managers the model layer and helps with the relationships, or dependencies that exist between CFCs that collaborate in your model layer".

Lex, "You mean like a service or manager CFC that uses a DAO or Gateway CFC?"

Mex, "exactly like that. The service component or CFC is dependent on the DAO and Gateway to do its job. The way that is typically handled is when the service object is created, it has an init method or function that is called that creates the other objects it needs. In a larger application that has lots of services, this can become a big headache to keep track of."

Lex, "I think i heard some of the other programmers i work with complaining about this and how you have to open a bunch of files to track down what is being created and where."

Mex, "right, CS reduces that complexity by putting all that object create code into a single file or container. That file is responsible for defining all singleton objects in the application."

Lex, "instead of putting create object code in the init method of the service for the DAO and Gateway, you put it in a coldspring file? I could do that for all the services in the application in this one file?"

Mex, "yes and yes"

Lex, "Is the coldspring file magic?"

Mex, "sort of, seriously, its just a xml style file, its really not that complicated, once you understand what its doing"

Lex, "ok, im in, lets get down to some nitty gritty"

Mex, "i thought you would never ask"

Mex.....

CS is a framework, a black box, with a lot of code that you never touch, you simply use it. If you are using a framework like mach-ii, fusebox or model-glue, you have specific "plug ins or hooks" that connect CS to your model. Mach-ii has a plug-in architecture that connects CS to your application.

You write a little code upon application start that executes and creates an object pointer to the black box (CS). Then you use the CS object passing into it the file path to your bean definition file to load the definitions. Each of the beans (objects) is loaded in the application scope. This is really the only file that CS interacts with.

If the object that you are creating has no dependencies, its very simple to create the object with a xml style notation. If the object needs arguments passed in upon instantiation, use the arguments parameter to pass that data along. If the object has dependencies on other objects, use the tag to inject the dependency into the parent dependent object. Think of this as an "inner-bean". If the injected object is only used by the parent object, then define the collaborating objects like this:

bean id="someService" class="somepath.someService"
property name="someGateway"
bean id="someGateway" class="somepath.someGateway"
/property
/bean

When someService is created, it is injected with the someGateway object. The someGateway object is only available to the someService object. Sometimes, the object needs a more global scope, so other objects can reference it as an injection.

If the object being injected is already defined, use this notation to inject:

bean id="someService" class="somepath.someService"
property name="someGateway"
ref bean="someGateway"/
/property
/bean


The difference is that you are not injecting a new object


property name="someGateway"
bean id="someGateway" class="somepath.someGateway"
/property

but are injecting an existing object

property name="someGateway"
ref bean="someGateway"/
/property


ya dig?

More to follow.

Tuesday, June 10, 2008

Anemic Domain Model

I was reading an article by Sean Corfield in Fusion Authority today. I have read this article before, but my brain was not ready to grok it, today, it grokked.

The main concept is that too often we load up bus. logic in the service object instead of the bean or value object where it belongs. If you think critically on this, it makes sense that since the data and methods of an object are encapsulated into the value or bean object, so too should the bus. rules around it.

The anemic model is one where the value beans are just containers with state and getter and setter methods - not much else, the bus. rules are stored in the service object.

Sean makes a good point that many of our web applications are getting record sets, presenting in a collection, hiding detail, proving details about one record when requested, not alot of bus. logic to fill up our value beans. But, a good candidate is validation logic when dealing with single or groups of recs, rather than putting that logic in the service, leave it in the value bean - let it live along with the data and methods that it works on.

I recently completed grokking why bus. logic should be in the service and not the listener (model layer, not the application). I supplemented my understanding by going through a few of the older listeners and moving bus. logic out of and into related service object. Perhaps i will iterate again, moving small amount of logic from the services into the beans.

Lets turn those anemic value objects into rich domain objects!

Friday, June 6, 2008

hard core refacoring

I have spent the past 2 days retooling the model layer of a mach-ii application.

I have renamed numerous listeners and moved then into a new listeners folder. I am really trying to promote the idea of model and application autonomy.

/listeners/ objectNameLister1, ... objectNameListerx

/model/objectName/ service, bean, DAO, Gateway

Each time i renamed a listener, i did a careful search of the controller to update all instances of the old listener name. In some cases, this was only a couple instances, in others, there were many. This also gave a sense of what parts of the application are more widely used.

In a few cases, i renamed a manager that was really a listener, moved it into the listener folder and created a new service cfc. The new listener should only speak to its registered service, so i had additional refactoring to do in the listener. I updated methods that had knowledge of the DAO and Gateway moving that into the respective service. This supports best practices of the listener being coupled to the application and bus. logic living in the model layer, not the listener.

Think about the model layer as application agnostic. Your model layer should be usable by another application. Imagine there is no mach-ii framework with listeners to invoke services. Another application may want to use the objects in your model layer. I moved ALL knowledge of DAO, Gateway and other services from the listeners into their service. The service is the king of the jungle, not the listener. The listener just passes things along.

There were a few listener methods where i left bus. logic in place, but that logic is dealing with announcing of events, making it application logic, which belongs in the listener NOT the service.

Changing the location of the listeners required me to update the path in one place, the mach-ii listeners configuration. If i changed the location of the model classes, i had to change the path of the object invocation (init) method in the service, DAO and Gateway. After doing this a few times, i really stated to see the beauty of the coldSpring layer, which encapsulates this type of change into a single entity, the coldSpring.xml file. I also saw that some of the objects are not taking advantage of the coldSpring framework. These are candidates for coldSpring.

When i encountered listeners and services that had an empty configuration or init method, at least in terms of object creation, and i would see pointer references in class methods, i knew those pointers were defined somewhere, who would have knowledge of such pointers? I also noticed a set method that accepted the object itself at the bottom of those classes. Each of these things is a clear indicator that there is an object management framework in play.

I am still getting my head around how coldSpring is doing things, i thought i would deploy all these changes first, then work on a coldSpring deployment separately.

Things are jelling now, jellin like a felon, architecturally speaking.

Wednesday, June 4, 2008

Evolution of a MVC application

I have been tasked the honor of bringing others into or up to speed with a big MVC application. That's ok, i used to be a teacher and trainer, part of my brain enjoys the mentoring role.

I have been studying the architecture of the application, doing some reverse engineering for awhile and have a little summary i would like to share. Blogging this stuff helps me internalize and forces me to think more critically.

In the beginning our application did not use services. Most entities were created following the

Bean
Manager
DAO
Gateway

design patten. Which is fine, except the managers are actually the listeners, they are extending the mach-ii framework listener. All of these files are located in the root of the application in the model folder. Object instantiations to the DAO/Gateway occur in the managers (listener) constructor. The manager is trying to act like a manager (service) by creating its dependency objects (DAO, Gateway) in its constructor. Thats fine, good practice.

As the application grew, real managers started appearing, but not in the model folder (that should just be listeners) in a org. path. The idea of the org. path is to promote the concept that the model or bus. layer is application agnostic. It should not live in the same file structure as the applications listeners. Ill buy that.

The managers, playing the service role, live in the org path along with the other depenency objects, DAO, gateway and Bean (value bean). The managers (services) are responsible for instantiating their dependency objects (DAO, Gateway and bean). The listeners in the model path are only instantiating their manager or service object.

As sub applications start appearing, listeners are where they should, in the model layer and in a couple cases, the related bus. logic (bean, service, DAO, Gateway) appear in a folder beneath the model layer. This is ok, but does not seem to promote the idea of reusable model layer components or agnostic model layer.

In most cases, the listeners are instantiating their service object in their constructors while the service is instantiating their dependent objects in the init functions.

Eventually, ColdSpring was introduced to start managing all these object and dependency object creation. ColdSpring is a framework that abstracts the knowledge of dependencies from the actual objects. Ill study more on this as it appears some objects are not yet utilizing this feature.

Most of the application is following OO practices, meaning that object references are being passed along to service and DAO funtions that are requiring them and using the reference to the bean to handle updating or persistence requirements. Gateway functions are typically accepting values, not references and returning queries.

Some of the application functionality, like the stuff i wrote, is using object wrappers but is too often using procedural pass by value and not object reference. It was not until recently that i really started looking critically at this and reading in blogs why this is problematic.

As i continue to stretch my brain and teach others about this application architecture, i will continue to re-factor and implement OO practices.

Refactoring with on eye on patterns

I have been looking with a different eye at existing code in our applications. Refactoring code is an important part of any programmers job. I hear the stats about 75% of programmers time is spent maintaining existing systems. That seems about right to me. I have spent a lot of time the past month studying design patterns and best practices for CF developers, since the excellent CF Objective conference in May.

I have been looking at listeners in our mach-ii application and their managers (services) with an eye for moving bus. logic out of the listener and into the service. We actually had a cfc that was named a manager, but was actually a listener, it was extending the machii listener framework and was referencing event args. but did not have a service layer at all. I have been refactoring, renaming the manager to listener and creating a service layer between the listener and DAO/Gateway. It has taken me a long time to really get my head around why we would need all these layers, but i think its finally starting to jell.

I have spent lots of time in blogs, tutorials, books and existing code, learning from the experts, standing on the shoulders of giants, as my former co-worker liked to say.

I will continue looking at the listener and moving bus. logic out and into the service layer repeating the mantra "the listener only passes data to the service layer", its a traffic cop, not a problem solver. The listener can contain logic that directs the flow of the application, but not any logic that pertains to the bus. objects. The bus. objects are application agnostic!

I woke up this am thinking and repeating this to my 11 year old son.

"The bean is a container, that holds data and instructions about something, an object". When the application needs to reference the data or behaviors of the bean, it asks the service layer to do it. The service layer instantiates the bean and passes references to the bean into DAO which will operate on the bean." In others words, a reference to the bean is passed along to service who then passes where it needs to. Any functions that manipulate the data stored in the bean do so by reference. A DAO method requires a object be passed in and references the attibutes of the object via the argument reference passed in."

We are no longer passing values around from one function to another, but rather passing references to a bean.

Friday, May 30, 2008

Evils of debugging tiered software

Typically, one of the payoffs of a tiered MVC designed application is ease of maintenance. I'm not so sure awhen it comes to debugging. If you are familiar with the application architecture and the application is consistent in how it models objects then the debugging is easier.

I just spend about 3 hrs trying to solve a bug that i introduced while refactoring. I am refactoring some code in a pair of collaborating objects a listener and a service .

I am moving bus. logic from the listener into the service. My listener instantiates the service in its configure method. I created the problem in the one of the service functions, but the error was being reported by CF in the listener constructor at the line number where the instantiation to the service was being called. Eventually, i was able to track the error down in the service function that was using the same variable name for both an argument and a locally vared variable. The error was reported correctly but it took me way too long to figure out that the reporting of the error in the listener constructor was caused by a function in the service. Seems obvious in hindsight, that the listener constructor was failing because it was creating the new object that had to parse the entire cfc before it would create a new instance of itself.

Moral - if the error is occurring in a constructor or init function, then look carefully down stream into the instantiated objects.

Tuesday, May 27, 2008

Listener -vs- service layer

Ok, ive been feeling this question for awhile in one of our main applications DataMentor. We have a machii implementation around the application. I am seeing more clearly the reason that we should put our business logic in a service and not a listener. The listeners are part of the application, and our service layer should be application agnostic. I can look back at early design decisions and see bus. logic in the listeners, and even listeners that were playing the role of service or manager. As we build new features into DataMentor, we can follow the best practices of services -vs- listeners and we can continue to re-factor code as we make smaller changes to legacy logic.

Here are a few excerpts from some respected machii architects, Sean Corfield and others.

"If you built a service layer that is independent of the framework that orchestrates actions taken against the model and then you built one or more listeners that mostly just delegate to that service layer, you'll be in good shape."

"Don't think it won't happen to you! I guarantee that you'll find yourself putting a Flex front-end on a legacy Mach II application at some point and you'll wish you too had done a better job of separating your business model from your listeners!"

"Right, a web service front end will also show the same issues. And just to be clear, Flex, Flash and Web Services all rely on the model portion, the CFCs, and not Mach II (or Model-Glue) which is why separating the framework from the model is so important."

See full discussion here.

This is from the machii developers guide on listeners:

Mach II interacts with the Model portion of your application using components that extend MachII.framework.Listener. In a simple application, all of your business logic might be implemented in such listeners but this approach does not scale well with increasing application complexity because, amongst other things, it introduces a tight coupling between the elements of your business logic and the Mach II framework.

You are much better off ensuring there is only a thin layer of coupling between the framework and your application - if necessary, create new components that extend the Mach II listener component, whose sole purpose is to communicate those events to the components within your business model. In other words, try to isolate your business components from the framework components as much as possible: only listener components should know about the framework; only listener components should access Mach II properties; only listener components should announce events. The core business components should know nothing about Mach II and have no dependencies at all on the framework.


In our cfobjective class last month we had a spirited discussion about this. One of the principles i recall was the listeners job being to pass along data to the service layer. The only logic that should be in the listener is logic pertaining to program flow. The listener could announce other events, reference controller properties and set event arguments. When it was done doing these things, it simply handed the event args off to the service. The listener knows nothing about the model layer and the model layer knows nothing about the listener, excepts the names of methods exposed via the API.

Design Patters - more details

Design Patterns in ColdFusion

Content paraphrased from http://www.jroller.com/page/kwiersma.

I keep coming back to these patterns because I support a large application that implements all of them and have been asked to share my knowledge. This is the knowledge! Granted, there is a lot of business logic in the application, but the architecture of the application follows closely the the principles found in these patterns.

Beans ( Business Objects or Value Objects)
DAOs (Data Access Objects)
Gateways (Data Gateway Objects)
Services (Manager Objects)


The Bean
  • Typically represents a specific entity in your model
  • Carries "encapsulated" data between the different layers of your application
    • like a structure, instead of directly accessing data with a key you call a method
  • Helps organize data structures instead passing structures around ad-hoc
  • Has a consistent and simple interface (Controllable API)
  • Has methods called getters/setters (aka accessors) to access data [getFirstName() / setFirstName()]
  • Might be composed of other beans
  • Easily created with a code generator

DAO (data access object)
  • DAOs only interact with one row of data via the primary key
  • Used to save/load objects from data storage
  • A DAO could interface with: Database / Legacy persistent data storage (XML / Text File)
  • Usually have ScRuD method that take a bean
    • (ScRuD - Save | (create) | Read | (update) | Delete)

Gateways (Aggregated Data)
  • return one or more rows of data
  • Typically returns a cfquery object
  • Rarely it can return a bean (Querying by User/Pwd)
  • Performs functionality that may affect one or more rows
Services: (Kings of the Jungles)
  • Contains your business logic:
  • Bean Validation / Creation
  • Application specific business logic
  • Save / Load / Delete from DAO (via the facade pattern)
  • Gateway Interaction (via the facade pattern)
  • Usually depends on a DAO and Gateway
  • Services can consume other services (very social)