Sunday, May 1, 2016

Interface Segregation Principle

This is another principle developed by Robert Martin who I have had the great pleasure to see speak several times at conferences.  He is a very lively speaker and you return to coding wanting to do your best work after you see him speak.  As for a skilled software craftsman, he is at the top of his game. 

ISP says that no client should be forced to depend on methods it doesn't use.  Martin came up with this when he was consulting with Xerox.  He found they had a job class that was used for every single task in the system.   A stapling job shouldn't have to know anything about a print job and all the methods for printing.

OK people I work for Xerox and there nothing called  Staple Job.  Stapling is an attribute on a job.  Print jobs can have an attribute that says staple me.  But so can Copy jobs.  So I'm not sure where he saw this but maybe it was a looong time ago. 

In practice when working with Microsoft Windows for example, there are what I call "Big A!& Classes".  They are huge with a bazillion attributes and methods.  Often I don't care about 9/10ths of them. I search through the documentation for what I need.  This is one of many interfaces I have used and dare say I have created that violate this principle. 

However, when I create an interface, I literally fight people to the bone to keep it simple.  More functionality is desired and interfaces get new methods and before you know it, you have a massive class with more methods and data then any sane person can keep straight.  I have to argue quite a bit to keep it simple - deadlines are tight and people don't want to do the extra work for this principle. 

On the flip side, I think this principle could be considered "too pure" for many software engineers.  And engineers I talk to about this principle find it too difficult to practice in a real word setting.  They understand it intellectually but don't see the benefits.   Testing is one huge benefit.  If you have a massive class for a job you would have to implement the print functions even for a staple job (which doesn't exist, just saying…).  Even if it was a no-op, you'd have to test it.


Testing takes up over half of our development activities.  So if you can save on that, ISP is worth it! 

Saturday, February 27, 2016

Single Responsibility or Changing Growing Responsibilities Principle

Architecture is full of examples of items designed to do more than one thing.  Your smart phone is a flash light.  From my last examples, a chair is also a clothes hanger.  A seat cushion is a flotation device. 

Robert Martin said in his book Agile Software Development, Principles, Patterns, and Practice (http://en.wikipedia.org/wiki/Robert_Cecil_Martin),  that every class should have a single responsibility over a part of the function.  The function-part should be encapsulated and the class should do that and only that. 

I understand the need for this as it makes the class easy to understand.  It also could reduce the introduction of bugs.  Have you ever worked with "spaghetti code"?  You make a change and it causes a bug in another area you couldn’t have imagined in your wildest dreams.   If a class has two different things it does, and you change one thing, it could affect the other piece and thus break something.  Martin gives an example a class that compiles AND prints a report.    If the content of the report changes, the class must change.  If the format of the print must change, then the class changes.  Martin argues that there is no reason for these two things to be coupled because if the format of the print changes, the content does not change and thus should not need to be recompiled and tested. Martin says a class should have only one reason to change (not two, like in this example).  


In an imperfect world, needs of software change over time.  An example: My manager is crazy over this particular module we have to is used to access and configure accounting data.  Over time it has evolved to access security data as well.  This drives him crazy because it violates the single responsibility principle (although he doesn't call it that and doesn't know that Robert Martin invented the term).  I however, think this is OK, and have argued this fact with him.   Given the schedule pressures we were under to combine these two pieces, which are closely related in our system, is not horrific.  Not perfect but not catastrophic either.  

Sunday, February 21, 2016

Form Follows Function and Function can also follow Form

We as engineers know this old saying and if you are an SDM graduate, you may remember hearing or saying it classes.   But where did that saying come from?  It can be attributed to a book by Peter Blake called "Form follows Fiasco".  It was a critique of modern architecture which the author said was too focused on form and that the function should be the utmost important in any design.  This is what I always thought "Form follows function" meant - but some interpretations say that if the function is met in the purest, most simple way, the form follows and it will be beautiful.  (1)  .  The chair designs in Denmark represent this principle.  Software, which can so easily get complex, is another example (see some actual code later). 

So if we look at the chair picture from my last blog post, in the last row, that chair looks uncomfortable to me.  If the purpose of the chair is comfort, then without a solid back and full arm rests, this chair doesn't fit the bill.  However, if the chair is to made to fit completely underneath a table, then the design goals are different and conflict with the comfort goal.  To make a chair fit underneath the table, some comfort will have to be sacrificed.

So depending on the goals of the design, what form  will meet the design criteria?  That is the question to ask.  Each design criteria might not be met perfectly but the stakeholders need to decide which one can be sacrificed.  It was more important for the chair to fit underneath the table then for it to be perfectly supportive of the back.  After all people will only be sitting here for short bouts at the dinner table. 

Also what is beautiful in software code? I had my 84 year old mother look at some code and I asked her if she thought it was beautiful. She thought all of it was … very strange.  She could see no beauty in it whatsoever.  (To be fair, she also never liked furniture from Denmark, even when it was all the rage here in the US in the late 1960s). 

Here's an example of some weather data I was working with recently from a web service that needed to be parsed:



The data was in JSON (Javascript Object Notation) format which is a widely used  by web services to return data described with text, and is human readable.  To parse this, we could created one massive class with all the items needed inside. 


However, one could break everything into subsclasses like this design, such as wind, coordinates, etc into separate classes.  Is that cleaner?  Easier to maintain?  Easier to understand?  Beautiful form?  I happen to like all in one, the first case, because I can see it all in one file.  But if I changed wind, I would end of changing the weather class.  That can be a problem to introduce bugs into a larger system. 


Back to my Danish furniture, I found a chair that was brilliantly designed as clothes hanger. 



Is this chair a good clothes hanger?  Yeah, it's pretty good.  It won't function as a full closet but it can hang a few things.  Is it the most comfortable chair in the world?  No but it is supportive and someone can sit in it, even when clothes are hanging on it.   And it also keeps beauty in the curved lines and rounded edges.  Notice that the form does indeed follow function.  This form is not just of a chair that you can sit on.  It's a chair that you sit on and hang clothes on. 

Another example is a seat cushion that serves as a flotation device.  This does two things.  It isn't the best seat cushion in town and it isn't the best flotation device in town, but it works as both.  Tradeoffs occur.  Can you imagine what would happen to this chair if the designer kept iterating to make the chair more comfortable and to hang more clothes?


So while I agree function dictates form, the simplest form and often the most beautiful form will come from meeting the a minimalist set of functions.  

Sunday, January 31, 2016

Each Iteration is Better

That's the theory any way.  An iteration is defined as "A process of repeating a set of operations until a specific result is achieved".   Iteration in software works because we can typically build something quickly for stakeholders to review.  From that feedback, we can revise the design.   For stakeholders, sometimes they don't know exactly what they want, so iterating allows them to change their minds without waiting until the final product to discover it wasn't what they wanted at all. 

This funny picture shows all the stakeholders involved in a product and how it can go oh-so-wrong.  Iterating through the project can make this picture not so funny-sad.  Yes the customer will explain the project like the first picture and the first iteration might deliver the second picture.  "But it doesn't swing", says the customer.  OK, we'll fix it to make it swing.  There's the third picture.  But oh, I need it to go around in a circle too!  The fourth picture won't happen because the programmer was already delivering the first two pictures, right?  And the descriptions don't matter, because we are using an Agile development process where "Working Software over comprehensive documentation" is what is at value.  There wasn't a separate installation, the product was delivered in phases so the seventh picture shouldn't occur with iterations.  How software gets supported - remember, all the stakeholders should give input into iterations, including support staff.  Iterations would make this series converge on the last picture.  With each iteration, the first picture would  evolve into the last picture - and with hooks on the rope so it can be more easily replaced by support staff! 

With iterations,  each design cycle should narrow all the possibilities of change so that the project can move forward.    For iterating to work with software or really any product design, all the stakeholders must have a clear picture of the final product.  In practice, this doesn't always work.  For example, the customer has one vision,  and several iterations are completed, and then a new vision emerges.  This is often considered a positive, as iterating is a discovery process for all involved.  However, most stakeholders involved need some kind of finish criteria and often a date is involved as well as money.  If you take the customer on a journey to figure out what they want,   it should be clear that there you can't predict when this could end. 

I've been involved in several projects where convergence didn't happen.  One was a case where the product was documentation to describe an existing architecture.  I couldn't get stakeholders to agree on what the architecture was.  I iterated over it several times and was honing in on something and slowly but surely bringing stakeholders along.  But one stakeholder, who was only marginally involved decided at the last minute that the architecture description was all wrong and that I needed to take a completely different view point.  His idea wasn't wrong, it was actually an interesting take on our system,  but I was running out of time.  It was frustrating.  Since I could not get stakeholders to agree, I drew up a financial statement showing what the company had already spent on this effort and that convergence was not going to occur, and I recommended they give up the effort. 

Here's another twist on iterations.  You need a team that trusts each other and is honest, while still being respectful of course.  One the stakeholders was the president of the company.  He wrote up an architecture a few years earlier and had several people review it.  Everyone said it was good and correct.  I realized that no one had the gumption to give him the feedback they were giving me.   I guess I should feel lucky.  His architecture description was not very good.   So even though it looked like his documentation converged, it truly didn't.  It wasn't used by anyone (except him), there were things incorrect with it, and it wasn't a useful description.  

Iterations often don't converge in real projects because we run out of time and thus we are stuck with what we've got.  I observed non-convergence in iterations when I was in Copenhagen recently, and I visited several furniture design museums.  I was fascinated to see these modern furniture designers used iteration. 


But when I saw these chairs, they all looked wonderful - beautiful designs in their own.  They didn't seem like incomplete versions of something.  In part this is the nature of furniture design versus software.  You have to build a chair and then build another chair for each iteration, versus just the legs.  But in this case, it seems like the furniture designer was not heading towards an end goal. 

I have a hard time figuring out what the designer's goals were with the first row of chairs.  It seems like he started with something more traditional/colonial, made it smaller and more simple, and then made some radical changes with the last chair.  This last chair doesn't look all that comfortable, but it is simple and beautiful.  In the second row is that each iteration - something was taken out, to make the chair more simple.  Each chair in the is functional and beautiful. 

A design that meets all its goals perfectly will not always lead to the simplest design.  And yet the two most simplest chairs are arguably the most beautiful.  From my experience,  the simplest software is the most beautiful as well.


My rule for iterating is stop before you made it too perfect.  Meet a minimum set of goals which may deliver the best form.