Showing posts with label Legacy Code. Show all posts
Showing posts with label Legacy Code. Show all posts

Thursday, June 23, 2016

Do experienced developers have to learn?

Just recently I’ve had the not so nice experience of ignorance presented publicly. There has been a session on software engineering a colleague and I compiled for our department. The narrative was around extensible architecture a topic that would need some promotion round here as we are faced with a bunch of legacy code.

Virtually no-one showed up. Afterwards I figured that they were too busy or just not convinced that a topic like this would apply to them for they are experienced developers with some 10, 15 or even 20 years of experience in corporate software development. They just know how to code.

How did actually write all this legacy code, then? I wonder.

What happens here is a nice little mistake: experience == knowledge applicable

This is no new situation to me. I’m faced with claims like that all the time. Just like a UI developer once told me that she would not provide any mock ups for the team to discuss and commit to for she would be an experienced UI developer who knows how to build UIs for years. Again a manifestation of experience outweighs everything else.

What’s wrong with a developer so convinced and self-assured that he would give a statement like this?

Basically nothing when it comes to self-esteem. Basically everything when it comes to the ability and will to learn to progress in ones skills and abilities.

The guys giving these statements were the ones that showed only little impulse to question themselves to reflect on their skills and how they fit to the needs. It definitely has consequences when a skilled procedural programmer tries to use her skill on an object oriented language and environment. This would result in a legacy code base that is not extensible, supportable or testable, as could be observed in our code base.

Why does some otherwise intelligent person fail to see this difference? Do they really not see the difference? Or is there something else?

I didn’t come to a conclusion about this yet. My hypothesis circles around uncertainty, fear of loss of control, self-betrayal and plain ignorance.

Thinking about being in the situation of having 20 odd years of experience in software development (which I have) and considering myself an expert (which I do) and someone not even working in my problem domain coming around trying to tell me how to do things differently (which I basically did) I guess I would have and show my objections to that person.

In the end this person would question me. The expert. Would basically say I did something less optimal and perfect than I would consider it myself to be. I could imagine myself not giving a damn about this. I just would not feel comfortable with admitting my work over years has been less than excellent.


Switch back. While this feelings are just and cannot be ignored there has to happen something to improve the code quality, the design. In my opinion the admittance of less than optimal work, the admittance of failure would be to closely related to failing as a person, to closely related to not getting the bonus granted by the boss. The culture of failure needs to be there. A culture where making and admitting a failure would be understood as a learning opportunity. A culture where there is no need for a never failing expert who tells everybody who things are handled here and who has to approve any idea. We need a culture where true expertise shows itself in the experience that everyone will make mistakes and the simple thing that one single person could not know everything. Even an experienced expert level developer could learn something from a complete newbie every now and then. 



Read also:

On Coaching Agile - What I've learned from being an agile coach
On Sporadics - How to deal with intermittent tests in continuous delivery
On Agile Testing - Do we need testers?



The opinions expressed in this blog are my own views and not those of SAP

Saturday, December 6, 2014

On Coaching Agile: Techniques - Show and tell

When coaching agile methodology as well as with any other coaching you are supposed to make your point in a way that coachees are not only able to repeat what you have said but to get the idea of it. They are supposed to be able to adopt the principles to their own daily work. This will only work if you get their attention and to make them listen instead of just hearing. If you do not manage to achieve that you could as well talk about little elves in the trees. The outcome would be the same with regards to agile methodology.

So, what stands between you and a coachees attention very often sums up to pure prejudice, which could be translate into one simple sentence: "This won't work for our code." Very often this simple statement prevented my coachees from listening in the first place. They would attend the training for they are supposed to do so, and they are willing to stand it, somehow. These people will not listen, they are not open to what you want to say. To get their attention is to get around their prejudices. How would you do that?

Many people these days want to publish their own book. There are a lot of book on demand offerings where anyone who hears the call could publish his or her book dreaming of becoming the next Philip Roth or J.K. Rowling. Unfortunately most of them are not at this level. However, they enjoy what they are doing. Many attend creative writing classes to learn about how a novel would be written, what principles should be followed. The result is there are many novels around that reflect these classes teachings. They share the ever same plot structure:

Plot point 2 - Mid Point (Crisis) - Plot Point 2 - Dark Moment (Even deeper crisis) - Resolution - Wrap up

Very seldom there is development, own ideas to what a plot could look like. Most of the time there is just repetition of what has been told. They heard but did they really listen? Has there been something to listen to?

Another shortcoming of creative writing novels are the fact that they tend to TELL the reader a story. Just like this one here:

"Pat has left. Tom was very angry in one moment. The other he was wiping his eyes out. He felt sad and empty, changing moods with a blink of an eye."

Everything said. Does this catch you? Probably not. There is no flesh to the bones, no room for my thoughts to flow around a scene, to come to conclusions about it. Thinking was done for me. These sentences are gone long before the end of the novel. Same goes for many coaches. They would just stand in front of a room full of coachees and read their slides of have their say. People try to get through it without snoring. If I would be a coachee in there I would still have my prejudice and nothing could be done about it. Once out of the room I would have forgotten what might have been said. Why?

Well I just were told something. No one tried to make me thinking.

This what differentiates a serious writer from a creative writing writer is the ability to create scenes, to show me places and people, to make me think about them, to give room for thoughts and still be in control of the flow of the story. The writer makes me think and guides me through the story. Just like this:

"Photographs littering the floor. Pat and Tom at some lovely mansion up in the hills. Pat and Tom diving. Pat and Tom at many places. Pat kissing Tom. Tom hugging Pat. Some of them are torn, showing either Pat or Tom smiling at someone who's no longer there. Tom was standing at the window staring into emptiness with a blank expression. A vase lying shattered between his feet. His cheeks were wet of tears. Suddenly he turned around, kicked a photograph into the next corner and screamed at the top of his voice."

This scene shows the moods Tom are in. The reader is able to think, to figure out what's going on. She will be involved with the scene for the writer SHOWed it to her. And this is what we want to achieve in coachings as well. Get the people involved by showing what me mean. Give them a chance to come to the conclusions themselves instead of telling them what you already know and they do not know where this has come from.

A very nice example I recently was able to experience has been the session TDD and Refactoring with LEGO at Agile Testing Days 2014 in Potsdam, Germany. Bryan Beecham and Mike Bowler showed the effects of TDD, refactoring, technical debt and lack of communication between teams working on the same project with simple but very effective hands on exercises using LEGO bricks. You could physically feel the heavy load of technical debt. You could physically feel the effects of refactoring and TDD. Whether or not you come with prejudices and the strong feeling not to be willing to get involved with this the pure fact that you would be allowed to play with LEGO makes you letting down your defenses. And this is what opens up your mind just enough to be vulnerable for new ideas. When doing my next class room training I want to try this instead of reading and explaining my slides.

Another approach to get around the prejudice and especially to get around the this-won't-work-for-my-code statement would be to actually show that it works for their code as well. Me and my partner spent some time upfront the training to lay hands on the code of the team to coach. We would let them show us some part of the code they do not unit test and they think not to be unit testable at all. Within a week we would create the moving parts required to build and run a first unit test suite. And we would do just enough legacy code magic to get sample unit tests done that proof the approach works. Within the training we would have a session "Legacy Code" and the examples their are taken from the teams code base. This would be the time when we show them what could be done to their code. And guess what we got each time: Wow! No other part of the raining got them more involved and open for discussions than this one. This usually would be the time to go back to refactoring and TDD principles, to go back to test isolation. And every time we did this the teams picked up from there to grow their unit test base steadily. We just had to plant the seed and SHOW them how it works instead of TELLing them that it would be possible.



A checklist to summarize:

Pro:
- makes people think
- gives room for own conclusions
- opens up peoples minds just enough to make them join the discussion
- this-won't-work-for-us will not work anymore

Con:
- for the LEGO thing: the session is harder to control
- preparation becomes much more expensive
- you would need access to the teams code base and some initial support



Read also:

On Sporadics - How to deal with intermittent tests in continuous delivery
Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7

The opinions expressed in this blog are my own views and not those of SAP

Monday, October 27, 2014

On Coaching Agile: Killer Questions - What do you want to test?

When coaching teams or individuals in agile techniques like TDD, Refactoring, Clean Code, CI, you name it then I've found out that certain questions yield interesting effects. My absolute favorite would be this one here:

What do you want to test?

In the meaning of: What feature or behavior do you want to test?

One of the key take aways in trainings on agile techniques would be the knowledge about and the appliance of the testing pyramid. Many teams I trained would have a test structure that imitates an upside down pyramid or a trapeze standing on the short edge or even a big letter T. When they attend a training they would learn about TDD and unit tests and are eager to write them for their code too. And what seems to be rather easy in the training with a well designed and small sample application tends to become overwhelmingly difficult when they get back to their own code base which usually would be more complex and more ridden with legacy code issues.

Nevertheless they start out and want to write the first unit test themselves. And here is where the trouble starts. How would you do that? Most of them lack experience of what a good unit test would look like. What unit should you begin with? And which tests would make sense? If you never ever tried to write unit tests for your production code these questions are tough. Everything is so much more complicated compared to end-to-end testing where there is no need to understand the inner structure of your code and where design issues are not preventing you from testing.

The following is condensed from several sessions with developers trying to put a piece of their code under test. There is no single developer who behaved exactly this way. I took the freedom to exaggerate the situation for the educational purpose. But please be aware that any part of this is taken from real situations: 

So, when I pair (actually: triple) with my developers before writing one single line of code I ask them: 

What do you want to test?

Most of the developers really have no good answer to this question. They are able to explain the implementation to its tiniest detail but they fail answering this rather simple question. That is why asking it will usually be the begin of a long discussion where they tell me what actually happens in their code which things get to be done and how. This is when I would guide the discussion to the structure of the code and the building blocks it consists of. We try to identify the parts that would not heavily make use of components which are not under control of the team. To begin with we would focus on the components that depend on components under control by the team to make things a little bit easier. Most of the time this initial discussion already brings about a better understanding of their own code and architecture which will help a lot in the upcoming part of the session. Besides, me as a coach I'm able to understand the coding on a relaively high level of abstraction which helps me to not get lost in too much details. I would gain enough knowledge to understand the features and what tests there should be. With that I'm able to guide them further down the road.

Once the component to put under test has been identified I would ask the question again: 

What do you want to test?

Many times this is when I get my tour through the component and what it would be doing one more time. This is when I try to find a nice unit to start testing with. Sometimes they would pick a unit to test themselves and sometimes not. Whatever they would pick I'd try to start with. It is important that they learn to decide themselves. It is important that they take over the lead as much as possible. It is not my show. It is not about how I would proceed. It's more about being a facilitator, to lend a helping hand. When there is a unit to test I ask one more time

What do you want to test?

Now it's about to find the method to test. Often the units picked had one method that would stand for what the whole unit is all about. Anything else in this unit are just private helper methods. Now I would try to nail them down on a certain behavior of this unit, a certain method to test. Usually I would get the same tour through algorithms and underlying layers again. And here it is important to come down to what a unit test is all about: testing a certain behavior for a defined input producing an expected output. And this is what they really have to understand here:

It is about this behavior. That's the reason we write unit tests. To secure a certain behavior of the unit.

It is not about testing all paths and all combinations. It is about testing a behavior which is directly derived from the acceptance criteria of a user story. Any code that is not covered by such acceptance criteria is useless for it implements stuff no one ever asked for. When developers write their tests with the implementation in mind then they might get a high code coverage but what we would really need is a high feature coverage. By asking the question

What (feature/behavior) do you want to test?

one would always stay in the outside-in perspective which helps to keep the acceptance criteria in mind. With that writing down expected results of tests becomes pretty easy for everything follows directly from the acceptance criteria.

So, to get to the point which tests have to be written I very frequently ask my question. It proofed to be of use to not let them go the whole tour again although they always try. Early interruption is required. But be careful. Because this repetition easily will become very annoying for the people it would be wise to guide through additional questions to point them to the expected behavior or to the obvious negative tests that would be needed. If the procedure does not seem to come to an end you should propose something by asking: What if we try this and that? In the end we want to write unit tests. We don't want to drive the developers crazy.

Especially when we talk about legacy code it is more like covering the existing code with negative tests for these are usually difficult to write as end-to-end tests if at all. This would add value to the existing test base and yields fast positive return on investment by disclosing possible fatal errors that would cause the application to crash. There never has been a session without at least one of these. In most cases these tests are quite easy to write and the bugs they are disclosing are often easy to fix. With that the developers would have a successful first unit test session. In later sessions the very same technique could be used to bring about the positive tests as well.


A checklist to summarize:


Pro:
  • focuses on feature/behavior instead of algorithms and lines of code 
    • opens up your mind for new approaches
    • maybe the existing implementation could be improved?
  • forces to divide the feature into portions to be tested 
    • unveils structure of the feature at hand from an outside in point of view
    • discovers possible negative test opportunities instead of focusing on the happy path
  • annoys and breaks indifference
  • as any question forces the developer to come up with his own answers 
    • solution will be better accepted 
Con:
  • easily becomes too annoying and causes resistance 
    • guidance through hints or additional hint like questions required

Read also:

On Sporadics - How to deal with intermittent tests in continuous delivery


The opinions expressed in this blog are my own views and not those of SAP