Introduction: This issue combines the previous evolutionary architecture with emergent design concepts in an emergency design article with a case study to show how to discover, accumulate, and exploit unexpected design elements in your code. Once you understand how to identify a design element, you can use that knowledge to improve the design of your code. Emergent design allows you to discover those aspects of your code that are unexpected but have become an important part of your code base.
In the first phase of this series, "research architecture and design," I asserted that each of the larger projects included design elements that were beyond everyone's expectation. When you think about a problem in detail, you often find that something that you think is difficult is actually easier, and some things you think are easier are actually more difficult. Subsequent installments illustrate some of the ways to discover hidden and interesting design elements. In this article, I combine those ideas and provide an expanded case study in which tools and methods are used to discover the neglected but equally important parts of the code base.
In "Combining methods and SLAP," I introduced the concept of idiomatic patterns (idiomatic patterns). The idiomatic pattern does not apply to all projects, as compared to the general design pattern (designing Patterns), which is written by the four-person group Patterns. However, they are a common and representative design practice in the code. Idiomatic patterns range from a pure technology model (such as the way a project handles transactions) to a problem domain pattern (such as always checking the customer's credit before processing an order), which can be idiomatic. Discovering these patterns is critical to emergent design.
A supporter of the design methodology of the big designer up Front to start coding, it takes a lot of time to determine all the necessary design elements for the current application. Most of the content in the documentation is still important for the overall design of the solution. However, in the implementation of the software process, will continue to encounter accidents. Each design element of the implementation is interconnected with other design elements to form an extremely complex dependency and relational network. There are some aspects of the code that are supposed to be normal, but when it comes to implementing all the other necessary parts of the system, the complexity is magnified. The inability to understand the complex interactions between the different design elements in the code makes it difficult to estimate the effort required to complete the solution. In software, estimation is still a mysterious "black art", because it is difficult to understand such a complex coupling and interaction network, so it is difficult to analyze.
Agile methodologies, which rely on emergent design, try a different approach. Agile architectures and designs do not shy away from design until code is written, but their real-world workers already know that the whole problem can only be fully understood until an important part is achieved. The development techniques in emergent design allow you to postpone making decisions until you have more context. The Lean software movement has a good concept called last responsible moment: It's not the decision to postpone to the last minute, but the last moment of reliability. The longer you postpone the design decision, the more information you will have, so that you can make more subtle and realistic decisions.
Accumulate idiomatic patterns
Emergent design requires the discovery of design elements in existing code. Those elements can be viewed as valid abstractions with potential for reuse. One technique to accumulate those idiomatic patterns is to use a combination of metrics. To demonstrate this technique, I will use the Apache Struts code base (as in previous installments). The reason I use Struts is not because I think it's flawed (actually the opposite), but because it's more famous and open source. I think every code base includes idiomatic patterns, so you can use any project.
Use indicators
In "emergent design through metrics," I discussed the use of metrics to discover interesting parts of unfamiliar code libraries as a refactoring goal to improve the design. I used two metrics: cyclomatic complexity (cyclomatic complexity) and afferent coupling (afferent coupling). Cyclomatic complexity is a measure of the relative complexity of a method relative to another method. Therefore, this index is only useful compared with other cyclomatic complexity indices. However, it can be said that a method with lower cyclomatic complexity is usually simpler. Incoming coupling indicates the number of times another class refers to the current class through a field or parameter. I use the CJKM metric tool to collect these numbers on the Struts code base.