I have followed the Spring project for sometime now and there are a lot of things I like about the community and its approach, I am particularly inspired by the mission statement and feel I can contribute something of value while also benefiting from utilising Spring. I have been developing a pure on demand application server architecture which has raised some fundamental questions about my approach to software design and development. This post is attempting to articulate the realisations I have gained from understanding the implications of applying the Inversion of Control Pattern in an application server framework.
This is a fairly philosophical post and its purpose is to spark a debate about application development in general, however, this debate should be kept in the Spring context. To achieve this I am suggesting a comparison between Spring and the design I have been working on because there are many similarities but a few key differences, in this respect I am calling on the whole of the Spring community to evaluate their approach. My contribution is therefore two fold, on one hand I can contribute to the articulation of Spring fundamentals and on the other I can implement solutions. Following is a brief of the architecture I am proposing and some statements on how I perceive Spring. These perceptions are the key to the debate and I would like to know if people agree with them or not, or if they generally agree but feel different terms or descriptions would be more appropriate.
The design I am working on extends and refines the request/response model with a request/resolution/response model. The 'on-demand' aspect of the architecture can be summarised as 'the dynamic composition of a resolution from a specified domain declaration in response to a given service request'. This means that the software components necessary to complete the resolution of a request and give a response are provided at runtime and at runtime only, i.e. on-demand. In the composition of a resolution environment I have separated my concerns into six layers, each of these layers isolate a distinct set of problems in relation to the overall problem. The basic premise of the design is that the application server can serve multiple applications for multiple domains. When a client connects to a particular domain it is assigned the necessary resources, does it job and relinquishes the resources.
This is how I have separated my development concerns:
Domains - Deployment specification, in relation to the MVC pattern a domain is responsible for some aspects of the view.
Clients - Used to model a clients movement through possible paths in response to application events in a given domain (its context), a client is reactive (Reactor Pattern). In relation to the MVC pattern a client is responsible for some aspects of the view and some aspects of the controller.
Applications - Provides the abstractions for making a bridge between general concepts and application events/methods, i.e. de-multiplexing environment events to application events. (Proactor Pattern). In relation to the MVC pattern an application is responsible for playing the role of controller and some aspects of the model.
Environments - Provide the abstractions for making a bridge between concepts and technology. i.e. de-multiplexing Machine events to Environment events. (Proactor Pattern) In relation to the MVC pattern a client is responsible for some aspects of the model.
Machines - Isolated runtime access to a range of hardware, this is the intended replacement for Threads. Threads are designed to be general purpose and don't work well if there are large numbers of them, a machine is really a lightweight thread designed for server environments. The implementation I have been working on, depending on the applications running, will use as little a number of threads as is possible, 3 in the best cases, to manage 1000's of machines, these threads perform well considering how much processor time they are given, plus, there is minimal context switching between them a problem that according to the website, plagued the SEDA project), Machines communicate with other Machines using packets therefore Machine to Machine communication is implicitly asynchronous. An application designed to run in a Machine is inherently multi-user but only needs to be designed to handle one user. Machines can be swapped for another in the resolution phase, the intention here is to have different machines for throughputs, i.e. different buffering strategies etc. A Machine is an active object (Active Object Pattern).
Kernel - Server wide management of physical sockets, a very simple and therefore very robust design. The kernel has been designed to always run, applications are isolated from the kernel by the Machine layer so Machines can crash but the kernel will keep running. The kernel is responsible for initiating the composition of a resolution environment for a given request, this allows for configuration changes to be virtually instant and not require a stop/start routine. High levels of concurrent access are achieved through atomic operations and a common exchange point. A common exchange point is a part of the main server cycle where synchronization for all machines occurs, machines don't need to be locked individually in this case because the common exchange point means machines are implicitly locked (or guaranteed to be accessed by a single thread only). This is very much the same approach taken in the MySQL MyISAM tables where it is deduced that it is quicker to lock and unlock a table rather than individual rows, this is actually where I got my idea.
Eventually I want to sit my own custom Structured Development Environment (in the form of an IDE) on top of this.
The above is not so important at this stage, what is important is how it relates to Spring and particular lines in the mission statement:
- It's best to program to interfaces, rather than classes. Spring reduces the complexity cost of using interfaces to zero.
- OO design is more important than any implementation technology, such as J2EE.
The similarity in these statements exposes an underlying concept, this concept is the general principle of abstraction and/or separation of concerns. From the above statements I am asserting that in general software is designed from two perspectives and each perspective poses a distinct set of problems from each other requiring differing approaches to solutions, I now want re-iterate the above and expand on it.
- It's best to program to interfaces, rather than classes.
- OO design is more important than any implementation technology.
My work concurs with the above and has led me to conclude:
- Application code should be devoid of all implementation details.
- Application code should no longer deal with technology directly instead opting to deal with concepts such as persistence.
- Application code should assume a deployment environment that has the necessary concepts available to resolve the applications requirements.
- Applications are declarative in nature.
- Application development requires a top down perspective.
In this respect an application needs a complimentary environment which is simply the bridge between implementation technology and design concepts.
- Generally the host environment should resolve application requirements if it can or handle the situation intelligently if it can't.
- Host environments are algorithmic in nature (deal with runtime casing).
- Host environments require a bottom up perspective.
These two perspectives are combined with a deployment specification which collectively make an individual installation. An application development phase from inception to installation inevitably has a beginning and end, implying a process. This process is usually handled by adopting a 'Development Approach' and using a 'Structured Development Environment' to produce (or reuse) 'Supporting Implementation Technologies' for running the application. The top down and bottom up perspectives are directly related to the Inversion of Control Pattern.
It says on the about page that 'Spring is a layered Java/J2EE application framework' but from these conclusions my perception of Spring is that it is more than just that, I can summarize it as:
I believe the Spring Community is fostering a Structured Development Environment.
- A Structured Development Environment combines a Common Development Approach with Supporting Implementation Technologies.
- A Common Development Approach is a 'top down' design perspective and is synonymous with Spring Community Development Practices.
- The Supporting Implementation Technologies have a 'bottom up' design perspective and are synonymous with the Spring Framework code base.
The previous summary is what is most important here because I am calling upon the Spring Community to define 'exactly' what Spring is. I believe Spring is moving in this direction, would people agree?