I’m going to propose a new design concept with an admittedly awkward name called the “Put Code Where You’d Expect to Find It” Principle. It means exactly what it sounds like. A team should strive to consistently put different types of code into separate, logical places in the structure. Following this principle, I’m going to put security related code in a namespace with “Security” or “Authorization” or “Authentication” in its name. Data access code is going in “Data” or “Persistence” namespaces. Business logic is going to be placed in the appropriate Domain Model class, or an accurately named Use Case Controller (if you swing that way) or Service Layer class. The point being, assuming a modicum of familiarity with a system, that you should be able to consistently and quickly find any piece of code by its functionality. Think of this principle as creating a Dewey Decimal system for your code.
Part of the “…Where You Expect to Find It” principle is to simply create and enforce some consistency within your system. On several of my Agile projects I’ve noticed “this is how we’re going to do it” moments when the team settles on a pattern to follow, then follows it. “We’re going to do data access with a repository class for each parent domain class object” or “I like this pattern, let’s use it for all web pages” or “let’s suffix all of our Gateway classes with Gateway” are all examples. When these patterns are defined and applied consistently, it becomes easier to find the code you’re looking for. Defining, and refining, these patterns of a system seems to lead to big jumps in developer throughput and increases a team’s ability to exercise collective code ownership.
I think the main reason to be excited about Ruby on Rails (RoR) and its ilk is improved software maintainability through Opinionated Software. RoR forces web developers into a bit of a straight jacket, but that’s a good thing in a way. RoR enforces a consistent source code tree layout; a consistent division of responsibilities between model, view, and controller classes; and consistency in naming conventions for just about everything. While some of the design choices or limitations of RoR may be debatable, the advantages for maintainability are undeniable. Any experienced RoR developer is going to be able to quickly understand the patterns of a new RoR application because the “this is the way we do it” decisions have been made as a community and baked into the framework itself. RoR puts code where you’d expect to find it. My colleague also suggested Jakarta Commons as another example of consistency. I’m still a little dubious about some of the details, but I’m starting to get much more interested in Software Factories as well for the consistency that they create.
Moving to a negative example, last year my team was extending our legacy web application and needed to find the code that governed the navigation bar at the top of each page. We finally found the code smack dab in the middle of a huge code file called “Security.asp” in the “_ScriptLibrary” system folder created by the old Visual Interdev tool. To make matters worse, we found three different versions of “Security.asp” scattered through the code tree. At this point we expect to find everything and the kitchen sink in the “Security.asp” file, but it was a terrible place to dump the navigation code. One, the name “Security.asp” doesn’t imply navigation logic, and two, a system folder is an unusual place for custom code. The application could be improved by simply moving the navigation subroutines into a separate “NavigationLibrary.asp” script in a logical folder. Then the people who come behind us will be able to find the navigation logic when we’re gone.
The newer Integrated Development Environment tools help quite a bit with this. I wouldn’t want to live without ReSharper’s CTRL-N shortcut to find any class in the solution (with wild cards too!). Then again, finding code with ReSharper will be a whole lot easier if you employ good naming practices and put code where you would expect to find it.