Software has diverse applications. This book deals with design of software written for enterprise users, public consumers or other similar software. In software jargon this book is about middle-ware and presentation layer of software systems which deal with database & messaging software and interact with other similar software implementations.
I use object oriented programming languages (Java, C# and Ruby) for building these software. My software designs are influenced by the following work. This is not intended to be a complete list but enough to be useful for the reader to set the context for the book.
In my career, mostly at ThoughtWorks, I have worked on large and legacy projects. On these projects I have used the design insights provided by these work. (While these are primary inspirations there are others as well which I would mention as we go on). This book is about implementation of these ideas and what new patterns emerge out of them. I hope that the reader who do similar work as I do would find them useful. I also see my work as that of a curator, bringing ideas that make sense me to the developers like me.
Any software has four class of users consumer, operator, developer and customer. (Customers don't directly use the software but they are interested in the properties of software like cost of change. This book would not directly talk about these aspects of software.) Software should help its user productively achieve their goals. Designing good software means achieving this goal.
The success of the the kind of products I have worked on, is dependent not only on the design quality of application/system but also on that of software quality of test, build, deployment, monitoring code. For brevity I would use production and enabling software for them respectively. Though enabling software doesn't run in production they are immensely valuable nonetheless. So valuable that they also (rightly) influence how we build production software.
Domain driven design brought into focus the importance of understanding the problem domain in order to do a good job of solving it. One part of understanding the domain is coming up with a vocabulary which one can use to communicate with each other. The vocabulary can be backed by a glossary-of-terms defining their meaning and their relationship with each other. This approach is really about representing simple concepts from the domain and defining relationship between them. In other words it creates a useful abstraction of the domain. But I have found that there are other domains as well along with the business problem domain, which we deal with when building software. Understanding what these domains and their boundaries are can be quite useful in winning over complexities in software. As, the similar techniques can be applied to them as well. I have found this process of abstracting the problem via use of terms (names) extremely useful. I would follow this approach quite a lot in the book to not so much to illustrate the approach rather the applicability.
Since abstraction and domain creation is my primary tool I find it natural to structure the book in a way that it deals with high level concepts first and works it ways through to the real programs.
Domain of making software
There are five kinds of software we develop to take an idea to reality. These software are: Business System, Build, Test, Deployment and Operational. Each of these software do have influence over each other.
Operational: Provisioning, Monitoring, Backup and Recovery
Deployment: Installer and Deployer
Test: Unit, Functional and Performance
Build: Build, Continuous Integration
Users, building-blocks, solution-sub-domains (build, test, deployment, application), problem domain, technology,
System Architecture - Services, Modules and Applications
Build, Continuous Integration, Continuous Testing and Automated Deployment
Simplicity and performance are two key characteristics of software important to its users.