I am doing some work at the moment summarising an architecture that I have developed over the last 6 months. The hard part was thinking about where to start. In thinking about it I realised there were some priniciples that informed all of the architectural choices that had been made. The team I am with agree with these. But I can see that others may strenuously disagree with some of them.
Open Standards over Proprietary Products
There are two competing ideas in the software industry.
One is that a single vendor can satisfy all current and future requirements. For the past 60 years this has first meant IBM and later meant Microsoft. In this approach you embrace proprietary everything on the assumption that you will only ever work with that vendor’s products. Examples of this approach are EBCDIC (a proprietary ASCII), NetBeui, IPX, RTF, DOS, .NET and Oracle.
The other idea is Open Standards. This is where you assume there will be multiple vendors. Getting everything to work requires standards open to each vendor to implement. Examples of this latter approach are TCP/IP networking, Unicode, the Internet, World Wide Web, Linux, Web Services, SQL2003 and J2EE.
Many of our customers want choice. Most of them will in the end want to use our software with leading prorietary products. We need to offer first class integration with those. But we can also service customers that want to pursue Linux and other open standards. There primary motivation is to achieve commodity pricing of technologies that have become commodities.
Integration in many cases is easy because almost all modern proprietary products implement large numbers of open standards themselves. Examples are Oracle (SQL2003), Web Services (.NET), TCP/IP (Windows 95 onwards).
Open standards can be used in by using proprietary products in standards-based ways or by using commodity priced products such as open source/cheapware such as JBoss, JRun and PostGIS.
Acquire components rather than build them
In examining the software we have built, over 98% of our runtime code is acquired rather than written in-house. When we add Eclipse and JBoss to the mix, together with tools our code drops to a fraction of a percent.
This is a healthy thing. Application development is about gluing infrastructure and plumbing together and only writing what represents the true IP of an organisation. Both initial costs and maintenance costs are kept down.
Use Open Source/Freeware/Cheapware for Commoditised components
There are three forms of commodity priced software components: Open Source , Freeware and Cheapware .
There are 16,630 Java projects (Nov 2005) on http://sourceforge.net, the most available for any language.
Some examples of commoditised components used in our project are:
* BeanShell – dynamic scripting using Java syntax
* jBPM – Java Business Process Management
* Hibernate – An object relational mapping library
* geotools – Geospatial Tools
* JBoss – embedded application server
* Java – free programming language and runtime environment
* Linux – a Unix like operating system, and one of two supported operating systems
Cross Platform by Default
Consistent with other principles everything we build is cross-platform by default. To avoid costly integration problems, some developers develop on Linux and we continuously integrate on Linux. It is easier to work on the server on Linux if the client also runs on Linux.
There is a very low cost (a few days so far) to support Linux in our process.
Go with Mainstream Approaches by Default
There are always many ways of solving a problem. We go with a mainstream solution until or unless an alternative can be justified. Some of these mainstream approaches are:
1. The full J2EE as the underlying platform
2. Stateless Session EJBs for the service layer, exposed as RMI Remote classes, Web Services Endpoints, local services for the web applications
3. Security based on J2EE Declarative Security
4. JSPs as the default web view
5. RMI for remoting to EJBs
6. JMS for parallel execution on the server
7. Eclipse application clients
Detailed upfront design usually fails because:
1. there is insufficient understanding of the problem and the technologies upfront
2. changes occur that invalidate the design
In Agile, you do architecture and design just in time. What do you do about varying skill levels and keeping the architecture consistent? You create the the first-ofs on a just in time basis which then allows other groups to copy these as templates.
Another aspect is that implementations change as more requirements are implemented. Care must be taken to avoid fragilities in the architecture for this to succeed. In practice this means monitoring and correcting technical debt through continous refactoring.
Complexity must pay for itself.
Simplicity is subjective. The following is a list of things which can be considered simple:
* 10 lines of code versus 100 lines of code
* code that is expressed in terms of a well-known pattern rather code that does not follow a pattern
* Use of a library or framework understood by the majority of the developers, compared with one that is not
* Documented code and libraries compared with those that are not.
* Reuse of code compared with single use.
Pure Java by default
Being pure Java supports simplicity, cross-platform operation and an Agile approach. Callouts to other languages should be carefully managed.