This is what I wrote in wiki today.
I have a struggle in having confidence with the design decision that I am making because:
- Eventhough I know OO, I actually know little about real world OO
- I'm having problem finding someone or some people at work that have the skills or even the interest in embarking in this learning journey together
The wiki article and the blog post were written to combat those concerns. I want to be corrected if I am wrong and hopefully they will spark some curiosity on other developers (finger crossed).
I have created a functionality that needs to be recorded in the logging table.
Normally, I would just need to create a CFQUERY on my processing template and I would probably cut and paste it from somewhere.
However there are problems with this approach:
- I cut and pasted the code which means I am duplicating the code across the system (a violation of DRY principle) - generally speaking this is considered as a bad practice in software engineering.
- What if someone added a new column to the table and to ensure consistency you want every single CFQUERY that saves to this table is updated as well. Do a system wide search (and pray your Dreamweaver doesn't crash in the process).
- What if there are "some hidden logic" that govern the insertion of record on that table that I might not be aware of ? Or logic that is added after I created the template. For example, in the future perhaps, we are requiring for every Email type of logging to have the activity subject column to be prefixed with the word "EMAIL:". To enforce this rule we would have to do search and place across system.
We need to restrict UPDATE/INSERT access to the this table and we need to be disciplined about it.
A service CFC is good for this. let's called it LoggingService.cfc and in it, we create a function called: saveLogInformation( stColumnsAndTheirValues )
This CFC and the function can also give us the flexibility on the implementation:
- You can put any rules/logic or data validation in this function - you can 100% sure that the latest logic will be reflected on this saving function - you don't have to do a keyword search on the whole system to work out how other pages are saving values to this table.
- You then can write straight CFQUERY or perhaps CFSTOREPROC on the function to save to the database - however I think it is better to actually use a Data Access component to do this.
- If you use a Data Access CFC then you can the option to:
- Write your own CFQUERY/CFSTOREPROC to save to database - you shouldn't put any logic in this - the logic is on the service - this component just do the saving and nothing else.
- Use a Model framework like Reactor/Transfer to manage it for you
So you will end up creating at least 2 CFCs:
- Service CFC
- Data Access CFC ( DAO )
Risks and Benefits
- If you somehow broke the CFC, the effect will be system-wide (it will not affect your project alone). Thus a thorough testing is mandatory.
- CFC creation are expensive in ColdFusion ( performance might decrease if lots of CFCs are created - but we are just starting so we don't have this issue - if this do become an issue - persisting the heavily used CFCs on SESSION or APPLICATION is recommended ).
Benefit is obvious - easier to maintain system.
Yes, creating a CFQUERY on your process form might take 10 minutes and doing this approach might take an hour. But you are saving someone else's time by creating something that is reusable and I believe you will improve the overall quality of the system (and hey you'll learn new concepts along the way too).