Evolutionary design?

Yes, it will be very useful a software design that can evolve (developprogress, make progress, advance, move forward, make headway, maturegrow, open out, unfoldunrollexpandenlargespreadextend).  I do not want to rewrite a lot of code from the scratch from time to time.

The main question is if it is sufficient ?

In fact, I will want a software that could follow the business.

That mean this software could be changed with the business needs changes. These changes could be small or complex, could be rare or often.  Or <even late>.

That mean this software could be changed with reasonable cost, without unnecessary waste.

That mean this software could be changed indefinitely change easy and economically.  The software will not have too much technical debt and the team will be always be prepared and <in shape>.

That mean my software & my process should be Adaptive and Lean.




TDD trick: getting effective & efficient design

How do we design a complex behavior or build a complex solution? Can we imagine everything big up front and then just write the full code?

 No, probably we will do it incrementally.

We will make progress incrementally and directly to the solution?

Well … it is complicated…

Just tell me how it works.

We will have a first idea of the solution, we will make it work, we will do some tests… and then we will continue with the next increments, but … we will often discover that we need to adapt and change the first code.

There is any danger to be stuck or have some other problems?

Yes, there are more sources of problems. First, if it is too complicated, we can be stuck from the beginning and we can have no idea how to start. Second … when we adapt/change the initial code to add the increments, we can break the behavior previously implemented.

What you say is that when we build something, what we really do is build & change? …and for any change we will need regression test?


Build real model: Build & Change & Regression Test. Repeat.

You are using test-first approach and auto-tests?


… that mean, in this scenario (without auto-test), the real test will be rather performed when implementation is “ready”?

Yes…. but the ugly part is that we could have many broken parts, and we need to perform again all the tests. Even worse: what we consider as “implemented” will be a big fragile mess, hard to be stabilized.

That mean that, in fact, you will do a lot of tests, you will re-build and repeat many of the tests, with a lot of extra effort and with rather low quality as result?

Something like that.

Summary –  designing without auto-tests scenario

  • Facing the complexity, we can be stuck from the beginning
  • Design it is incremental anyway: build ~ build & change and repeat
  • With any change, we will break things
  • We will test a lot anyway
  • If we will repeat the test after each increment – that will take a lot
  • If we will postpone regression test until “implementation end”, we will still test a lot and we will get a big, fragile, buggy mess, very hard to stabilize
  • Design improvement is expensive and we will need again the whole spiral of tests
  • It is very likely to still have a mess after ”stabilization” and many hidden bugs

So … auto-test will fix all these problems?

Not necessary, you will need some tricks… as Uncle Bob “Getting unstuck”.

Robert C. Martin, Clean Code videos – Episode 19, Advanced TDD part 1, Chapter “Getting unstuck”: <<…and will write the most degenerate tests cases we can, we will very gradually climb the ladder of complexity on little test case at the time and for every test case it fails, will make it pass by generalize the production code, rather than doing some specific fix just to get the test to pass.>>   

What is happening here:

  • “Getting unstuck”
    • We will not be stuck from the beginning, because we can start with simplest test cases
    • It is less likely to be stuck later, because by extracting one test cases after another, the complexity of the remaining problems will decrease step by step
  • With regression tests available, we are free to adapt and advance to the solution.
  • Regression test is inexpensive and fast
  • Not breaking things when adding more features
  • No big fragile mess at the end

So… that should be enough?

No…. there are also other tricks, such Kent Beck: make it work, make it right, make it fast. You do not want to have a wonderful, fast & clean code and later discover that it is not working.

Summary of the differences  

  • Getting stuck versus Getting Unstuck
  • Throw away the tests with slow re-test versus persistent test with fats re-test
  • Break the previous increments versus keeping them working
  • Fragile big mess versus robust clean code

Manual tests ~ throw away the tests + re-build them for each regression test



Architecture: 2 n-dimensional layers

Original Sin: Unidimensional Asymmetry

Back in the day, I was delighted when I first found this three layers’ architectural pattern:


Finally, some order in the chaos!

 … but, trying to use something like this in practice was somehow difficult: there are other aspects that does not fit to any of these layers.

The next interesting thing that come up to me was “Layered class type architecture” from Scott W. Ambler “Building Object Applications That Work”:  Interface, Process, Domain, Persistence, System.

Now was clear that, unfortunately, something is wrong with the 3-Layers Architectural Model. … and the “original sin” is the unidimensional asymmetry: the UI-Persistence “line” is the unique dimensions and many other software areas cannot fit here.

The fix: Symmetry!

On of the first actionable and symmetrical model was the UML (Jacobson) robustness diagram. Any use cases could be represented as being realized by objects that are instances of three categories of classes boundary, control and entity

  • Boundary, Control, Entity

That is simple, beautiful and symmetric: UI and other I/O (Input/Output) aspects are managed in non- discriminatory manner.  One problem: too few guidance.

Koni Buhrer “Universal Design Patterns” goes a little further – four design elements & their recommended interaction could describe everything and offer a symmetrical model:

  • Data Entities, I/O servers, Transformation Servers, Data Flow Managers

It is symmetric, it is logical, actionable, but still too few guidance.

What we could need more?

Robert C. Martin and with Clean Architecture and Alistair Cockburn with Hexagonal Architecture have some beautiful answers and guidance (see Uncle Bob biblio for other authors similar works).

With Hexagonal Architecture name, Alistair Cockburn want to make clear the main defect of classical model  – unidimensional  lack of symmetry: <Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases. > . This architecture model will decouple use-cases (~ the application) and the I/O dependent on technology: “When the application has something to send out, it sends it out through a port to an adapter, which creates the appropriate signals needed by the receiving technology (human or automated).”  (quotes from mentioned A. Cockburn post)

Robert C. Martin Clean Architecture make a step further on strategically separating the concerns and present these software areas (quotes from Uncle Bob recommended article )

  • Entities – representing the functional part that is application-independent, working at a higher level: domain or enterprise
  • Use cases – representing the functional part that is application-dependent, and realize the flow of data using the business domain and enterprise rules
  • Interface Adapters – “set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web”; on Uncle Bob View MVC and MVP parts goes here
  • Framework and drivers – “frameworks and tools such as the Database, the Web Framework, etc.” And what is most important, according to Uncle Bob, – “This layer is where all the details go. The Web is a detail. The database is a detail.”. Yes, technologies & deployment mode is not the core of your application, it is what will change independently and do you want to decouple them.

I strongly recommend all above described symmetrical models: Robustness Analysis (Jacobson), Universal Design Pattern (Koni Buhrer), Hexagonal Architecture (Alistair Cockburn), Clean Architecture (Robert C. Martin) or Layered Class Typed Architecture (Scott W. Ambler) that are logically equivalent with more or less details.

Simplified representation of symmetrical models:



  • Flow control orchestrate I/O parts (symmetrically) and Business Logic, where Entities are the exchanged data
  • If the Inversion of Control it is used and the participants to the flow are represented by interfaces, the design will be more adaptable and testable

What we could need more?

There is some asymmetry!


There is some asymmetry in logic architectural areas that is skipped somehow by current models of Hexagonal or Clean Architecture, and this is the reason behind the original mistake of unidimensional linear model:

  • There are two kind of interactions for the systems
    • The client level interaction – the one with the systems actors
    • The resources level interaction – the one to access the its resources (such databases, heavy processing)
  • The client level interaction
    • Contain – links the system with its clients/actors
    • Dedicated flow control to manage (possible) client session state (interaction state)
  • The resources level interaction
    • Contain – link the system with its resources
    • Dedicated flow control to manage (rather) stateless access to these resources



  • Each layer is represented in a simplified form here. In fact, it could contains full set of software areas: Entities (Business/Enterprise), Flow Control (Use Case) and I/O adapters.
  • Each layer is symmetrical, but the aggregate is asymmetrical, based on actor-resources vectorization

Scaling aspects (performance and others)

Service Layer

  • can manage the access to resources with the benefits of its stateless model, using various patterns and tools that are based on this aspect.

Interaction Layer

  • can manage in a decoupled way the possible scaling issues of clients’ data cache
  • idem for managing the external interaction aspects


Examples – same services with various forms of interaction

  • Generic Model


  • UI based Module
    • Interaction with the Human User Client is designed with MVP pattern and provide access to system resources via a set of three services, where interaction layer also orchestrates the calls of these (resources access) services


  • “Flat” Flow Background Module
    • The client/actor is an internal timer. When it is invoked a single (resource) access server, the interaction layer flow could be “flat” (just redirect the call)


  • Complex Flow Background Module
    • In a similar case, but when the background run it is similar with one or more actions from UI based module: the interaction flow will keep also the state of the client session between successive services calls


Notes about Microservices

Microservices could be a choice for architecture decisions, but my problem is all the talk about “monolith-application” versus “microservices”. I recommend to read first these Robert Martin articles:

 In the above proposed model, the “service”

  • Has a clear responsibility – manage the access to the system resources
  • Has a rather “plain interface” – the service itself is decoupled from its deployment mode
  • These areas are decoupled: the services, the way how actors interact to the systems to access them, and their deployment mode. Services are reusable for more types of interactions and more type of deployment

How the microservices fit with this model:

  • The service it is in the same micro-monolith (sic!) with its deployment mode
  • The client interaction flow mode is out of scope, but it is forced to access a fixed deployment mode (with afferent technology)

Update (May 15, 2017)

Just find from an Alistair Cockburn tweet (see bellow) that he has updated his “Hexagonal Architecture” with a similar “asymmetry” concept:

<<New note on at . Primary/ secondary actor asymmetry (end of the article) Take look if you like>>

Few comments about the difference between the two similar viewpoints:

  • I still believe that main split is between cell related to “client interaction flow” and the cell related to “resource access service(s) flow”
  • The case when we have primary actors and secondary actors it is just a particular case when the resource access flow could be assimilated to an internal use case and/or with a distinct component
  • In a generic case, there is the possibility that “client interaction flow” to be in the same use case and in the same component as the “resource access service(s) flow”
  • 2 cell architecture is never about <<UI and back-end services decisions>> (see Cockburn post section “Separating Development of UI and Application Logic“): we have in the same time flow control, business and technology in both “front-end”, interaction cell and in “back end” resources access cell
  • UI is not the only way for interaction with system clients: we can have, for example, external request/response interactions or scheduling/timers, listeners etc.
  • 2 cell architecture it is not only about separating adapters and ports, it is about separating also the flows in these two categories: client interaction flow and resource access orchestration flow. The whole application is split in two cells, not only the port and adapters.



“Layered class type architecture” from Scott W. Ambler

Universal Design Pattern – by Koni Buhrer

Hexagonal Architecture – by Alistair Cockburn

Clean Architecture – by Robert C. Martin

Microservices – by Martin Fowler

Refactoring: strategy & collaborative work

Introduction –  The extended definition of Refactoring contains also this part:  “Its heart is a series of small behavior preserving transformations. Each transformation (called a “refactoring”) does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it’s less likely to go wrong. The system is kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.”- Martin Fowler, at refactoring.com.

Note: this imaginary dialog it’s inspired from an intensive and extensive practice.

What if we will have to perform a Big Refactoring? 

Refactoring cannot be big, it is a special kind of redesign, performed in small steps. See the above definition again.

Reformulate: I need to do a lot of refactorings to clean a legacy code.  There is any best practice?    

You need a strategy?


Well, agile and software engineering offer a lot of tactics, including the Martin Fowler refactoring sets but almost no strategy, except … you should work clean from the first time. Use Martin Fowler indications from the start (or early enough), also Uncle Bob Clean Code and Clean Architecture.

Hey! I already have a lot of legacy code debt to solve!

Ok! Let’s build a strategy: how do we start?

This was my question!

Refactoring supposed improving the design, while preserving the functionality. Tests included. Do you have good requirements specifications or a good set of automated tests?

Not in this case.

Then you should recover functionality knowledge from the code and put/perform incrementally some tests. Better: functionality should be explicitly represented in the code and should be testable. And remember: there are two kinds of functionality…


Yes, first, the one that is application-independent and represent the target domain (domain business rules) and the one that is application-depend aka flow of control.

I remember: that sound like Uncle Bob Clean Architecture.

Yes. You will need to be able to apply distinct tests to them, without mix them with other concerns such as UI, persistence, network and others. Anyway, where do I usually start? I will try to make the running scenarios very clear into the code and that mean the flow of control.

In English, please?

I want to clearly see these: were the event triggered by the system actors start and the end-to-end full path until return. More, I want to refactor to make this path clear enough.

How could be not clear? ­­­

Global context. If the functionality path chaotically accesses the global context, then we could have undesired intersections with other paths/scenarios, that will compromise both data and function. In the same time, we can decouple flow/orchestration from specialized concerns.

What we get?

We will have explicit representation of the functionality (with no undesired contacts with other flows), needed for tests (we can apply auto-tests on it). Also we will have the first entry points to the specialized parts that also could be <decorated> with some tests. Then we can apply tactical refactoring as we need.

And …the domain business rules?

Must be decoupled from other concerns and you have to dedicate them specialized design/test elements.

That’s all?

Almost. You need to test any redesign. Tests need knowledge about functionality. If some parts are missing, now it is the time to recover them in auto-tests (preferable) or in other form of specification.

How do I know that recovered requirements are correct?

You don’t. More, you should always suspect that spaghetti-like legacy code include many unobserved bugs. You should validate these functional requirements by intensive collaboration with your colleagues, with domain experts, customer and other stakeholders.

Do you have any idea about how to do that?    

Start with Pair Programming (refactor in pairs). Pairing is not enough, and you will probably need more people involved – use Model Storming: discuss the resulted functionality with more colleagues.

Model Storming?

Yes, it is an agile practice, part of Agile Modeling (and Disciplined Agile) and it was created to complement core practices from XP. Also, you should actively involve your stakeholders in validating the recovered functionality…. Active Stakeholder Participation, that it is another Agile Modeling recommended practices. And at the end you will have more free bonuses.

What bonuses?

Functionality it is easy to accurately read from code (seconds!) and your colleagues and your stakeholders will already have acquired the recovered functional knowledge.

Summary –  Refactoring for significant spaghetti legacy code need tests/testing. Usually, knowledge about functionality necessary for testing it is insufficient, so must be recovered from the code. An effective & proven way to do that is to apply Clean Architecture principles: decuple both domain rules and application specific flow of control (aka use cases). Anyway, legacy code with too much technical debt will contain a lot of bugs, so recovered functionality it is inaccurate and need to be validated.  Knowledge & expertise needed for validation it is distributed among team members, domain experts, customers and other stakeholders, so you need to work in a collaborative manner with all mentioned parts. There are some outstanding software engineering and agile practices that could help on this aspect:

Note: “need” and “necessary” are often use in above text, just because we have followed the logical path of necessary things for testing a redesigned legacy code.

Remember: A lot of technical debt ~ inaccurate functionality. To refactor & test, you must re-start the process & collaborative work from functional requirements acquisition.     

%d bloggers like this: