Your Architecture Sucks and I Don’t Care ignited a bit of a flame war as such topics usually do. On one hand I can see the benefits of good architecture, but on the other, this must be weighed against the real goal of software which is to either generate revenue or perform some necessary task. Universally, having something ugly that works sooner is better.
However, architecture also has a great deal of long term value, and that value increases with the size of the project Good architecture becomes necessary to expand, fix, and maintain the application as well as make it easier for newer developers to understand the working code. While every project should strive for the best architecture, initially, it should not be the most important thing.
The best way to strike a balance between the two is to design it initially so that it is good enough to work with. Your code should be written such that it is easy to refactor at a later date so you can easily retrofit the architectural improvements. Think of it as an agile architecture which starts out rough and can slowly be refined over time as the developers get more of an idea of what the architecture needs. The key factor is to not worry about writing perfect code, just write code that can easily be refactored.
Don’t Repeat Yourself (DRY)
Repeated code means that if you change it once, you have to change it a lot of places. DRY means you use constant values and methods instead of re-iterating the code each time. Once you have those methods in place you can move them around if you want to change the architecture or re-write them if you are not happy with them for other reasons. This also produces code that has shorter methods since you end up using function calls more instead of verbatim code everywhere. Consider DRY the foundation on which refactoring is built.
Rough out the layers
Chances are that while you aren’t going to know specifically what beans each layer needs, you will have an idea of what layers you will need and you should write your code accordingly. By spacing out your code you will give it room to move and breathe.
If you’ve ever moved house, when everything is unloaded off the truck, you don’t put it all in one room and then try and pull out different items and move it to its final location. Instead, you put items approximately where they are supposed to go so you can easily move items around without having to disturb everything else around it. The same applies to code, write it in the layer where you expect it will stay and give it room to move. When you do move it, it will be easier since you have to change less code to relocate it.
Typically, you will have classes that belong in the view layer to interact with the view components and deal with things like form postbacks and parameters. This might take the form of Spring MVC Controllers, JSF backing beans or a Wicket Page. You will have a business layer that the view layers use to get things done that handle the business rules and trigger changes to the database or sending emails etc. Lastly, there is the data layer which the business layer uses to access and modify external data. This layer could be optional as it could be part of the business layer but long term, probably shouldn’t. Often the business layer controls transactions and could make multiple calls to the data layer in the same transaction. Using this basic template, you give your code enough space to enable you to move it around later on.
With the DRY principle, if you put functionality in methods you can choose to relocate the code to a new layer and call the code in the new layer from the old method. Eventually, you can remove the old bean method and call the layer directly from the bean methods. Layers also help enforce the DRY principle since certain functions will belong to certain layers requiring you to create reusable methods. IDEs help a lot with this since if you move or relocate a method, it will complain about it.
Layers promote testability of applications and when you change different parts of the layers in the refactoring process your unit tests will tell you if you broke something as you go along. For certain types of code, one of the equally important parts of unit tests is the ability to perform regression tests to see if you broke something. It is a sure fire way to test that your new change works with the entire code base.
When you start a project , there are plenty of tough questions that depend on the application you are writing, but by layering your code and ensuring that functionality takes place only in well defined points which you can alter or relocate, you ensure that your code remains able to change based on architectural decisions and business demands.