“A complex system that works is invariably found to have evolved from a simple system that worked…A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.” — John Gall in Systemantics: How Systems Really Work and How They Fail
Software is complex, so the point is, how do you organize your system at a high level to be flexible, loosely coupled, and yet highly cohesive? we need to document simple mechanisms that work. Here are certain points to ponder while considering an undertaking like software development on a larger scale –
- Define a well known software process and then stick to it
- Provide a common vocabulary and taxonomy for developers and architects.
- Enable solutions to be described concisely as combinations of patterns.
- Enable reuse of architecture, design, and implementation decisions.
Selection of the software process is one of the foremost and visionary step in the software engineering and has to be applied wisely and diligently, as its effects may last in the whole software development life cycle and the success of any software is highly dependent on it. During my professional career I have noticed many times that we know some process, say Test driven (TDD) or Agile, is great but we don't know when it is feasible. I am using Model Driven Development and Agile Development for a long time and applied them where needed. I suggest that we should always have some comparative study before adapting any methodology. Here is my take on this broad subject –
Before even go into the details of our subject topic, I'll discuss a little bit about SDLC, Software Engineering and Object Oriented Software Development / Engineering. Software development life cycle (SDLC, SDLC2), also known as “Macro Process” has four phases, the Inception, elaboration, construction and transition / delivery and if we take the iterative and incremental behavior of the software process the picture of it presented by Grady Booch in his finest book on object oriented design.
[ Courtesy: Book “Object-Oriented Analysis and Design with Applications (Third Edition)” ]
SDLC requires a vision and shall be divided into different phases logically and carefully. These SDLC phases broadly include the followings –
Here is an abstract view of the software development life cycle (SDLC) –
[ SDLC (Macro Process), Simplified View ]
Proper Software engineering then is applied by putting a well known software process in place, that actually imposes certain rules to accomplish various software development tasks economically and in time. In other words, software project management enforces well known software engineering principles. Now, what we deal in software engineering are requirements, analyze those requirements, detailing different scenarios along with use cases, documenting them, defining proper procedures for design and development of the software, defining testing / QA related issues, software configuration and change management planning etc. And most importantly, software engineering enforces a proper software process or a combination of processes (hybrid process) where needed. The process we are considering here in our discussion is either, it utilizes DDD (design first) or TDD (implementation first) and both will be discussed in the object oriented paradigm. In the Object Oriented Software Development or Object Oriented Paradigm, when we are analyzing a problem domain or analyzing requirements, actually we are looking for objects / abstractions that will solve some particular problem in the software. First cut objects / abstractions are mare names/nouns and for behavior we look for verbs / actions. Now, how we fill the gaps of how our abstraction will look like, we go deeper in analyzing the requirements, and come up with some handful of use cases, those actually give us an idea of functional aspects of the objects or give us behavioral aspect of them or provides us interfaces, called object contracts. So the outcome of the use cases are the interfaces, providing us the means of testing the contracts. This practice along with sequence / scenarios leads us to find interactions between objects – where are we heading??? we are into the designing of the solution, I mean we are creating a static design which tells us how the interfaces and then the concrete implementations would look like and what are the interdependencies among those objects. When you look deeper into the model the software patterns would evolve and you will replace some of the interactions with the well known design patterns. Here are the tasks that we accomplished during this phase of Model Driven Approach and all of these tasks are Iterative and Incremental by nature –
- Analyzing requirements
- Elaborate requirements - Use case scenarios
- Building prototype
- Finding Objects responsible for a particular job.
- Finding relationships among them.
- Finding design patterns needed.
- Elaborate Objects while designing them, and find functionality for them
If you now look at the bigger picture, you don’t see any need of another process like Test Driven / Agile process, am I right? But hello we are not done yet… With the model in hand, you actually categorize them, that leads to components and then the categorization of components leads you to Domains. So it was bottom up, right, we found the objects, then the components and then the domains... During this categorization process, at some point we realize that some of the areas are new to us. We call them “GREY” areas. We come across these grey areas right in the beginning of the objects / components discovery and we might have no idea how they will look like and during componentization and object discovery process, we’ll realize that we might have incomplete picture of the design and it will become much more obvious when we discover the rest of the domains. In the end we mostly have “Green” and some “Grey” Domains; let’s stop here for a while, take a deep breath, we’ll see how to deal with this situation. By Grey we mean no or very little knowledge of the domain or component or object. When you reach at this point then, Test Driven Development (TDD) Approach becomes feasible for those Grey areas. TDD also known as Agile process or RAD process is both Iterative and Incremental, I call them recursive in nature as the solution is unknown. You only enforce this process when you don’t have enough knowledge or sufficient details about the domain/component/object in hand. In order to get acquaintance about the component, you take baby steps while climbing up the tree, finding more abstractions and their relationships and gain the knowledge of Grey areas or unknowns... Its a bottom up approach too, but this time bottom up for demystifying objects and there relationships and the design then will evolve with time and the Grey areas will eventually become green and you have a better picture in front of you. When you reach at this point, that’s the time to update the Model and back on track with the Model Driven approach. This is really fantastic and you’ll start loving it
[ MDD vs. TDD ]
If you look at the whole scenario that I presented so far, you’ll see that most of the time you will be working in the known or green areas, and so the DDD is feasible to that point and TDD will only be feasible once you have grey areas. So no one process can strictly be followed in a real world. The best approach is, you start with Model Driven Development and that’s how the real world systems are made, that is you develop blueprint / prototype / model of the system first and then go for the development of it. During this development if you find something unknown, give it to the RND team to research on it, and come up with a solution for it until then you don’t stop the development and you move on with the rest. The RND in case of software activity shall take the TDD approach, and you may not be able to estimate the time of completion as TDD is an RND activity and RND projects usually have no time limits or the time of completion is unknown. Remember the software workflow will change altogether, as in TDD you write the test first, while in the DDD you model the design first and then test it later. This is an important factor to remember as they are complete inverse of each other (DDD==MDD==TDD) . Now, when you are involved in the RND of certain problem domain, you need a greater user experience, because its relatively a new area for you as well as new for others, so getting input of the consumers / actual users makes lot of sense, in that case you come up with user-stories, their roles etc… and then those user stories be further broken down into use-cases and that will help you a lot in defining new interfaces for testing of the new components under development or under test.
That's all folks for now, more on these may be some time later, feeling sleepy, its 2am yaar, cheers
If you enjoyed reading this blog, leave your valuable feedback
and consider subscribing to the RSS feed
. You can also subscribe to it by email
. Also, you can follow me on Twitter
. Thank you!