Paul Graham, entrepreneur, Lisp advocate, and general geek hero, posits1, and I am paraphrasing, that developers should develop in Lisp because otherwise they end up duplicating inherent Lisp functionality to build an advanced system. I currently work mostly with the Spring Framework, the initial and continuing goal of Spring is to simplify and "abstract out" a lot of the drudge work of building applications with J2EE, in fact what first seduced me was the ease, especially with an ORM like Hibernate, that you can very easily and with almost no code create basic Web CRUD apps. Of course creating quality apps is not completely simplified and these technologies are non-trivial and open a whole new dimension of complexity, but in a good way, mostly.
During my current Spring and Hibernate tenure, I have come to realize that in order to build a DRY system with these technologies you really need to build your own framework on top of these frameworks, this sentiment was echoed to me in a job interview by an architect, who was lamenting that there was a perception within the organization that once you drop in Spring and Hibernate all of your infrastructure work is done, in fact our concordance on this point was one of several reasons why I was offered and accepted the position.
So what does this framework look like? Well in this context I would abstractly define a "framework" as a collection of components and rules. Its intent is to guide the structural s development of a system towards DRY and consistent code and to create and maintain Conceptual Integrity in the system and throughout the development process and to create clean high level interfaces to increase developer productivity. This framework will vary from system to system and it will be driven by project specific technology decisions and design.
The two aspects of this approach are pretty intertwined, so I’ll start with the structural components, which can include a number of possible component categories, some components may be created to fill in deficiencies with the underlying technology components, while most will probably be more vertical convenience components which bridge the gap from application needs to the generalized underlying technology frameworks like Spring. A good example of this is security. Many projects I have worked on have had special security needs that in some cases require extending and overriding existing Spring Security classes. Essentially any code that can be used in multiple places in a system is a candidate for being "pulled down" to the framework layer. Also components that can be commoditized into services can be thought of as part of this approach also. In the Spring and Hibernate world two common framework patterns are the Generic Dao and the model base class.
Ultimately I cannot define what your framework will look like, as mine tends to vary from project to project and generally includes the components mentioned above, as well as other components such as custom property editors, reusable comparators, Dao and Model audit functionality, special JSP tags, etc. Your framework may be quite different, and it might not be in Java, as it might be in another language and framework like Ruby on Rails or Scala/Lift for example. Also you should plan on the framework being an organic evolving entity which grows constantly through refactoring and harvesting, and in this case I would call it "downward refactoring" where common and possibly redundant code is refactored down to the framework layer.
The rules aspect includes, of course, coding standards, but it should also guide developers on their choices covering how to use underlying technologies, and relatively mundane things like how the project is structured, and naming, also this is not a comprehensive list and also may vary over the project event space. An example of rules would be to dictate how specific technologies are used, in Spring and Hibernate there are often multiple ways to write code which performs the same function as well as competing configuration "modes" e.g. annotations vs. XML. One common coding variation in Hibernate systems is the HQL vs Criteria API "debate" many systems I have worked on tend to have a haphazard mix of both, a consistent system will have Dao classes that have specific rules about when to choose the Criteria API over HQL and thus not leave it to the developer’s whim. Rules should also be viewed organic and evolving, especially if the developers are new to technologies. Also the rules should extend to how and when the framework components should be used.
Of course as I was writing this, I came across several reuse skepticism articles including "Reuse Myth - can you afford reusable code?" which was on the Reddit and following the links yielded: "the imperial clothing crisis" and "Hidden Costs Of Code Reuse". At first, my reaction was that all of this was completely antithetical to my arguments; however, in reading them, I realized that they are good sources for refinement of my points.
First I should point out that the framework architecture is hopefully created by the architects and alpha developers, also the alpha developers generally produce higher quality code at least three times faster than average 80%, so conceivably your software creation rate is still at least one to one, based on the argument about reusable code takes three times longer, also I would argue that in general it does in fact take more time to produce higher quality software than to produce lower quality software. Admittedly, most manager types usually don’t want to hear that!
It should be noted that framework code should be constructed in a deliberated and hopefully collaborative way, and that not everything should be made reusable, however, I am of the opinion that, if you use it more than once it is a candidate for reuse refactoring, however, this needs to be tempered by the level of effort to achieve reusability, sometimes cut and paste makes more sense. Also, as the above reuse skepticism articles suggest, don’t go crazy trying to create a bunch of reusable code before you have the need to use it. Another somewhat ironic point is that the framework concept that I am promoting often in part consists of components that reduce the generality of the underlying frameworks narrowing those API’s for more focused integration to define a cleaner interface with the higher level application code.
There is one additional "meta" component that I have used and seen during my career, it is sometimes referred to a sample or template project, the more recent name which I have encountered is bootstrap project. The bootstrap project often both exemplifies and ties the rules and components aspects together. It usually contains the configuration structure and usually sample code to guide how projects should be constructed, and it is often an actual running project which can be deployed to the target development environment.
1 This particular reference is actually restatement of Greenspun's Tenth Rule, which Paul Graham references in his essay, when I first wrote this I remembered it as Paul Graham's, however, upon rediscovering the essay I realized that it was actually a reference, I decided to leave it this way because I think Paul Graham’s essay and body of work is worth reading as is Philip Greenspun’s.
"..., also I would argue that in general it does in fact take more time to produce higher quality software than to produce lower quality software. " Well YES! unless you abandon simple reasoning, it is hard not to acknowledge this! A better quality usually requires a better coverage, which only experienced developer can bring on the table, mediocre and less experience ones will never consider most of the points in the bigger picture/coverage.
ReplyDelete"It should be noted that framework code should be constructed in a deliberated and hopefully collaborative way ... " this is a challenge I face sometimes when introducing a concept (approach) with an accompanying framework of how to do it! First many peers might not even get WHY! ,but the one who get WHY then tend to miss the point HOW! we are doing it! :)
Yet it is paramount for any member of the team to have both KNOW-HOW-and-WHY. What I am practicing at my current workplace is the requirement of peer-review. Not a single work-item can be closed by the same person who worked on it! this serves two purposes code-review and knowledge decimation. Will see how that will work out...