a good design? How do you distinguish a good design from one that is not. The answer is effective separation of concerns. Separation of concerns (SoC) is about organizing the product (especially the software part) into modules that have as little overlap as possible. SoC is the motivation for structured programming, object-oriented programming/development, aspect oriented programming/development, analysis and design patterns, architecture patterns and so on.
Achieving effective separation of concerns is not easy. In general, the first release of a product is usually undertaken by a group of fairly knowledgeable persons. They have layers, tiers, components and interfaces. The product size is still relatively small. They have an architecture description and in general the team knows the internals of the product. So, far so good. But over several releases, team members get replaced, and code is stuffed into the initial existing code and the complexity (such as McCabe complexity, lines of code per method/function/file) explodes and becomes obscure. This is no good. The initial attempt towards effective separation of concerns, which I call the primary architecture, is insufficient for later releases. There needs to be a secondary architecture to deal with extensions and plug-ins to keep the core of the product intact.
Evolving a product over releases is about dealing with changes. There are different kinds of changes:
- Modification of Existing Feature/Component . This first case is easy. You identify the impacted components and modify the codes there. This is what most developers do. There are no new components to be added. The primary architecture which the team knows provides sufficient guidance on how to do this.
- New Feature/Component . This is slightly more complicated. Nevertheless, the required change is in a new component and so it does not impact the existing code much. But you have to be careful how you organize the components. For example, you might have 5 components in a layer, but over a period of time, 5 becomes 50. You will most likely need to create packages to organize the components and to achieve reuse between them effectively. The primary architecture needs to be updated to reflect the new organization of components.
- Extension of Existing Feature/Component . This third case is tricky as it deals with cross-cutting concerns. This is where a feature needs to be executed in a component whose scope cannot include that feature. This requires some kind of extensibility mechanism in place. It can be a framework, or a design pattern, or an aspect composition mechanism, and so on. I use the term secondary architecture to highlight the need to pay close attention to such cross-cutting effects.
Yet, even trickier is to know the difference between the three kinds of changes above. Effective separation of concerns can be abstract, but please persevere on. Once you get the hang of it, it becomes relatively simple.
Separating these three kinds of changes should be applied not just to requirements, but also to design and test. This is what is termed as “Use Case Modularity – preserving the separation of concerns from requirements to code and test, Extensions and extension points apply not just to use cases, but also test cases as well.
6. Mindset: Stay Close To Your Real Users
The key motivation of user stories is to help the development team put themselves in the shoes of the real users and to describe usage scenarios that are of value to the users. The same motivation applies for use case specifications, but use case specifications have embedded in it the constructs to achieve effective separation of concerns right at requirements and analysis time through