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.