What is in my beans? -- WAS: 3rd party libs and services question

55 views
Skip to first unread message

Kevin Pepperman

unread,
Mar 6, 2010, 9:18:46 PM3/6/10
to framework-one
Just to follow through-- I got a few emails questioning my reply and my thinking on the original post "3rd party libs and services question".

When I say I add helper methods to my transient beans instead of having the functions exist in a service layer, I do have a few rules that define what methods go into my transients.

I think all query's and config should be in the service layer, injected as args or setters.
All global/generic methods should be in a service layer too.
Any methods that act directly on the data that a transient bean contains should be in the bean.
eg: makeName(FIRTSNAME, LASTNAME){ return "#FIRTSNAME# #LASTNAME#";}
I also add all methods that generate the output from the querys or internal data, weather I am returning a Array,Struct,query,HTML or what-have-you I always add those methods to the bean.
eg: I don't think a transient should need a service layer just to convert a query of available colors to a array of colors, a list of colors, JSONP text, and a select box. 

The bean should know how to do this, I don't like passing my beans around in the service, and I especially don't like passing data around in the service layer and calling methods in the bean to process data. The beans have an init() constructor, and a setup() method called either by the bean-injector or the controller layer, passing in the reference to either the request context or the event object. The setup() method does all the work, I return the fully populated RICH bean to the controller, or just use the event object/context variables in the view.
I don't need to tell my bean how or when to do something or how to get the data it needs. 

A lot of my practice is from what I have found has worked for myself, especially when I was trying to learn OOP. I came from a procedural CFML and PHP backround, I, like many knew I had to learn OOP when cfc's and PHP classes matured.
But I was intimidated by the seemingly more complex way of thinking, and even after months of hard work I still was not as productive as I was in my "Cowboy Coder/Code by Coincidence/just get it to work" days.
Now that a couple years have gone by and I have developed and worked on several OOP projects my productivity is way better than It used to be. An my applications are much simpler to work on.

The big shift for me was realizing how to begin my OOP projects, the biggest mistakes I made from the beginning was trying to get something simple to work within complex systems instead of using the frameworks for code that has already been tested.
Now when I begin something, I don't just whip out MachII/ColdSpring and code by configuration.
All that will do is constrain you to the framework and create another layer of complexity that should not exist at the testing/dev phase. You should never be chasing missing variables or syntax errors in a application scoped service component, just because you want to test code in the live framework. You end up spending more time trying to figure out why ColdSpring wont load the configuration.xml with your new beans then actually fixing the problem.
Compile time errors are nearly impossible to figure out in frameworks, but on a simple template its easy.

I start coding the old fashioned way, good old Procedural code in plain vanilla .cfm.
I create my methods, I try stuff out-- I get things to work first in a simple template, then as the code progresses I may move some methods to a .cfc, but I maintain the simplicity of testing in the single template, I compose my components in the page they way I need them, then I create a test suite of each method in each .cfc.

After I am happy with the code, I can generate code for any framework, .war the test code with the framework/server and plunk the .war into Tomcat to test.
The point being taking advantage of the benefits of procedural code (YES, there are many benefits) to develop, then moving it to objects and frameworks after you know it works correct.

I followed as many groups and read as much about it as I could-- but most of the stuff I read was either about Java or was using concepts and dogma that were conceived/coined by Java.
Java, being a strictly typed language does not allow the "low level" code to be nearly as flexible as CFML. Coding in CFML so easy because we can do things in so many ways, our datatypes and process flow can be put together as simple or as complex as we want depending on our abilitys and confidence.

One of the biggest strengths of CFML/PHP is OOP, it allows massive systems to be programmed that allow huge flexibility.
Combined with the fact that we CAN use the code procedurally, these languages are (IMO) going to be around for a very long time.
I think it important for developers to always write code in ways that are comfortable and simple, and above all-- in a way that they can completely understand what they are doing.

I only use objects for the actual application once they are tested, I think OOP is not really a good way to write and test low level code and functions, but it is a great way to assemble complex systems.
--
/Kevin Pepperman

"They who can give up essential liberty to obtain a little temporary safety, deserve neither liberty nor safety." - Benjamin Franklin

Sean Corfield

unread,
Mar 9, 2010, 1:24:44 PM3/9/10
to framew...@googlegroups.com
A great post Kevin!

It's nice to see an emphasis on rich business object functionality
rather than what you so often see in "OO" CFML code: calls to getters
on beans, followed by calculations on those values, followed by calls
to setters on those beans. If we follow the "Tell, Don't Ask!"
principle, we should see very few calls to getters and setters. In
general, construction should take care of most "set" operations and
only views should be calling getters (and even then Peter Bell's
recommendations lean toward calling display() or field() methods on
the beans to get the display-ready formatted data or the form control
for editing).

Very interesting to hear your "start procedural and refactor to OO"
approach. That's quite unusual but I can see how it would work for a
lot of CFers. It does speak to a "red green refactor" mentality which
you find in test-driven development: writing the simplest code that
works and refactoring into the "correct" code (although there you
start with a test that fails - the 'red' part - and write the simplest
code, usually a method, that works - the 'green' part). The problem
with TDD for a lot of CFers is, I think, that it assumes objects and
CFers have a hard time coming up with the "right" objects in the first
place - something your approach addresses.

Thank you!

Sean

Kevin Pepperman

unread,
Mar 9, 2010, 7:45:13 PM3/9/10
to framew...@googlegroups.com
A lot of my thinking came from Javascript, PHP and Jquery.
In Javascript a function IS A object-- in fact everything is an object in javascript.
CFML is sort of the same, although it does not have anon functions yet.

I really like how PHP/JS lets you use OO all in one script, CFML makes it seem like OO is all about CFC's-- which it is NOT. OO is about encapsulation.
I think if you could use CFML like PHP/JS and create script objects then run them all in the same script, the concepts would be much simpler to grasp.
It is too easy to get bogged down in how the objects are interacting instead of what they are actually doing.

The more I look at OOP in general, the more I realize that the concepts strengths are not just because you put all your methods into a service/bean, but in the fact that you are looking at single name-spaced entities with multiple variables as an encapsulated container with methods.

In CFML a Struct() is still on object, a Hash Map if I recall, so I could not get past the reasons why OOP was using a bean just to do what a Struct() was already doing, albeit with no methods.
Once I started developing plugins for jquery, and learning how to use prototypes and name-spacing correctly, it really improved how I did OO in CFML.

I just began to realize that I was thinking about how to get things to work in OO way too hard, and not concentrating on what the actual code was doing.
I ended up with procedural code in a service, with beans and querys being passed around then returning a bean that only contained a struct() of my processed variables.

One day I read something you wrote about Rich beans vs Anemic and it really opened my eyes to what I was doing, All I was doing was making my code more complex, and the actual muscle in my code was doing exactly the same thing it would do if it were all procedural, only now its in a service, and my beans knew nothing about anything.
I had all of the complexity of OO and none of the benefits of rich beans.

So, I adopted a better approach by making sure that I encapsulate all my routines, and I test them all separate from my services and frameworks. I let my beans have all the sunlight and nutrients they needs to get the job done, and I only give my beans code that has been tested. 
As the bean matures I move some functions to the service layer.
It really does not matter where the CFML runs, it always does the same thing-- what matters is if you are really paying attention to how much each method is doing, and trying to break stuff down into simple methods rather than on HUGE method that procedurally processes a huge chunk of logic.
(i just typo-ed "methgods", which is prob a good interpretation of what I was doing wrong-- instead of "GOD" objects, I had "GOD" methods.)

I really try to not follow the "herd" on most things, I know there are benefits and problems with every approach. I try to fit only things that I can truly understand into my workflow.
I think that above all is the most important thing, understand what you are doing-- don't just use the latest greatest concepts just because.

The most issues I see people having is when something breaks in a complex system, and they cannot figure out why-- "my framework ate my error".
I say Test, test, test-- THEN assemble. 
Reply all
Reply to author
Forward
0 new messages