Principles, Patterns and Practices

Agile Principles, Patterns and Practices in C# by Robert Martin, aka Uncle Bob, is another good, accessible read on how to design code.  This book is aimed at a higher level of abstraction than Clean Code and with that comes more good insights into ways to design code.

If you have heard about the SOLID principles and have not read this book (or the earlier Agile Software Development Principles, Patterns and Practices), you should.  You may learn some interesting insights into what Uncle Bob thinks these things mean which you may or may not have thought through yourself.  In the murky world of software development where things mean a half a dozen different things to different people, going back to the person who originally wrote about the terms can often generate insights that may have been diluted or diverged from the original thinking – for good or bad.

Emergent Design and TDD

The emergent design / TDD example is an inspirational sample of the art.   The bowling ball kata is focused on a pairing session that results in far different – and potentially far simpler – code than attempting to do full OO analysis up front.  The bowling ball example does not get implemented with objects representing classic nouns from bowling, but instead a much simpler design evolves that meets the needs of the requirements.  I feel that this is the best example that I’ve seen of where TDD works to simplify code and allows the design to emerge instead of being dictated up front.  This is achieved by initially doing the simplest thing; and then being able to refactor freely underneath the API that is set up to meet the requirements.

SOLID

A chapter is dedicated to each part of SOLID.  Despite knowing a reasonable amount about SOLID from both Clean Code and other reading, I still picked up several new insights along the way.

In dependency inversion – the idea of the consumer owning the interface – not the implementation was new to me.  It is interesting to experiment with this idea and try it out to determine what it means to the code I work on.

I enjoyed the fact that Uncle Bob does talk about caution / moderation in using SOLID and patterns.  For instance – when do you apply the Open / Closed principle?  Well a reasonable answer is when you are making a change to the code – then close it against changes of the same kind in the future.  Don’t proactively attempt to protect the code against all potential and fantasized possible changes as most likely you’ll miss the actual way it will need to change, while complicating the code.

When does something violate SRP?  When it needs to change for more than one reason.  But if it isn’t changing perhaps it doesn’t matter right now if you can look at the code and potentially see multiple responsibilities – as long as the code is concise enough and the design isn’t getting in the way now.  When it does change then perhaps extract the responsibility that is changing using SRP to guide that decision.

I can see some enthusiastic zealots reading this book and the SOLID chapters in particular and going out into the world with the One True Way to write code – with interfaces on everything and closed to all possible changes in the future and so on.  This isn’t what is being suggested, but I can see some who desire the Answer™ coming away from the book with that as the Answer.  Based on my reading – particularly on people commenting on Dependency Inversion overuse – this has already been done in spades.  That isn’t the idea.  The idea is to understand the principles so that they can be used effectively to help you build code that can change more easily in the future.

Coffee Maker example

The Coffee Maker example is an example of what a zealot may take away from this book.  The end result is an awesomely designed pluggable thing using all the principles and several patterns to the max.  It is a thing of beauty.  And it is something that I have never experienced needing to implement and would be massive overkill for most business applications that I’ve worked on.  The beautiful polymorphic design is often excessive overkill in real world business apps – and excessive excitement about plugability that isn’t a requirement often leads to convoluted messy code bases – something that I don’t think Uncle Bob is pro and something that I have seen (and sometimes done…) while search for “good design”.

A later chapter in the book discusses how to slowly refactor towards a better design as requirements come in.  The example shows the process of refactoring towards a given pattern.  That is the key and most important take away from this book that I suspect some may miss.  The coffee maker example should not launch itself onto the world in its final perfect polymorphic form.  The requirements should drive it there.  And the beautiful design that emerges based on those requirements is really interesting to analyze and appreciate – assuming the requirements needed it to emerge.

UML… still is boring to me

There are several chapters in the middle of the book that are around UML.  I know why they are there.  I appreciate it and thank Uncle Bob for the effort.  However I had to drag myself through those chapters.   For some reason I find UML really boring.  Though I know I shouldn’t.  I know I should use it, and I know I should use it right.  Maybe when I grow up more I’ll get back to those chapters and use UML better.

However – the key take away is that design is not dead.  Drawing pictures as conversation pieces to convey design is useful.  And UML is a tool to help developers communicate more effectively.  Communication is very important.  So do it.  But don’t write too much of it… rather code.

Patterns, patterns, patterns!

The final chapters of the book are dedicated to different patterns – such as the bridge and adapter patterns.  There are several concrete examples of how these patterns can be used as well as an example of refactoring, based on incoming requirements, towards a specific pattern which ends up with a more SOLID design.

Again, the patterns shown are end goals, driven by requirements that make the design change.  As the design changes it becomes obvious that one pattern or another may help to keep the code clean.  At that point, the code is refactored towards a pattern.  It may occur that other design changes make the pattern no longer useful.  At that time, refactor away.  The idea isn’t to build the code out of the blocks to support a selection of hand picked patterns.  That would be possible, but the requirements haven’t driven their need and so the code may be far less simple and effective than otherwise.

Drive from the requirements

This was a great read for me. It gave me new insights and drove my understanding of some things.  I always enjoy that.  It also highlighted for me the continued need to drive from requirements and refactor towards useful patterns rather than trying to force them up front.

Advertisements

Implementation Patterns

Kent Beck’s Implementation Patterns book is an easy and enjoyable read.  Many things are familiar, as one would expect from patterns that you’ve encountered before.  Others were hmmm – that’s an interesting idea, I hadn’t thought of like that before – which I always enjoy.

Four things stood out in particular for me.

Guard Clauses

I’ve always been a single return kind of guy.  It is what I was introduced to.  I was coding in C/C++ so you needed to have a clean-up phase inside the method if you had put anything on the heap.  And debugging was easier when working in assembly to debug your code if there was only a single return.  And Dykstra said it was a good idea.

But the way Kent Beck describes guard clauses just makes sense.  It combines really well with the example in Clean Code around separating the error handling concern from what the code is actually intending to do and achieving Single Responsibility.  It makes things simpler.

The context of needing a single return is embedded in longer methods/functions and a world where you didn’t have garbage collecting.  Today there is a move to keep methods below 10 lines, so if you exit early, well you were exiting on average in 5 lines anyway so it should make sense to read the code and understand.  The context in which a single return made sense did possibly exist.  But if you write short methods and return using guard clauses to show non-standard paths the clarity and readability of the code seems to be greater.

Cleaning too quickly

Two patterns stood out to me as being more difficult to see if you clean your code too early.  Potentially a better design is being obscured and cleaning your code a little later might allow that design to emerge more easily.

Strategy fields

If you have a few case statements that always branch on the same things, perhaps there is potential for a strategy object – a class for each case statement, implementing the different strategies.  Your multiple case statements merge into ensuring the right strategy object is created – probably at object creation time – and then just calling the strategy field to do the work.  No more ugly if trees or case statements.

Object Method

When a class starts to get large and parts of it start to do a bunch of things that are related, you might have a case for extracting an object method – an object that implements a complex method for the original class.

I particularly enjoyed the book’s description of the refactoring process to see and draw out an object method.  The key being that cleaning up the code by breaking it into smaller pieces can obscure the need for the object method.  The first step of the refactoring is to merge it all together into one big method and then extract it to the new class.

Cleaning

Maybe leaving it a little while to see the design is a good idea.  Otherwise if you work to eradicate the ifs and cases you might miss that you could use strategy fields.  If you clean up your methods too much, you might need to undo that work in order to better see and extract an object method.

Double Dispatch

Double dispatch is cool.  I knew about it and have used it, but I often forget about it as a tool that can solve OO problems.  It was good to be reminded of it, and to dig a little into the examples and think on some examples of my own where it made sense – or not.

Frameworks

The discussion around how you think differently if you work on a framework stuck with me.  I started in a large organisation which essentially was a framework – an operating system.  All code was paranoid and couldn’t fail.  Everything had to check inputs everywhere.  This embedded me with a certain way of thinking about code right from the beginning of my career.  This was a very valuable experience, but it didn’t teach me the value of doing the simplest thing to achieve the specific business goal.  The business goal wasn’t generally a specific quantifiable business requirement but a framework one of providing non-crashable, functional, non-hackable, useful APIs.  It has taken me many years of working on business applications to unlearn this.  It was great to see the book highlight the difference in the way you think about code when others are actively consuming it as a framework.

How you code comes back to what you’re valuing.  In frameworks it is keeping the consumer of the framework working (hopefully).  In business code where all the code is controlled, ruthless culling of old code is able to be done in the interests of simplicity as the code is (hopefully) in the control of the coder.

Recommended if you’re a thinking coder

I’d recommend reading Implementation Patterns if you’re keen to continue understanding how you code and why you make the design decisions you make, or if you’re looking for a few new options.  I found it useful reading each pattern and asking – where would I use it, where wouldn’t I – and really understanding the value of the pattern.  The book is very readable and certainly has helped me a little further on my road to digging into my thinking around coding ideas.  That is really valuable to me as a thinking coder.

Clean Code

I had heard about the book Clean Code by Robert Martin for a while before I finally read it. I was a PM / SM / PO blend at the time but I was glad that finally someone was writing something that people were actually using to get a bit better at coding.  I first read it at the end of last year and really enjoyed it.  When I started coding full time again this year I reread it.  I wish I had read it 13 years ago.  Though possible I wouldn’t have been mature enough to get it.  But it would have made several things a little simpler.

A couple of things were Ah-Ha! moments for me.

  • Placement of methods in relationship to other methods – where to place code in a class so it is easy to find and readable.
  • Error handling is a separate concern – remove it from the main flow of the code and the code gets far more readable.
  • Code is read more than it is written.  Make it readable.  And that can take several passes.  You need to know how to refactor safely and effectively.
  • Breaking up the code into small chunks is exactly what we do in Scrum with Stories.
  • Clean Code isn’t necessarily good code.  This isn’t a book about design.  In some ways it is the prerequisites to enable you to better see the design that is emerging so that your design can become good.  Then your clean code may be awesome code.

Readability
The thing that makes Clean Code beautiful is that it gives you simple rules or ideas that when you read them you go, hmmm… interesting – I hadn’t looked at it that way, but it could work.  And it makes sense.  So then you try them.

I have never had anyone outlining clear patterns for how to actually layout code before.  Perhaps I’ve missed the books or perhaps I didn’t find them accessible or perhaps I wasn’t in the mind space to be looking for them.  Developers are good at reinventing the wheel.  Everyone comes up with coding standards – but no one places the business value and understanding of why those coding standards are what they are.  Too often they feel like arbitrary rules.  No coding standard I’ve seen before has expressed the idea of readability – like a newspaper – and the flow of where you should try and think about placing the methods that another method calls.  No coding standard I’ve seen before has captured the idea of how you read the code as being important.  Most coding standards have “name your variable like this” or “name your method like this” types of rules – but none of them roll these ideas up to the class as a whole.  They all look at the micro level – at the single line of code where you name your variable tszEndUserName.  Not that this makes them bad.  Coding standards are useful in helping to unify the way people code on a project which is useful.  But too often it doesn’t work as well as one might envision.  My experience is things without the why usually don’t work as well as one might envision.

Admittedly a lot of the ideas that are suggested are made much easier by today’s IDEs helping us and also due to the style that Uncle Bob and all the other authors in Clean Code suggest.  If you keep the entire class file under 100 lines it is very easy to find out anything that you want in that class.

Error Handling
Error handling as a separation of concerns was a particular light bulb moment for me.  I started my coding career working on operating system code in C++/C.  There were no concepts of exception handling at the time.  Everything we returned had to have an error code.  And you could never ever crash.  This has influenced my view of how I write code and have expected others to write code.  Paranoid and defensively.  In business applications this isn’t always useful.  Extracting the concern of error handling and using exceptions effectively makes the code clearer.  This is a Good Thing.  Combining that with using the Null object pattern could make for some great goodness.

Write Once Read Many
Most people don’t think about this.  But when it is pointed out, it is really obvious.  Developers read the code more than they write it.  So spending the time to make it able to be understood and work well makes a lot of sense.  If you need to spend a lot of time working it out later, that is costly – and time not spent doing other things – like adding new features.

This does imply however that you have tests to safely refactor the underlying workings of the design several times.  Refactoring without those tests will make the process far more painful – and less likely to be as successful.

Small Methods and Classes
One of the areas I’ve heard people object relatively strongly to is method size.  The common argument is that they can understand the whole method by looking at all 30+ lines of it in one go instead of having to jump to multiple different places in order to read all the code.  I understand this argument and empathise with it a bit.

I’ve heard similar arguments made for why small story size isn’t effective.  It is impossible to implement or understand a small story.  It needs to get larger in order to do it right / get the full picture / etc.  But in Scrum and other agile techniques the value of breaking things smaller has been proven to be effective.

Small methods and small classes and highly descriptive naming all add up to reducing the batch size.  When I want to understand something – the smaller the thing is that I need to understand and fix the better.  Simple is good.

But simple is hard.  And one underlying reason why I would need to look in each of those methods is that I can’t necessarily trust that they will do exactly what they say they do.  And that is a root cause.  Not the act of breaking them down.  A code base needs to learn to trust that a method does what is says it will do and no more and then small methods will become more trusted as you won’t need to delve into every single one in order to understand why something isn’t working as is expected.

Design and Clean Code
Clean Code isn’t (much) about design.  It is largely working in the micro level of your code to make it cleaner and more beautiful.  There is unfortunately a new tendency of software developers to read this book (or get told about it) and then talk about how they are writing clean code.  Too often that involves grabbing some of the ideas portrayed and ignoring many others.  And then using the fact that they are writing clean code to imply that they are writing good code.  I’ve worked in organisations where clean code meant the code I write – which didn’t include tests.

Robert Martin has done a good thing in writing this book.  What people refer to now as clean code may not be quite what he intended.  Just like Scrum – there will be many ways of viewing clean code – and not all of them will be highly effective and give the true promises of what was originally intended by the author. What probably was intended was getting people talking about the idea of focusing on code quality. And that is a Good Thing.

Cleaning my code
I’ve been enjoying using these ideas while practicing coding katas and learning TDD.  I’ve been trying to clean up my production code using continuous refactoring.  It has been a great experience for me to be completely in control of my code using TDD.  And trying out these ideas has increased my understanding and I believe the quality of the code I write now.  Of course I can always get better and I look forward to doing so.  I particularly look forward to reading the Principles, Patterns and Practices book as well as watching the Clean Coders videos to push my coding a little bit further.

Clean code is a small stepping stone to writing great code.  It is wonderful that someone has written these ideas down instead of just the macro design ones.  It is particularly great that it is so readable and presented in such an accessible way.  Thanks Uncle Bob!

Drive

Having spent the majority of my time in Rotorua visiting and evaluating all the local playgrounds, I’ve had some time to do some reading.  This is a great thing as I’ve managed to get through Drive – which admittedly is a short read but I’m glad that I have as it provides some ideas that resonate with me.

The concepts behind agility are often brought back to business drivers.  What are the business reasons for the things we do?  We can’t deliver fast enough.  We can’t deploy often enough.  Our quality is low.  Okay – what can we do to deliver every week with a known high quality?  Right, let’s start doing those things.  Often these are brought back to business and money.  If you can’t monetize the reason for a software development practice then does it not have value?  Thankfully a lot of the agile development practices sell themselves when finding the right questions to ask or goals to shoot for.

The softer side of agility – breaking down silos, treating people humanely, motivating them to become the best that they can become – often plays second fiddle to these hard business drivers.  Scrum and the community around scrum do a good job at making the softer side more relevant.  Scrum is a great blueprint for controlling the chaos around creating software.  Focusing on the core values of commitment, focus, openness, respect and courage allows for a more collaborative and respectful environment that can be far more successful at empowering people and hence being highly productive – the thing that the business really wants.  But this is often frowned upon.  Just take a look at Richard Bailey’s talk at the Cape Town Scrum Gathering on the Hippies have taken over my team to play games to see how a CEO could view this.  My gut says this attitude isn’t the exception for most top level people in most organizations – no matter the size or the amount that they believe that they are agile.

Daniel Pink’s Motivation 3.0 introduces something else.  He fires from the hip with actual research – something that is all too often lacking in the software development work.  He shows how the traditional ways of compensation aren’t valid – something that a lot of us do know instinctively.  For instance offering a carrot of a bonus for completing work on time isn’t necessarily going to work – particularly when looking at the longer view.  It is all very enjoyable.  But kicking into his premise around Autonomy, Mastery and Purpose is far more engaging (unless you hadn’t seen the TED videos already 🙂 )

Drive introduces an additional blueprint to work with when leading and motivating people to do the best that they can.  This nicely augments everything Scrum is trying to achieve.  The concepts of autonomy (being able to do the job your way), mastery (striving to be a master at your work) and purpose (actually caring about what you’re trying to achieve) resonate well with Scrum.  When looked at on the team level – autonomy (self organizing teams), mastery (through continuous improvement) and purpose (focused Sprint/release deliverables) are clear in Scrum.  The psychology of how you engage the team to determine the way forward are empowering and seem to be central to these ideas.  They work.  We know they work as we get better teams by doing them. 

But is there something missing for the individual?  Is there something that should be added into the mix to make even more productive and motivated teams by engaging with individuals as well as the team as a whole?  And what about Mastery?  Scrum focuses on the team getting better, but doesn’t tell you how.  It is recommended to use XP practices, but not required.  And individual developers, testers or any team members should be able to focus on mastery as individuals.  Scrum doesn’t really address any of these things – which isn’t a flaw with Scrum – it just isn’t Scrum’s focus.  I’m wondering how to harness these things better to lead, mentor and coach better.  That should be interesting. 

You can be agile without being humane.  I imagine you can be waterfall while being humane.  Companies have been successfully making money for their shareholders for all of time just as much when they are focused on the human side as when they aren’t.  But there is the argument that working for an organization that has a purpose that employees can get behind and making that the core goal of the organization – while having a secondary goal of profit in order to survive – seems to be very appealing.  Making shareholder profit secondary to the overall purpose is very appealing.  Working for an organization whose goal is to make itself an awesome place to work is very appealing.  Working for an organization whose goal is to change the world, cure cancel or something else noble is far more motivating than to make some shareholder, that isn’t you, more money.  

Autonomy, Mastery, Purpose – I’ve had some of each of these during my career, but I’m not sure I’ve had all three simultaneously.  Something to work towards!

Now off to read Clean Code.  Or maybe The Prisoner of Zenda.

Got Books!

Some vacation reading:

  • Drive – because it is Daniel Pink and I really should read it.
  • Clean code – because I haven’t yet read it!?!
  • Continuous Delivery – because Fadi Stephan recommended it. Paging through it, it looks really great.
  • Applying UML and Patterns – because Herman Lintvelt recommended it in his DDD talk at SUGSA earlier in the year and I’m intrigued. Apparently it has a bad title and isn’t about UML at all – more OO design which is interesting.
  • Rework – because a collegue recommended it as an interesting read, and what the hell. Though it was in the “self-help” section in Exclusives which is a little disturbing.

All I need now is a copy of Kent Beck’s 2nd Edition XP book and I’ll be happily ensconsed in learning.

Hmmm… perhaps I need a kindle – the instant gratification may make up for not having the books to hold in the hand.

And now for 5 weeks holiday to read them all.  Yay!