Beyond S.O.L.I.D.  Part-I                Your Path to Build an Evolutionary Architecture
Radar Map: Code Quality Fitness Function

Beyond S.O.L.I.D. Part-I Your Path to Build an Evolutionary Architecture

We have repeatedly seen scenarios where changing code in one place for a functionality starts impacting other functionalities. We all have worked on code that is difficult to read and extend, let alone unit testable. As a Developer/Tech Lead/Architect, we have spent sleepless nights fixing bugs during the testing phase or after going to production.

Implementing S.O.L.I.D. principles and GoF/JEE Design Patterns are stepping-stones to writing good code. However, developing an application requires more than just writing a few classes. The challenge is to compose hundreds of classes and manage dependencies to make our application manageable, extendable, and testable. Implementing different frameworks, tools, protocols, Databases, and external integration brings its own challenges. Every development team goes through this problem in one or the other way!

Questions that one needs to ask; "How do we create different components so that when interacting with each other our components meet the following criteria":

  • Package different classes associated with multiple design patterns, to reduce the impact of changes within the application. (Usability/Reusability/maintainability)
  • Manage dependencies and indirection between different layers, modules, and classes. (Manageability and Code stability)
  • How do I know that my dependencies are in the correct direction and that my application/functionality is stable? (Code Stability/Build/Dependency Management)
  • Create a testable code. (Maintainability/ Developer's efficiency)

Before we start, let me explain the term used in this article.

  • Component: A Collection of classes that can be grouped and deployed together as an independent unit.
  • Second Order Effect: A change in code for one function can have an impact on other functionalities, sometimes difficult to sort out.
  • Architecture Fitness Function: A particular type of objective function that is used to summarize ... how close a given design solution is to achieving the set aims. (Definition borrowed from Building Evolutionary Architecture: Neal Ford)

Let's understand the principles used to build evolutionary architecture. Defining Architecture Fitness Functions help us to objectivize our architecture, measure them effectively, and automate Architecture Governance. This article is divided into three parts. The first two parts will cover the principles to define Architecture Fitness Function and govern our project. The third part will cover the application of these principles, and tools used to automate Architecture Governance.?

Principles of Component Cohesion:

This principle guides how to group classes effectively in a component that can be deployed independently. It consists of 3 principles.

1. The Common Closure Principle (CCP):

Classes impacted by the same kind of changes should be placed together. It is very similar to Single Responsibility Principle from a component perspective. It will help minimize the impact of a change when a requirement changes. Other Components that do not need to change need not be revalidated.

No alt text provided for this image
Application of Common Closure Principle

As shown in the above diagram (Figure-1a), we have packaged classes associated with HTTP (protocol) as part of the core component. Thus the ‘core’ is not reusable if we want to port to a different protocol (unless we change the code and pass related classes to the core layer) as shown in Figure-1b. To make the core package reusable, the core component need not contain protocol-related packages as in Figure 1c.

2. The Common Reuse Principle (CRP):

Classes reused together should be placed in the same component. When a component is reused, all the classes within that component tend to be reused together. Though self-explanatory, the decision needs to be taken as to what constitutes the core component. We will see how the third principle is applied to define the core component.?

3. Release/Reuse Equivalence Principle (REP):

Every component that we declare as reusable must follow a release cycle. This includes but is not limited to tracking features, changes, issues, versioning, etc. Since managing these components incur a cost, these components should be large enough to justify its release management cost.

Considering the cost, and efforts involved in these activities, it is unlikely that you will create many components. (It is better to plan a small number of strategic components that confirms the other two principles that we have discussed earlier.)

While they look simple and easy, these three principles oppose each other. Taking one into consideration impacts the other two. The trick is to find the right balance. Let me explain this with Component Tension Diagram. This is where Architect/Tech Lead makes critical decisions to achieve desired Architecture Fitness Functions.

Let us take an example of an Order Service API. Generally, an order consists of a List of items with their respective quantity and unit price, Promotions/Coupons, Tax Information, Delivery cost, and Shipping and Billing Address. This Order Service would need Tax, Delivery, Discount Calculation, Total Order Cost Calculation, Item cost Calculation, etc. Then we have the Payment service, Address Validation Service without which we can't process the order. The decision that we have to take is "How the code should be packaged to build components? How many components should be built that will conform to our Fitness Functions?"

No alt text provided for this image
Component Tension Diagram

  • Condition 1:?When we apply REP and CRP, leave out CCP: We need to split our scope/requirements into multiple components. A minor change will impact too many components to realize Order Service capability.
  • Condition 2:?When we apply REP and CCP, leave out CRP: Every addition or removal of business rules or changes in the object structure associated with dependent entity changes would warrant a new release, increasing the cost of maintenance and releasing multiple versions of our component.
  • Condition 3:?When we apply CRP and CCP, leave out REP: We won't have any reusable component as it's not being published.

Along with the Principles of Component Cohesion, we also need to understand the Principles of Component Coupling, which deals with the relationship between components. They both need to be applied together to reach goals defined by the Architecture Fitness Function. I will explain the Principles of Component Coupling in part II of the article.

Aarun Awasthi

AWS / Azure architect || Solutions architect || Service delivery || Cyber security expert || Operation support || Team mentoring || End to end delivery || PSM

1 年

Hi Prashant Joshi , thank you for sharing this , I an also working on the same scenarios. Also would like tobk ow how do we fit the microfrontend in this architecture.

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了