Monday, 10 December 2012

Code Retreat in ThoughtWorks 2012

This time I was in taking a part in Code Retreat organized by London branch of ThoughtWorks and it was awesome !!



I decided to spent half of a day writing code in languages other than Java. I have chosen Groovy, Ruby and C#. I have to say that all sessions went very well. 
Okay, so let me describe them briefly: 

#session 1: Groovy with no constraints - just a warm up in a language similar to Java.


#session 2: Java and baby steps - this one was very good. The quite nice and neat design was emerging from the code driven by our tests.


#session 3: Ruby and no more than 4 lines of code per method - actually 4 lines of code per method wasn't hard to achieve in Ruby. To be fairly honest, the longest method we had, had literally 2 lines. What's more, Ruby guy, I was pairing with, has shown me some magic in Vim. I thought I knew Vim quite good, however it appeared I am a barely novice :P


#session 4: Java and immutable objects - this was actually quite interesting one, as well. Immutable objects were affecting our design in a way we did not expect, at the very beginning. 


#session 5: Java and no primitives - again another interesting design emerged.


#session 6: C# and tell don't ask (our choice) - that was actually quite a challenge to use only procedures.


All in all, it was very educational, eyes opening and enlightening day. Although there were couple of tricks I learned, I think the most valuable one is related to the way of coping & pasting code. If you really need to do it, do it as below:

- copy & paste the code
- use question marks to denote parts of code you have to amend
- replace question marks with valid code starting from the top

Just to make things clear, let's have a look on a below example:


"Any live cell with fewer than two live neighbours dies, as if caused by under-population."

@Test
public void liveCellWithFewerThanTwoLiveNeighboursDies() {
	int oneNeighbour = 1;
	Cell liveCell = new Cell(ALIVE, oneNeighbour);

	liveCell.tick();

	assertThat(liveCell.getState(), is(equalTo(DEAD)));
}

And here you decided to copy above test in order to tweak it slightly, so that you can get another valid test.

"Any live cell with more than three live neighbours dies, as if by overcrowding."
@Test
public void liveCellWith???NeighboursDies() {
	int ???Neighbour??? = ???;
	Cell liveCell = new Cell(ALIVE, ???Neighbour???);

	liveCell.tick();

	assertThat(liveCell.getState(), is(equalTo(DEAD)));
}

And here is the result:

@Test
public void liveCellWithMoreThanThreeLiveNeighboursDies() {
	int fiveNeighbours = 5;
	Cell liveCell = new Cell(ALIVE, fiveNeighbours);

	liveCell.tick();

	assertThat(liveCell.getState(), is(equalTo(DEAD)));
}

As simple as that, but helps you to avoid silly errors.

Saturday, 24 November 2012

Manager in Agile team.

There is no manager in Agile team.

It might be hard to believe, but developers know what needs to be done, as they have backlog and their own brain!
They do not need another guy, who is cultivating seagull management. 


And now shit load of stuff is getting a new meaning :P


Saturday, 10 November 2012

Which game are you playing ?

Few days back, I spoke with my friend about pretty "funny" situation. He told me that developers at his project are playing a game, which my friend called Pair Programming vs. Code Review. If developers like each other, they play Pair Programming. If they do not like each other, then they play Code Review.

As you can see those developers found a problem, where it was not even existing. That's a rare and undesired skill, which often manifest itself in pseudo pragmatic teams, who are probably not sticking to 5th Agile manifesto principle: 
"Build projects around motivated individuals. 
Give them the environment and support they need, and trust them to get the job done."
Generally, it is called over-engineering! But not only that, they are loosing time for guerrilla warfare, rather than focusing on helping each other. They also seem not to have any respect to each other. 

The question is: should it be this way? Of course, no!
I would like to be clear about Pair Programming and Code Review, so let's start from some definitions.

Scratching Tiger, Hidden Dragon - Pair Programming

One developer types in code at the keyboard. He works at the tactical level. The other one looks for mistakes and thinks strategically about whether the code is being written right and whether the right code is being written. 

You can also describe pair programming in a more holistic and tao oriented way, as a yin-yang or a unity and harmony arousing from diversity. There are many approaches explaining principles of pair programming like coder and observer, driver and navigator, however I am always keen on scratching tiger and hidden dragon parallel. 



In other words, it is a conjunction of opposite features like active and passive, linear and non-linear or specific and general in a collective action such as solving a problem - programming in this case.
To be fairly honest, one can extend and generalize this approach to any sort of task you have got to do. 

The overall idea is very easy to grasp and simple. Let's look at pair programming from two, different perspectives: tiger and dragon.

Scratching Tiger:

  1. Active person writing the code, almost scratching it
  2. Keeps on focusing on syntax and details
  3. Uses his linear part of brain, logical (left) hemisphere to solve arousing problems


Hidden Dragon:
  1. Passive person pays attention to code quality and acceptance criteria fulfillment, almost like dragon, flying in the sky and observing what tiger does
  2. Can see whole solution, has an overall idea of subsequent tasks and steps
  3. Uses his non-linear part of brain, abstract (right) hemisphere to imagine a flow and grasp the bigger picture
You would probably agree that above description is somewhat static and simply a bit boring. Frankly, you are right, but the key here is movement and synergy you can get from it.

How can we get the movement ?

Again, this is simple. You need a proper space. Comfortable desk, two chars and two keyboards. These things are really important, so do not neglect any of it, especially two keyboards. These prerequisites enable higher level of collaboration between developers. Apart from that they are not loosing time and ideas, while swapping keyboards.

And now comes the most important part. Developers are creating a collective mind, which is buzzing and boiling due to new, fresh ideas. The worst thing you can do, is not switching between Tiger and Dragon role. You have to do it frequently, without any hesitation and freely. You cannot be afraid of your partner saying leave that keyboard, etc. When you see Tiger did a typo, initialized a loop in a wrong way or did not do refactoring, which might be done - simply take over and use your own keyboard to fix it. You need to change perspectives very often and switch your brain from linear to non-linear mode and vice versa. That is the only way you can solve difficult problems. 



Why pairing on solving tasks?

Mainly because of four reasons:
  • Readability - two people take care about readable code, both of them have to understand what was written
  • Code quality - percentage of defects found 40% - 60% (Steve McConnell "Code Complete")
  • Bus factor - knowledge sharing and mitigating the risk of single point of failure
  • Pressure - group shields developers from external pressure much better than single developer can protect himself. What's more, in stressful situations people tend to cluster to face difficult situation.

Okay, so when it is worth to pair? 


It is definitely more expedient to pair on crucial and strategically important tasks. It is also useful to pair on both very hard, non-trivial implementations and medium level difficulty tasks. There is no use of pairing on relatively easy tasks, as they do not add so much value, comparing to effort.

Always remember about rotating pairs, not giving an opportunity to get used to your partner. The efficiency is decreasing then. Moreover, it is also good not to pair newbies, as there is not master-apprentice relation, which negatively affects pairing process. Definitely people need to like each other.


Code Review - No junk in a trunk


It is a sort of semi formal walkthrough the code aiming to:

  1. share knowledge (mitigate bus factor)
  2. check design from high level perspective
  3. check at least SOLID rules appliance
  4. check definition of done (DoD)
  5. increase resilience before holidays

When can you perform code review?

Of course after development and testing, but before merging to master or trunk, so that there is no junk in a trunk.



The programmer or pair, who developed a solution, walks some other team member through new code. They start from telling the story and acceptance criteria, then they are explaining applied design and showing working, green, CI  system tests. There is also a place for Q&A and potentially some code review remarks or changes. Code review is able to discover between 20% to 40% of defects (Steve McConnell "Code Complete").

Summary

Code Review and Pair Programming are two, complementary techniques improving the general quality of the provided solution. Apart from that they mitigate the risk associated with bus factor, by knowledge sharing.
Both of them create a useful unity in development cycle. 
You may even use scratching tiger, hidden dragon parallel, in this case, as well. Pair Programming would be a tiger and code review a dragon looking at the solution from the distance. 

It is much cheaper (sic!) to let developers be tigers and dragons, rather than giving them a wigging that they loose time for crap.

Rarely you have to choose between these two approaches. Then do it wisely and choose pairing. If your management is trying to be clumsy lean oriented and tells you should not do pairing, as it is a pure waste, take at least code review. Remember, half pairing is still better than not paring at all. It is always good to discuss design, start doing the most tricky bit together and then split and finish what you started separately, if time is so valuable. 
However, in fact it does not hold true. You are writing robust and clean solutions faster while paring and reviewing, than not. 

Saturday, 20 October 2012

What's so cool about OO?

When people start reading or talking about object oriented (OO) design, there is always a bunch of quite fundamental questions appearing, at some point.
  1. What does OO design really mean?
  2. Does writing in object oriented language mean I am creating OO design? 
  3. Why some developers despite using OO language, they do not create OO code?
  4. How is OO language different from functional one?
  5. What is the first class citizen in OO and functional approaches?
Let's start from the top to the bottom and try to answer these burning questions.

Ad.1. What does OO design really mean?

Short answer:
It is all about dependency management.

Long answer:
It means breaking source code dependency and diverting it, so that we would get an independent deployability.

Ad.2. Does writing in object oriented language mean I am creating OO design? 

Short answer:
No.

Long answer:
OO language is providing you a mechanism, to grow an OO code. The trick is that OO language creates an opportunity of using that mechanism, but nobody is pushing you to do so. That is why you have to be aware of what you are doing and consciously use available language features.

Ad. 3. Why some developers despite using OO language, they do not create OO code?

Short answer:
They do not know what OO design is. 

Long answer:
Some developers assume that writing in Java, an OO language, means they are so cool that everything they touch is OO. It is not true. Even worse thing is they do not know how wrong they are. This is sad, but often it is true.

Ad.4. How is OO language different from functional one?

Short answer:
These two approaches are very different.

Long answer:
These are two, entirely different concepts. Each of them has its own strengths and limitations. We have to know both sides to choose wisely what we need. Same time, we have to be aware of the consequences of our choice. 
Object oriented languages have a very good dependency management mechanism. On the other hand, functional approach is much better in terms of:

  • multithreading (immutability out of the box)
  • lack of states, which means lack of side effects
  • flow oriented applications.

Ad.5. What is the first class citizen in OO and functional approaches?

Short answer:
Object oriented languages: objects.
Functional languages: functions.

Long answer:
Functional languages: functions.
Object oriented languages: objects, but to be fairly honest the interface is the one, who is a major player. 
As I said previously, it is all about dependency management. To be more precise, it is all about how to invert source code dependency (aka compile time dependency) against flow of control (aka runtime dependency). To satisfy that idea, we have a set of techniques enabling us dealing with dependencies:
  • SOLID principles - helps to manage dependencies in OO design
  • Component cohesion principle - describes forces that cause classes to be grouped in the independently deployable components
  • Component Coupling principle - describes forces that govern dependencies between components
Robert C. Martin pulled together above principles and formed a regim of dependency management.


Okay, so what is the beef ?

Again, it is all about dependency management. Let's crack down some simple, but not easy example. 
Imagine a car using an engine. The Car object is having a dependency to the SportEngine. 
We may crystalize that dependency by saying that Car has a start method, which uses SportEngine's run method. That is how our initial dependency may look like:




package com.korczak.oskar.blog;

import com.korczak.oskar.blog.engine.SportEngine;
            
public class Car {

 private SportEngine sportEngine;

 public Car(SportEngine aSportEngine) {
  this.sportEngine = aSportEngine;
 }

 public void start() {
  sportEngine.run();
 }
}

package com.korczak.oskar.blog.engine;

public class SportEngine {

 public void run() {
           // here goes some engine implementation
 }
}



As you can see, we have a source code dependency pointing exactly to the same direction as runtime dependency. Source code dependency is an import statement in Car class, which associates Car with SportEngine, in a direct way. Runtime dependency tells you that Car uses SportEngine, so that it can start properly.
The whole idea of solving above problem and many other, similar issues is:
TO BREAK A SOURCE CODE DEPENDENCY AND DIVERT IT




That is an extremely crucial thing to understand. However, there is one gotcha here. People may think that whole trick is about diverting the compile time dependency arrow from SportEngine to point directly to the Car. This is wrong! It needs to point towards Car, but not directly. 

How can we do it ?

Let's introduce a middle man called an Engine, which in fact is a polymorphic interface between Car and SportEngine. The Car class will be using Engine interface, which would have a run method. On the other hand, SportEngine class will be implementing Engine interface. 
From now on, we have the source code dependency diverted and pointing towards Car class, at least from SportEngine's perspective. That point of view is one of the most important assumptions, which we need to understand. Only embracing SportEngine's perspective and its source code dependencies allows us to see the bigger picture. 
From high level perspective, the whole idea looks easy, however it is only a superficial feeling. In fact, we have to see the problem from three, totally different perspectives (Car, Engine and SportEngine).

Summing up, SportEngine knows about Engine and so as Car class. The runtime dependency's direction remains the same and points through Engine's interface to SportEngine class.







package com.korczak.oskar.blog;

import com.korczak.oskar.blog.engine.Engine;

public class Car {

 private Engine engine;

 public Car(Engine anEngine) {
  this.engine = anEngine;
 }

 public void start() {
  engine.run();
 }
}
package com.korczak.oskar.blog.engine;

public interface Engine {

 public void run();

}
package com.korczak.oskar.blog.engine;

public class SportEngine implements Engine {

 public void run() {
           // here goes some engine implementation
 }
}

That is what we got:
  • Car and SportEngine are separate classes
  • Independent deployability
  • We can have many different Engines deployed 
  • Module SportEngine plugs in to Car

Real life example.

The almost obvious extension would be to apply above principle on different levels like: classes, modules, components, entire applications or DBs. 
Few days back, I found that principle very useful on a DB level. We got a very tight dependency between us and other project, who had a read only access to our DB. I know that letting even a read only access to other projects is something similar to ripping the application's skin and exposing our guts to the public, but let's not discuss the root cause of that situation. The issue was pretty substantial and causing a lot of annoyance, hurt feelings and other stuff. Every single alter operation on a table like changing the type of field, its length or adding a column was a massive pain for both sides. I will only mention that adding a new table or dropping it was even worse. On a top of that we found that we have different release cycles. Basically, we were required to slow down our process, so that we would conform to the slower project. Incidentally, it was very similar to situation almost all of us had at school. Teacher had always to work as fast as the slowest person in the group, causing others to be pissed off. On the other hand, the slowest guy was also annoyed as everybody was waiting for him. Typical loose-loose situation. 
We badly needed a clutch and we found one. The solution was to expose only those business data, the other project needed, via DB views. All the rest say technical data was hidden behind views. We built these views having a well defined interface between us and them. Interface was not changing almost at all and we were independent from the other project. We still could do releases in our pace, without any other external dependency. Other guys were also happy about still DB interface and maintaining their release cycle. Typical win-win situation.  

If we examine above case, we easily find that project exposing some data was an allegory of SportEngine and guys reading our DB were a reification of Car. We simply created an interface, which diverted a source code dependency.

Sunday, 14 October 2012

Show Me the Value

Do you recall a well-known phrase uttered by characters in the 1996 film 'Jerry Maguire'?



If one would like to sum up Agile practices in a neatly tailored way: 
'Show Me the Value' is one of the best approaches I have ever heard about. 

Sunday, 7 October 2012

The Bigger Picture of Lagre Projects

Have you ever thought how big your project is and what it implies? Many people boast of their projects and how lagre they are. However, there is one consequence, people seem not to be aware of: the bigger project is, the harder is to finish it on time or at all. According to Jim Johnson of the Standish Group: 

"Projects greater than $6M are considered large and have a 1% success rate."

Hence, if you do not know the size of you project you are taking a part in, you'd better ask Project or Programme Manager about that!



Sunday, 30 September 2012

Last samurai's scream of despair in bastard project

The rule of thumb is fact that legacy projects are definitely more common, than greenfield ones. People are saying there could not be anything worse, than legacy project. Hmm ... I strongly disagree. Let's have a quick look on definitions. 
Greenfield project menas there is lack of any constraints imposed by prior work and it is like a Saint Grail for all developers. The antonym to greenfield is brownfield, which basically means an abandoned area or underused facilities available for re-use. Between these two distant concepts, we can place legacy code, as an idea more close to brownfield. So as you can see, legacy project is not as bad as people are used to say. 



To my mind, the worst thing is a bastard project, which is a hybrid of legacy code and extremely high ignorance of almost all people involved in the project, in any way. This could be detected in couple of ways, but definitely by close observation. The most common symptoms are:
  • PM is telling you your project is a great challenge in your life
  • PM is telling you your project is an opportunity to work with (difficult) client
  • There also might be a set of legacy projects, around you, in your company, done for same client
  • Lack of tests or brittle tests (extreme example: "tests" exercising code without assertions, just to satisfy coverage)
  • No leading concept visible though whole project
  • Huge entropy in code base
  • Design screams help me or delete me
  • Scream of despair of the last samurai
I can only say that it is really nothing good happening with project that came to the point, when the last samurai screams due to distress. 'The Last Samurai' in the project is that sort of person, who serves his:
  • shogun/emperor (Client/Lead/PM)
  • co-brothers in clan (team members)
  • code of conduct (bushido)
Last samurai is always fighting for all above points. It is not only a matter of honor, but also a matter of faith in what he believes, common sense and health and safety. He knows what he is capable of, as he is a software craft master. The last samurai takes care about both his and entire crew's safety, as he feels very attached and committed to the project. He effortlessly sees the bigger picture and embeds his actions in project's context. The last samurai has also developed the ability of anticipating the future. That kind of person serves in the best way he could to his master. His rules and principles are like katana: shiny, resilient and well defined. Samurai is always true to his convictions, he never gives them up. One of samurais' rules says: "Katana wa bushi no tamashi", which means that the sword is the warrior's soul. One samurai in project is rare, but two and more of them are a true gift. 



So when you can hear the last samurai's scream of despair? Hmm ... it is a pretty tricky question, as samurai is a warrior, who is not afraid of sudden cuts and acute attacks. He does what he was trained to. The scream of distress is heard, when he is left alone. Project's Shogun is not considering his pieces of advice and has his own sick and not possible to introduce, weed-like visions. It is even worse, when the company's great emperor is deaf to samurai's begs and blind to results of his own debatable actions. It is highly probable that emperor is beguiled by some unreal promises and is working in his own business. 

Samurai means "the one who serves in close attendance to the nobility", so the worst thing for samurai is not to have a master, nobody to serve to - to be a ronin. 'The Last Samurai' movie shows Katsumoto and his co-warriors dying in unequal struggle, just to enlighten young emperor and to make his eyes open to true problems. In current world, the last samurai, can actually do one of below things: 

  • try to talk, enlighten and show the correct path, pointing same time to what was done in a wrong way, if it is not helping, than
  • show his problem to a panel of experts, if it is not helping, than
  • rotate out from that sort of project, if it is not helping or possible, than
  • change the job

Legacy project could be helpful in terms of self-development, however the necessary condition is will and passions to change it.
If a top brass is playing games, using you as a puppet and very often demanding you not to comply to your "bushido", then your ideological fundaments will start to shake. Instead of being resilient as samurai's sword, you are feeling like a wobbling jelly. It is highly probable that you will collapse. Your team lead is asking you to stop testing, so that you can deliver more crappy code. 'Quality does not matter in the tool you develop as it is not used by many people' - they tend to say. You could be also asked to write brittle tests or test your code on production environment. The only relevant thing for them is to manage to deliver before deadline. It does not matter, if new changes work or not. All this strange ideas are being justified by bizarre explanations and of course everything is for sake of client.
If you are thinking what the heck, you are right! Do not let them break your attitude and morale by constant mantra: 'Do not refactor this code'. If your team is breaking your balls, whole environment is reluctant to refactor, add tests and follow proved and established practices, there is only one thing you can do - ask yourself a question: "Would you like to be the last samurai, who moans dying for his shogun?".
I would not. That is why, I would rather stick to Tomek Kaczanowski's piece of advice and at least rotate out from that doggy, bastard project.


Sunday, 23 September 2012

Golden rule of readability

Golden Rule:
Readability on a first place. It is a general rule in software engineering. Of course, everything should be done with a dose of common sense.

Paraphrased by extremists:
It is better to have a readable and not working code, rather than non readable and working one. 

Explanation:
One is able to fix readable code easily. Although the second statement says the code works, it is still not readable!



Wednesday, 12 September 2012

Early and continuous customer's satisfaction in cyberspace


Let's consider first agile manifesto principle, i.e.: 
"Our highest priority is to satisfy the customer through early and continuous delivery of valuable software."

What it basically says is that there is nothing more important for us, than satisfying our business client through:
  • early delivery
  • continuous delivery
  • delivery of valuable software

Ideally, we ought to start to deliver something valuable for our customer from the very first day, when the project starts. Apart from that we have to remember about delivering these valuable bits constantly.
Hmm ... one may say, in reality, it is quite hard to commence delivering valuable software from the beginning of the project. 
To my mind, an important question seems to be: what is the definition of valuable software from client's perspective? The thing that only matters for business is something that adds value for them. They are 100% right, however in my humble opinion, majority of business people have slightly twisted perception of that definition. In other words, they seem to consider value in places, which directly maps to money. Whereas, a deeper look from risk management angle reveals business value in operational readiness or continuity of deliveries. This also means money, but this time not direct one. The root cause might be lack of risk management skills and not being able to see the clear, bigger picture of what is going on. They seem not to appreciate value hidden in infrastructure almost at all. In contrary, in any army, especially during the war, infrastructure like robust roads and railways or fast and reliable communication channels etc. are fundamental factors. The Second World War proved that rail and roads might be a key to transfer military units between places in few hours. 
Infrastructure, especially CI infrastructure, is not a direct business value itself. Although in IT it is something invisible (all in all everything is a software), the quality of it is a clue and creates a reliable scaffold, where business values can be spread. For instance painters always prime their canvas before painting. They do it in a fairly detailed and decent way, as they know it is a "scaffold for their vision". Infrastructure in IT pays dividend when the project lasts and even after that when it operates. So the question remais: what is a business value? Is infrastructure an added value for business? Is being operational BAU 24/7 a fair point? Aren't these two adjectives (early and continuous) a deliberate game of words in agile's first principle? Apparently contradictory, but in fact complementary statements: early and continuous delivery. In economy, they tend to say the the best business is the one, which is operating all the time. Wait a second, isn't it what we just said that infrastructure is something allowing business to be run and produce value 24/7? Yes that is exactly what we were in mind!
From my perspective, every project starts to deliver a value for business, from the very first day, either in pure business stories taken from backlog or in terms of infrastructure being a skeleton for whole business we cater. 




Now, let's focus on cybernetics, an extremely relevant and transdisciplinary science, rooted in ancient Greece and even earlier. Basically, it is an approach for exploring and examining regulatory systems in terms of their structure, constraints and possibilites. Cybernetics is only applicable when the system being analysed is involved in a closed signal loop. It means that actions done by the system causes some change in its environment and that change is fed to the system via information (feedback) that enables the system to change its behavior. Above description has two, valid points. First of all, cybernetics is a transdisciplinary science, which connotes a research strategy crossing many disciplinary boundaries, to create a holistic approach. This might be compared to generalization rule in OO languages. Secondly, definition focuses on feedback loop, as a main source of information for changing its behavior. Every scientist and discoverer may and should ask, if there is any principle or rule we can take from Cybernetics and apply it in Software Engineering?



Having all above knowledge in mind and treating it as a prerequisites let's do some cybernetic analysis and try to answer above question. Given every member of agile team is a distinct cybernetic system, equipped with some sort of feedback loop. Let's further assume that environment, we are deriving information from, is code base. Then the only unknown remains feedback loop. A source control management (SCM) tool might be perceived as a sort of feedback loop. 
Let's put under examination two very well known SCMs: SVN and Git. 
Probably all of us know what 'painful merges' are. We are exposed to them as we are breaking at least one of below rules (I was discussing that topic here):
  • Baby steps
  • Small scope of changes
  • Short living branches 

A rule of thumb is that SVN merges are not the most pleasant things we may do, in terms of development process. Because they are so, we do not tend to do them as frequent as we should. As a matter of fact, we end up with, say one merge per day, which is done in the morning, or even not that often. We are obviously breaking at least one of above rules and we might end up with something called a 'merge hell'!
On the other side, Git as an alternative SCM solution is having incorporated merging process (or rebasing if you like) into your day to day development cycle. Complying to rules allowing you to avoid painful merges and having Git on your side, enables you to commit more often, comparing to SVN. 
Let's come back to our cybernetic experiment and SCM as a parallel of feedback loop. How do you think, which SCM is better? Is it SVN with its clumsy funny merging process and rare synchronisation with remote repository or Git, which is pushing you to rebase frequently as a part of your development cycle? It is your choice, but remember about everyday pain of all people using strategy you have chosen!


Sunday, 9 September 2012

Two ways of constructing software design

"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - Sir Charles Antony Richard Hoare

Saturday, 8 September 2012

The way Monet designs software

I have been to art gallery, recently. The topic of my last visit was great impressionist of XIX century. I was standing in front of Monet's "Japanese footbridge" and seeing how that picture transports me into an actual moment that existed in the past. The artist and me (the sitter) encountered each other in a real time and place.



Imagine you are in the place when the portrait was being painted. What was happening in the place? Imagine the conversation between artist and the sitter. Conjure up the smells and the background noises. 

Step back in the time and ask yourself a question. Is your code base screaming out a design, a business need your code is fulfilling or it is just an awkward technical mumbling? If code base you are working with reflects model, view, controller, utilities etc. parts as separate packages or entities, the only thing it does, is wrapping business needs into technical bits. This is wrong! The driving factor for organizing code base should be business need. Only then, your code, which is a design, will be screaming business use cases to all of us.

Saturday, 1 September 2012

Basic development cycle in Git

This article is a short overview of Git and how it can be used in development.
I started to use Git, some time ago and almost same time I fell in love in it. Now, I know that I'm fully devoted to Git and I don't want to come back to SVN, any more. 
I don't want to slander SVN, as it solved majority of CVS drawbacks, which were teasing our industry. However, the thing is, Git is so much better, than SVN that honestly, I can't see the point of sticking to it, for even a minute longer, than I have to. SVN had its five minutes and used them in a pretty decent way. Now, it's time for the Git!
When it comes to Git's learning curve, it's not extremely steep. There is a well written book, titled GitPro, which shows all necessary concepts useful in every day development. If I were starting learning Git, I would read first three or four chapters, just to get a general idea what is the whole thing about.
In terms of architecture, the most influential decision made, was treating Git as a distributed Software Configuration Management (SCM) tool. That approach turned SVN's flaws into Git's virtues. Now, Git is boasting of its:
  • speed
  • failure resistance
  • spread backup
There is a very interesting observation showing that basing on a single design decision, Linus Torvalds got rid off all ridiculous issues we were heroically fighting with, in SVNLet's quickly recap all of them and show how Git copes with his ancestors' cons:
Speed - there is no need to wait for syncing with remote repo, every single time you want to commit, as Git is using a local copy of remote repo. The only thing you do is occasionally pulling and pushing changes from/to remote repo.
Failure resistance - there is no concept of central repo, so during development process everybody has a copy of the whole, initial repo. Assuming destruction of one of the repos, the recovery is quick and easy. It bases on a copy of remote repo on other machines. It's much harder to loose all changes on all dev machines. As a consequence of one repo failure, there is no longer a tie up for all developers.
Spread backup - given the remote repo is down, you can still work on your local copy of remote branch and sync with remote one, when it's up and running.



Okay, let's get down to the business and show how basic, Git, development cycle may look like.
First of all, we would need a Git installed on our machine. Furthermore, a GitHub account would be a sort of must for us, too. We will use GitHub to set up a project and have a reliable remote repo. Everything is described on GitHub's bootcamp page, so I'm not diving into it.
When it's done, we have two options. We may start our project on our local machine and add it to remote repo or we can clone existing remote repository. To start a repository at current directory issue:
$ git init

If you like to copy, say remote repo, use:
$ git clone https://github.com/oskarkorczak/sample-repo.git

You are able to list all your repositories (local and remote), using below command:
$ git branch -a

Now, we would like to crete a separate branch and start developing our change:
$ git checkout -b name-of-the-new-branch

Basing on a small steps rule and TDD cycle, you would like to commit every single time you have a green test. In order to check, what changes are going to be tracked or potentially going to be committed issue:
$ git status

You can also commit whenever you feel you did something valuable in branch. That's as simple as saying to Git:
$ git commit -am "Here comes your commit message."

It basically adds your changes under version control (-a switch) and puts an inline message (-m switch).
If you would be curious what is happening in Git's history, you can always ask for it, by issuing commnad:
$ git log

Given that it took you one day to develop a change in your branch. Now, you would like to sync it with others and commit to remote repo. First of all, you have to switch to your local master branch, which is a local copy of remote master (main) branch:
$ git checkout master

Then, download all changes done by other developers to your local master branch:
$ git pull origin master

Origin is a default name of remote repository. It basically works like IP:port address pair in networks. Origin might be an equivalent of IP and port may be a branch name, in this case, it's master. Let's switch back to our branch:
$ git checkout name-of-the-new-branch

Now, we have to stop for a second and clarify how rebase works. In a nutshell, it's highly probable that there have been some commits of other developers. Rebase is a process of lining them up, so that all sync commits from last pull request from local master, would be before your local branch amendments. Simplifying, it means that rebase process will put all your changes at the end of updated master branch.
$ git rebase master

If it happen that you would have some confilcts, rebase command will stop at the first conflit and notify you about that. You have to resolve all conflicts manually or alternatively you can install a merge tool. Resolving process is a step similar to SVN. You have to go to particular file, delete unnecessary entires and tell Git it's done, by adding new changes under version control:
$ git add resolved-file-names

Then, you have to prod Git to carry on rebasing your changes with local master by:
$ git rebase --continue

If you forgot about adding something to the code, you are always able to abort rebasing by:
$ git rebase --abort

After that, it's time to send your branch to GitHub, where it could be picked up by some Continuous Integration system for building and testing purposes.
$ git push origin name-of-the-new-branch

When all tests are green you can raise a pull request. On GitHub it's simple, you are switching to your branch, pressing a "Pull Request" button and it's done. You're getting a link to pull request, which might be send to all developers to be reviewed. When code review is done, your pull request might be merged with remote master automatically by pressing a "Merge" button in pull request. There might be also a case that between the moment you send your changes to GitHub and hitting "Merge" button, somebody else merged his changes in overlapping area of the project. Then, there couldn't be done a fast-forward merge, which means repeating a part of above sequence of steps. You will have to update your local master, do the rebase and once again send updated branch to GitHub. Another "push" will update exiting GitHub's branch automatically. "Merge" button is available once again.


Assuming that you smoothly went through code review and merging procedure, the last thing you should do is cleanup. Remote branch is no longer necessary and it shouldn't clutter remote repository, so we are going to delete it:

$ git push origin :name-of-the-new-branch

To be honest, deleting remote branch is a bit dodgy for me. Who the heck invented colon before branch name as a deletion marker? A sort of -d switch is more natural, isn't it?
On the other hand, removing local branch is totally different and is done by command:
$ git branch -d name-of-the-new-branch

There are also two more, very useful Git commands. First one is responsible for fetching all remotes to local repo:
$ git pull --all

Second one is removing from local repo all branches, which are not existing on remote repository:
$ git remote prune origin

Later on, say next day, when your code base is changed by other team members, you can call a chain of useful commands. They will update master and all other branches, clean branches no longer maintained on remote repo and list local and remote branches, which are currently used. All these things might be done by invoking commands you already know:
$ git pull origin master; git pull --all; git remote prune origin; git br -a

At this point, you should know whole, basic Git development cycle. 


There are also couple of golden rules related to development as such. They are especially useful while working with Git:

  1. Baby steps - use TDD and commit every single time you have a green test.
  2. Small scope of changes - keep your changes as small as possible, not to affect many places in the code base. It prevents your changes from alternating between you and other developers.
  3. Short living branches - tightly connected with above point. The longer branch lives, the more vulnerable it is for not merging in a fast-forward mode. 

Saturday, 25 August 2012

Brian Marick about monads

Brian Marick is one of the signatories of Agile Manifesto. He's also a person closely working with functional languages. 
Few days ago, a friend of mine showed me his amazing monad's tutorial on Vimeo.

There are 4 parts, so don't miss any of them.

Friday, 24 August 2012

Pig in the suit

I often hear people saying we do Agile in our company. Especially, HR, headhunters and recruiters are excelling and even abusing that term, but not only. Unfortunately, there are also some developers not paying attention to that game of words. 
To my mind, there is a fundamental difference between doing and being Agile. When somebody says his company is doing Agile, for me it basically means that Agile methodology was imposed to that company. There could be various reasons for that e.g. Agile is trendy or other competitors on the market are Agile, as well. 
Actually, this whole situation reminds me a story about pig in a suit. People were willing to transform pig into a gentleman. They dressed it in the suit and started to call it Sir. The thing was, it was still the pig eating potatoes from the feeding trough.



To be fairly honest, no one can do Agile. Basically, agile is an adjective so you simply can't do it. Instead, you can be agile and that matters, not only from linguistic point of view, but also from semantic one. Being Agile is like a culture, religion or something built-in into your mind and soul. It's a particular mindset you are applying to every decision in your project or life. It's something more than process or methodology. It's the way of life, a way of thinking and approaching problems. It's exactly what Chinese call "tao" or "dao" and Japanese "do". It all means the way, route or path. There are couple of things Eastern cultures are doing in a right way. One of them is naming convention. It's simple and self explanatory. For instance the whole philosophy related to Agile may be called AgileDo or Tao of Agile (i.e. The Way of Agile).
Company adopting Agile should also adopt all Agile values and principles. It's a simple choice between everything and nothing. You can't take a couple of bits and bobs from values, a bunch of principles and thinking that Bob's you uncle. No, you have to take them all.
Next time, when a headhunter, recruiter or anybody else calls you, remind yourself about pig in the suit and answer one, simple question. Would you like to work for the pig in the suit and call it Sir?



Wednesday, 22 August 2012

Explosive mixture - the art of showing options

Chemistry is very practical subject teaching us about actions, reactions and energy freed or absorbed. Couple of years back, I was really involved in chemistry and up till now I still really love it. I'll never forget my first experiments with so called 'fairly safe reagents', when I almost lost my teeth. I learned that there are combinations of components that may cause massive exergonic reactions.

How we can get an explosive mixture? It's simple, you only need an oversized backlog, tight deadlines, low morale and business constantly asking questions, where we are. All these things you can experience at work. The problem starts to appear when you are exposed to these factors at the same time. The critical mass is reached very quickly and business guys start asking detonating question: could you resign from all your current estimates and reevaluate all your tasks until first deadline, please. Of course, all of us have to conform, estimate effort, which is left and respond saying we can't make it. Then, business is trying to digest indigestible answer and they come up with new, marvelous idea: could you possibly reestimate and double-check your efforts once again, but this time considering sticking to first deadline and all stories in backlog. Again, you are at least trying to clarify that it's not feasible to do all planned work. As you probably can see the avalanche is round the corner. Business is now not asking, they require the work to be done, of course saying same time - no pressure. This is an exergonic reaction, which might have been stopped much earlier!

The trick is to know that scheme and stop it right after first question from business side. Instead of saying we can't make it and being on your way to reach critical mass for exergonic reaction, try saying we can provide you options. Basically that's the only thing you can do.

Let's consider an example, where business is asking you to create a communicator featured with chat, audio and video conferences. Let's further assume that whole project is endangered, as it's highly probable that it won't be delivered on time. In that case the only thing you can do is to provide some options, e.g. you may say can provide a communicator having:

  • no GUI
  • only chat
  • option of picking up the phone (establishing connection) without hearing each other :)
  • only chat and communication in half-duplex mode
  • only half-duplex
  • only full-duplex
  • only video without audio
  • no multi conferences, etc.
As you can see there are plenty of options and you don't have to say: "we can't make it". It's hundred times more digestible for business, than saying "it's not gonna be possible". It'a a win-win situation for both sides. You would do your best and business would be happy that there is at least opportunity to call and establish connection without hearing each other. Something is always better than nothing. Even, if that something is almost nothing.

Thursday, 16 August 2012

What does "software design" actually mean ?


Have you ever thought about software design and what it really means? Actually, I have spent some time investigating that problem. At some point, I even started to be so curious that I did my own enquiry. I was asking two simple questions: what design is and what does it mean, to almost all engineers I met. Basically, I could divide them into quite a few groups i.e. civil, electrical, mechanical, electronics and even aviation engineers. Interviewed engineers had also a different level of expertise. 
All their answers were focusing on inventing a solution to a given problem. Then, they were pointing that the problem itself should have been divided into subproblems, small enough to be tackled separately. Basically, that principle is called 'divide and conquer' and it's widely known in any sort of science. What's more, they were highlighting fact that series of prototypes or proofs of concept and its validations had to be done. If they were not happy with test results, they would have to redesign the prototype. Second important observation was blueprint produced as a result of whole designing process. There is also one more, extremely crucial concept hidden between lines - the price of implementing a solution. Everywhere apart from IT the price is very high. Almost always implementation takes time, manpower and money. However, in IT the whole, so called build process is relatively fast. Comparing to other branches of engineering, I would be tempted to say we have got it almost for free. I realized that this fundamental observation and what's more important, its implications are something we seem to forget and maybe even not fully understand. I came across two people dealing with that problem before me:
  1. Jack W. Reeves - C++ Journal (1992) article titled: "What is software design?"
  2. Robert C. Martin (aka Uncle Bob) in Clean Code Videos.

False Parallels


A thing worth mentioning is the existence of false parallels in software industry. We all know that software design is an abstract concept, which is definitely not something tangible as some mechanical parts, buildings or aircrafts are. Our community is often looking for similarities in other disciplines, just to show usage or explain some hidden concepts. For instance ideas of network bridge (bridge), JMS queue (pipe) or database (storage) are excellent examples. Although there are many true and valid examples, the wrong thing is association built in our minds that every single IT concept could be explained by similarities derived from other branches of engineering. I would say that it is not even all our fault. It's all about the way our brain is working. Generalizing is human's brain feature, not an obstacle or sort of impediment we have to fight with. This is a process we must be aware of and use it to understand our potential strengths and limitations. In fact, due to software design abstractiveness, majority of our concepts should be rather treated as mathematical or physical problems.


Why software engineering is so much different from other sciences ?


To be honest, there are couple of reasons, but the most important is price we pay for building code base. As whole build process is automated and needs compiler and/or linker, the overall price is extremely cheap. We may assume it is for free. If you calculate return of invest (ROI), which basically is a rate showing what you obtain involving a certain amount of means, you will get the result, which I call an infinite ROI. This is something every decent businessman is aiming for - infinite return of invest. Let's get down to brass tacks and show the formula:
Infinite ROI = ( amount of builds that could be done ) / ( time/money spent to build/buy compiler )
As you can see, the amount of builds done would be increasing over time, whereas the time/money spent on compiler would remain same. Hence, in a long run, it is worth to sacrifice any means to get automated build process. Incidentally, above statement seems to be valid in relation to continuous integration or delivery processes, as well. So after you have your compiler in place, you are able to build forever, for free.
The next, pretty significant thing is blueprint. All other sciences consider blueprint as a document describing design. Furthermore, that document is handed over to manufacturing team, so that they can implement concept prepared by engineers. The key thing here, is the blueprint itself acting as an input for development team. The output, on the other hand is a ready product. Basing on that observation, we may attempt to define our code base as a blueprint. That means that no other specification, Confluence, JIRA, Wiki page or even a Word document is a valid design document. The only thing that matters is our compilers input - source code. That's why we can conclude that software has very expensive design (as any other science), but it's cheap to implement, because we have automated manufacturing team - compiler. In contrary, building a dam, ship or space craft is having very expensive both design and build phase.


What everybody knows, but not everybody understands implications.


One of the major consequences of very fast build phase, is the increased level of changes in software requirements. I would even say that it is a constant evolution of requirements. Only by looking at 'changing requirements problem' from above angle, we are on a position to understand that we are no longer facing a problem of building a bridge outspread between A and B places. Software requirements become now an amorphous, organic, living system, rather that a strict document, where every single change in design costs time, money and whole design process has to be started from scratch.
Another very well known and established process in engineering is validation or testing. Typically, we build a model of say aeroplane, put it to the aerodynamic tunnel with bunch of probes and start to measure its performance and other parameters. This process is called validating or proving the concept. It's exactly the same what we are trying to do using so called spikes, proofs of concept (POC), prototypes and tests of course. Usually, when spike is not fulfilling requirements, we either trash it or redesign it a bit. Here comes the last aspect of whole validation process - redesigning. Basically, we call it refactoring, but in a nutshell it means refining our design so that it can be more powerful and resilient without harming client needs.
Kent Beck's TDD process (red-green-refactor) is our response to constant change in business requirements. To be fairly honest, Agile as such is an answer, but let's focus on TDD. As everywhere else, we also do have validation (red), implementation (green) and redesign (refractor) phase. Without established TDD process, we are extremely vulnerable  for errors, which are costing our client time and money. The rule of thumb is that even a small piece of code, during TDD process, is highly possible to be revised or fully rewritten.
If application we are writing would be an aircraft, everybody will know that it has to be done in a thorough and decent manner, tested hundred times, all scenarios checked (with weird edge cases on a top) before going to production. It's not a surprise that this kind of process takes time. What's more, it's expensive and it must last, as building is very expensive and almost always can be done only once. 
In IT we have a cheap building phase, but it doesn't dispense us from building proper solution. We also need to test what we did and redesign it form time to time. This is what mainly TDD, ATDD and BDD provides. That's how we should design our applications. That's our process! So what compiling is so quick. Let's leverage that fact for our convenience, not against us. 
I believe everybody knows at least one person saying that we don't need tests and refactoring is a waste of time. By saying that we are undermining our process, our credibility and understanding what the whole design is about.


Agile is our process


Software Engineering is so much similar and same time so much different from other branches of engineering that we deserve for distinct design process. That's why we have to and want to be Agile, not Waterfall. As Winston Royce says, in very first sentence of his paper titled: "Managing the development of large software systems", where he introduces Waterfall process: 
"I am going to describe my personal views about managing large software developments."
Waterfall is his view how large software development processes should be led - it doesn't mean it's the only one. Moreover, W. Royce worked for Lockhead, an aviation company, which is definitely a sort of that business, where safety is the crucial factor. What he did was moving whole manufacturing process from aircrafts to IT. Now, we know why it wasn't so effective. Of course, Waterfall is very useful in projects like: building a stadium, airplane, computer hardware, bridge or dam. This kind of process fits perfectly well to that sort of undertakings, but not in IT. Here building phase is cheap. I will be repeating that fact, as it's crucial to understand where we are and how it affects our job.


It's all about process, not coding.


Engineering is about setting up proper process, not about discussing whether final blueprint should be written in Word, CAD or something else. Software documentation (other than source code) should only capture:
  • important information from business/problem space, not directly included or visible in our design (which is code base)
  • aspects difficult to extract from code 
Everything else is in most useful place … code base. Our source code is what is passed to the compiler and is a matrix for building real (binary) code, which is run on various machines.
That is why I am appealing to you, please stop using parallels based on Civil Engineering, Architecture in an dumb way, which establish wrong associations in peoples' minds (especially non-software engineer ones). As I said earlier, human brain tends to generalize, so if we are selecting bad examples, they are sprouting, embedding themselves and transforming into a foundation for further associations. This is very tricky process, as initial comparison may seem to be a very good idea, however implications might be tragic. We are subconsciously comparing Agile and Waterfall production processes. We tend to equalize them and we start to think about them as same sort of processes applied to two different domains. This is wrong! The fundamental difference is in time of building a solution. That difference is so important that it changes the whole approach to software production process. It's no longer economic to spend one year designing and then implementing, whatever project is about. It's better to do something and ask for client for feedback. Of course, I'm not saying that we should drop TDD and refactoring. I'm just saying that designing phase as it's defined in Winston Royce's paper is no longer valid in software development. We should use TDD cycle instead.