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.
Tuesday, July 29, 2008
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.
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.
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");.
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."
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.
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.
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....
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....
Subscribe to:
Posts (Atom)