Showing posts with label Real Options. Show all posts
Showing posts with label Real Options. Show all posts

Saturday, 22 March 2014

Growing applications handled by micro services approach

Let's have a look on characteristics of systems we are building. In general, clients spend only about 10% of their money on building application. The rest 90% of their money is the cost of ownership. Our systems are getting less maintainable. They grow in size and from time to time we are witnesses of IT failures, like 'the biggest IT failure ever seen'. Also, for some reason, there is a tendency to rewrite the entire application every 2 to 5 years.

Above observations and concerns are leading us to one of the great bugaboos of software applications over the years, which is their size. The problem is that we simply tend to build too big systems! Although above statements seem to be quite obvious, we still do same mistakes all over again. 


Let's think for a while and ask ourselves a question: what we do, when a given class is doing too many things? We simply go and refactor it, so that it sticks to SRP principle. Second question: what we do when our system is doing too much? Basically, we keep adding new features. It is extremely counter intuitive, but that is what we do. In fact, I am not even surprised, as the most common way of teaching TDD is to apply it together with SOLID principles on a unit level. Of course it is true, but it might be extended to all levels of abstraction. However, having a tangled application, it is our duty to apply SRP principle on a system level. Such an approach may lead us, but is not limited, to micro services architecture.


Micro services characteristics

There is no official definition of micro services, but they do have their own, specific characteristics. Micro services might be treated as a result of applying refactoring, with an SRP principle in mind, on a system level. They enable easier testing and re-usage of services. Also, you may treat them as fine-grained SOA approach. Moreover, micro services create real options, as you may adapt different (right) tools for different jobs (Unix system analogy). Exploiting micro services style we are getting independent deployment and scale, easier test and a change (side effect of small systems!) and very important option - flexibility.

Architect and his job

Let's step back for a second and describe what an architect does? An architect is a person who is the 'chief builder' of a system. His role is to satisfy clients' needs. In addition, he should do 'just enough architecture and design upfront'. 

In terms of architect's work, it might be compared to city planning. All major requirements have to be envisaged in the plan and embraced accordingly. For instance, there has to be a place for industrial and housing zones, possibly some sub-zones for light and heavy industry, too. I am sure, people would also appreciate nice city centre with greenery and leisure bits. On the flip side, it would not be a good idea to build a playground for children in the middle of industrial zone, instead of housing area. What is more, such a city should have shared utilities like: electricity, waterworks and gas pipelines. 



All these decisions and many others must be done upfront. However, they cannot restrain or impose too tight constraints on zones themselves. That is why, an architect should do 'just enough design upfront'.

Getting maximum flexibility with upfront design
'Just enough' is in fact very fuzzy quantifier of 'upfront design', so in real life we need more concrete guidelines. We should be starting from asking a question, how we can provide just enough upfront design in order to provide flexibility in our architecture? 

Having city planning example in mind, it may lead us to a conclusion that such a high level plan is actually something what business people call a capability map. In simple terms, it is a diagram, which maps business needs and requirements into a set of services talking to each other, where services might be zones and interfaces between services might be utilities, in our city planning example.

In order to get a flexible design, apparently contradictory, but in fact complementary concepts are used i.e. evolutionary architecture and emergent design.


In a nutshell, evolutionary architecture is 'all the stuff that is hard to change later' ;) - usually these are interfaces and contracts between components/systems. That is why one of the core rules of evolutionary architecture suggests to defer decisions as late as possible (aka keep your options open).
On the other hand, there is a concept of emergent design. It is an idea of deriving a system design in the continuous process of adding incremental changes.
Here comes another, tricky question, how we should use these techniques? Luckily, the rule itself is fairly simple. We apply emergent design on a level of bounded contexts/services (zones) and evolutionary architecture on a level of gaps between bounded contexts i.e. interfaces.

Hexagonal architecture

Also, while designing the general architecture and communication between components/services, it is very important not to obstruct the natural, creative flow of the thoughts by distorted diagrams.



We should be using right tools from the very beginning - hexagonal architecture approach is one of them. It gives us extremely clear view on what should happen in the core of a given application and how that application should communicate with external systems. Apart from that hexagonal architecture introduces more generic concept of looking at a system. In contrary to common approach, we are able to freely express more than two integration points in our model (i.e. UI and DB integrations). 



Incidentally, if you were imaging a system that is described in terms of hexagonal architecture and sticking to SRP principle, instantly you would get a handy tool for depicting micro services and making SRP fully visible on a system level! Apart from that such a micro service also conforms to Bovine's conjecture: "objects should be no bigger than one's head", which in our case applies to the system.


Integration

Assuming we have micro services in place, we can start introducing well-defined interfaces (contracts) between them. It will give us a power of communication with external world e.g. micro services.

There are two, very important attributes of decent software:
  • high cohesion
  • loose coupling
High cohesion relates to a service. Basically it means service should have a single reason to change - that is where SRP comes from. In terms of loose coupling, it might be treated as description of components dependencies to other components. In this case it should be as loose, as possible.

Over the years, in software design we went through many integration patterns and anti-patterns, as well. It would be worth going through majority of them and pointing out theirs characteristics.

Data oriented integration (dependency on DB level):
  • no loose coupling
  • hard to reason about
  • brittle approach
  • difficult to maintain and change

Procedure oriented integration (RCP, CORBA, WSDL-binding, JAXB, Java Serialization):
  • method calls across boundaries
  • sharing serialized object (tight dependency)
  • adding methods with different input parameters doing similar things
  • above leads to 'God classes' syndrome 
  • above leads to very difficult change
  • above leads to 'objects explosion'
  • above leads to SRP and interface segregation principle (ISP) violation

Document oriented integration (JMS, messaging in general):
  • asynchronous (decoupled)
  • allows additive changes without breaking existing clients
  • adding a field in document without break
  • renaming a field in document, by adding new field - no breaks
  • requires middleware

Resource oriented integration (REST, not HTTP):
  • language agnostic 
  • expose state
  • noun oriented, not verb oriented like HTTP

When we talk about integration, it would be hard to forget about Postel's law: "Be liberal in what you do, conservative in what you expect". It might be translated into slightly more practical hint: "only bind to what you need, to reduce breaking service consumption".

As we see, there are many integration styles. However, RESTful approach looks like the most promising one. It is a fairly light concept, providing desired components' properties like loose coupling and it does not repeat errors from the past.

Summary
I believe I have outlined main issues in software design, prodding us to better understanding of the nature of the problem and finding out some better solutions. Searching for a right design is a continuous process and starts from the very beginning. Collecting and defining clients' requirements, the time architects spend on thinking about all use cases and satisfying client defined criteria, developers correctly modelling and implementing ideas can never be neglected. All these actions are crucial in the process of building anti-fragile and well-designed software.

Saturday, 7 September 2013

Real options come into being in real life

About two weeks ago, I came back from my holidays, where I, my brother and our friend spent time wandering in the mountains. We love hiking and we have many friends sharing our passion. Having such a hobby, it is almost obvious that there would be a constant, informal competition between all of us. When we meet with our friends, we often spend time discussing different tracks, unexplored routes and places, transition times between places etc.

We know that three of us create quite strong and reliable team, where everybody can count on each other in difficult situation. We have proven that plenty of times and we know, what we can expect from each other. That is why we decided to break out our friends' records. We were aspiring to establish three records in terms of: longest track, longest time spent in the mountains walking and the biggest total elevation crossed during entire trip.
We chose a track and prepared gear to go out, in the evening. We got up at midnight and went out. At 6 am, we were sitting at the highest peak on our route, delighting in the sunrise, at the crack of dawn. We took vast amount of photos, made a GoPro movie and went further chasing our records. Nothing was bidding fair our breakdown. 

We started to feel lack of physical power and motivation at about 16th hour of our wandering. All of us knew that feeling. We were trying not to talk about it, as it might have depressed others even more quickly. However, the truth was that we ate all our food, snacks, sweets, fruit and recovery gels. We also drunk entire water, isotonic drinks and tea we had with us. Each of us was motivating others to walk, being on a last legs same time. We were extremely suffering from lack of mental and physical power.

The interesting thing is that when you are fed up with everything and you hate your decision about breaking records, you miss your bed and glass of water, then you can transform that internal anger and find some more mental strength. It was helping us with keeping on pushing forward. 

Having one hour left to our stop, a shelter, we met very tall guy, standing on tracks cross and checking something in a map. He asked us how long would it take to go down following track he was pointing to.
We had just looked on each other, silently agreeing that the tall guy was completely lost in the mountains. However, he was talking so fast, and was so convinced that he is in a totally different location that we gave up. We did not have enough energy to argue with him. We waited, when he finished and told him: "You are in wrong valley, mate. You have about four hours to get to the place you would like to be and additional one and a half to come down". We were persuading him that the only choice he had was to follow the route we would be going down. The tall guy told us that he could have done that path in about three hours, as he is training ultra marathon running. We said okay, you might be right, however bear in mind that sunset would be in top thirty minutes, you have no food and water in a just one third of your camel bag and that is not all. The most dangerous thing was a bear, which was living in the neighborhood and approaching tracks from time to time. The tall guy admitted it was pointless to go to the location he wanted to be and bearing in mind sunset, lack of food and unwanted hand shake with bear, he decided to take our piece of advice. He decided to run down along route we pointed to him.

Before he left, we gave him an option of coming down with us through the forest, as we know that track very well and we had head lights. Also, we said that we had to stay for twenty minutes in hostel to buy some water and at least one Snickers per person.

Initially, he was reluctant and decided to run down himself. However, when we reached the hostel he was waiting for us with his mind changed.
He found our option useful and decided to exercise it. All of us went down chatting and laughing. At the end, he offered us a lift home, which we took as a miracle, as we were extremely exhausted.

It was the other day, when I realized that we had offered the tall guy a real option. It was having all option's properties like: 

  • value
  • expiry date
  • event transforming an option to a commitment

Option's value is not that easy to estimate. But, when you spare a while, thinking about it, you would probably come to the conclusion that you do not need to know its exact value. Humans are good in comparing and prioritizing, but they tend not to give correct absolute values. Thus, comparing is very good technique of evaluation options. It was obvious that the only other choice the tall guy had was to spend a night in the mountains, hugging with the bear (if lucky enough). So, basic comparison of two options gave him a fairly good understanding of his priorities. He had chosen to go down safely.

Expiry date was actually determined by the last point he knew for sure we would be heading to - the hostel.

Transformation moment was a moment, when option stopped being something, which may happen in the future and became a commitment of following three, exhausted guys. He knew perfectly well, why he would exercised that option. It was better for the tall guy to go with us, instead of spending a night in the mountains.

The conclusion is simple: real options are everywhere. They surround us. The only thing we need to do is to start thinking about them and seeing them. 
The most important lesson learnt for me is fact that even in very difficult situation, in unfavorable conditions and being on a last legs, one can still come up with a real option, which might be exercised.