Book Review: Who Moved My Cheese?

As I’ve been thinking about my career I realize I have seriously neglected the business side for many years.  As part of my quest to learn more about the business side I’ve been finding lists of the supposedly best business books, adding them to my Amazon wish list, finding them at Half Price Books and buying them there, and then reading them.  I know my brother has been doing the same thing and I know if both of us are doing it, there are many other people who are as well.  This is what has gotten me to write a review about the books I’m reading in my copious amounts of free time (haha).  Anyway, this wonderful little ditty Who Moved My Cheese? by Spencer Johnson, M.D. has quite a following both good and bad.  Amazon’s rating (3.3 / 5) seem to show it’s split right down the middle. Some people have said it has changed their life and others view it as trite simplistic mush not even worthy of a first grader.  And, spoiler alert, I fall into the latter camp — I’m not a fan of the book.  I’m glad I got it at HPB for $4.99 cause at it’s $19.95 MSRP it’s a complete rip-off and even at $4.99 I was a little ticked off.  I will give Dr. Johnson props for making a boat load of money off this book of common sense.

I won’t bore you with the fable, but just know it involves Sniff, Scurry, Hem, and Haw as the characters and THE MAZE as the place they live and find Cheese.  If you have just a little bit of imagination you’ll know right away that

  • All four characters find cheese
  • When the cheese disappears Sniff and Scurry leave right away and don’t complain
  • Hem and Haw stick around complaining (obviously) until one realizes they need to be like S&S and find new Cheese in the scary maze
  • Eventually the other one decides to venture out from the original Cheese station and finds everyone else happy

Throw in some nice banal quotes about Cheese (metaphor for money or happiness) and you’ve got a best selling business book.  I’ll save you the money and give some real advice:

  • Things change, get over it
  • No use in crying over the change
  • Be sensitive to changes in the workplace, note what they are and start making plans
  • Always be looking for the next big opportunity
  • Leave on your timeline, not the business’ timeline for you
  • Spend the $5 it’d cost you for this book at HPB on a beer and the $20 it’d cost you for the full thing on a decent meal.  It’d be money better spent.

Principles of Good Design as Applied to Software Engineering

Most people know Apple’s iconic designer, Jonathan Ives, but few have heard of another influential designer, Dieter Rams.  Dieter Rams was the chief of design at Braun from 1961 to 1995 and head of design until his retirement in 1998.  Some examples of his work include: 606 Universal Shelving System, the Braun T3 pocket radio, and the Braun T1000 radio. These are considered iconic and many of the new Apple products share more than a passing resemblance to these iconic designs.

Many industrial and user interface designers have been inspired by his work and design principles and I’ve often wondered how his ten principles for good design could be applied to software engineering and programming.  While maybe not intuitively obvious, I believe they can be applied to programming since the principles of design are always the same.  Additionally, one should never stop learning and what better way to learn than to learn something tangential to what you enjoy?  There are always universal lessons and principles that can be adapted and applied elsewhere.

Rams’ Design Principles

Rams’ design principles are simple and straight-forward and are summarized as follows:

Good design:

  • is innovative –The possibilities for innovation are not, by any means, exhausted. Technological development is always offering new opportunities for innovative design. But innovative design always develops in tandem with innovative technology, and can never be an end in itself.
  • makes a product useful –A product is bought to be used. It has to satisfy certain criteria, not only functional, but also psychological and aesthetic. Good design emphasizes the usefulness of a product whilst disregarding anything that could possibly detract from it.
  • is aesthetic –The aesthetic quality of a product is integral to its usefulness because products are used every day and have an effect on people and their well-being. Only well-executed objects can be beautiful.
  • makes a product understandable –It clarifies the product’s structure. Better still, it can make the product clearly express its function by making use of the user’s intuition. At best, it is self-explanatory.
  • is unobtrusive –Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.
  • is honest –It does not make a product more innovative, powerful or valuable than it really is. It does not attempt to manipulate the consumer with promises that cannot be kept.
  • is durable –It avoids being fashionable and therefore never appears antiquated. Unlike fashionable design, it lasts many years – even in today’s throwaway society.
  • is thorough to the last detail –Nothing must be arbitrary or left to chance. Care and accuracy in the design process show respect towards the consumer.
  • is concerned with the environment –Design makes an important contribution to the preservation of the environment. It conserves resources and minimizes physical and visual pollution throughout the lifecycle of the product.
  • is as little design as possible –Less, but better – because it concentrates on the essential aspects, and the products are not burdened with non-essentials. Back to purity, back to simplicity.

 As Applied to Software Engineering…

Looking at the ten design principles, I’m sure you’re already seeing parallels between them and good software engineering.  We’ll go down the list and examine the meaning of each statement in the context of software engineering.

First, good software engineering is innovative.  At first glance, this might seem to support the idea of using the newest and freshest technology available.  However, looking at the rest of the rule, it specifies innovative technology can never be an end in itself.  It means, use the appropriate job for the tool and eschew the idea of using the newest technology if it doesn’t fit your problem.  Using an older library in a new way can be more innovative than just using the newest technology.

Secondly, good software engineering makes a product useful.  In the case of the software engineer, this is about easy-to-understand code (User Interface concerns fall more under UX/UI people although coding is involved there too).  This falls inline with many of the principles put forward by Clean Code by Bob Martin.

Good software engineering is aesthetic.  The design of the program (or programs) is clean and simple, like the codebase, it is easily understandable, contains enough abstractions to make sense and can be easily modified to encompass new requirements.  This is a tough point to understand, it’s hard to know when the proper amount of abstraction has been reached or know what is easily understood by others.  A few point to think about are, is the design simple?  Are you using queues instead of actors, data instead of syntax, and polymorphism instead of inheritance, switching, or matching?  Have you pulled apart the design to the base components?  Can you easily describe each part of the system?  Can you extend the design by simply removing one or two components and replace them with two or three new ones?

It makes a product understandable.  A follow on to the second and third points, the design and codebase of the program can be grokked by a new developer with little effort.  This isn’t to say it is going to be some work to look through the codebase, but it should be obvious how all the modules interact.  As a software developer, you should aim for simplicity — and note: simplicity does not mean easy :).

Good software engineering is unobtrusive.  Again, another principle of Clean Code, the codebase and design does exactly what it needs to do, no more no less, yet has the ability to be modified and integrated within another project easily and simply.  This leads to question of “how do we know the system can be modified easily and simply?”  If it isn’t, how do we fix that? And, does it mean a programmer new to the project can understand the code?  Unfortunately, this is a very interesting problem and deserves an article all to itself, but let me touch on this quickly.  In my opinion, a system can be modified easily when there are distinct breaks in modules in the code defined by interfaces that allow for good unit testing of each module proving the system is not overly coupled.

It should be honest.  Write and design simple to understand and modify code.  Consider everyone who is going to be working in the codebase, everyone should be able to understand, extend, and fix bugs within the code and adjust the architecture.  I’m not advocating a cowboy coder to come in and do a large refactor (e.g. rewrite) because in their mind it is cleaner, but again, it should be at the right abstraction at all points.  It also relates to the idea of unobtrusiveness with knowing when code is easily modifiable.

It is durable.  It uses the best tool for the job at hand; advocating code reuse and proven projects versus reinventing the wheel.  It means eschewing technologies not completely tested for your situation, opting instead for proven technologies and methodologies.  It means extending proven technologies where needed and using ideas from the bleeding edge, to make a quality product meant to last.

Thorough to the last detail.  The software’s design is meant for stability and ease of extension. The code base is well thought out and easy to understand.  The unit tests, functional tests, and integration tests express all (or as close to all) issues that can occur at the each abstraction layer.  There is sufficient documentation to understand, deploy, and modify the software.

Is concerned with the (computing) environment.  There are no memory leaks (yes, you can still have them in managed memory languages!), the algorithms are as efficient as possible for their purpose (run time vs. memory) and care is taken not to use too many resources.  The code itself is clean, straight-forward, and easy to understand.  This does not mean to go prematurely optimize and read all the papers on new, hot data structures, but it means to make good rational choice that can be explained and understood as a starting point.  As learn more about the problem and have integration testing and testing on the environment, you can begin to focus on the areas of code that need to optimized and understood better for a faster or more elegant solution.

Is as little design as possible.  As has been brought up in earlier points, the design focuses on the specifications, not the “what could happen” or “wouldn’t be cool if…” questions.  The problem is solved and designed in an elegant and easy-to-undersand way.  The code reflects this by being easy to read, understand, and modify.  You can think of this as, not being overly complicated when it comes to designing classes and methods.  Don’t use an enormous amount of variables unless you need them.

Conclusion

Good design principles can be applied anywhere design is used.  The definitions that Rams’ used were obviously questions he asked himself about his products, but it illustrates a point not laid out in his principles of good design:  you must constantly question yourself, your process, and of course, your design and implementation.

Additional Notes

I noticed multiple people have written about Rams’ design principles as they apply to software as well, you can read their articles here, here.  A wonderful talk about simplicity in design by Rich Hickey can be watched here (you really should watch it).

Additionally, I stayed away from a lot of questions that can come up. I know I didn’t touch on the idea of the right solution versus the correct solution which I’ve talked about a little before.  Also, I didn’t talk about what happens if you have conflicts between teammates on if you believe your implementation is good and they don’t, or even if your idea for the design of the software is different than someone else on your team.  These are all topics I’d love to talk about but they really deserve their own posts where we can delve into them in detail.

If you like, dislike, or have anything to say about the article, let me know in the comments below!

The right solution versus the correct solution

There is a subtle distinction between the two.  Correct implies definitive or absolute whereas right implies an appropriate but still debatable solution. In programming, we run into this problem all the time.  What is the correct solution versus the right solution?  Often times we jump at the right solution instead of thinking about the problem and going with the correct solution.  Then there are times we debate over the correct solution when the right solution would serve perfectly well.

Programming is the art of trade-offs and the right solution versus the correct solution is a perfect example (just read about it here).

Java and Immutability: Creating a Simple Builder

The more I look back on what I learned about programming in school (junior high, high school, college, etc.) I realize that although it made a great base on which to learn, it really does not get you ready for problems you’re going to see in the real world.  Of course, even then the problems are always changing and what you thought was the best approach a year ago, a month ago, or even within the last hour, isn’t.

One of the largest hurdles to jump over (besides recursiveness), in my opinion, is mutable versus immutable.  The main reason is because you’re taught from the time you start programming through college (ignoring those of you who took a Haskell class) you’re only taught using C, C++, or Java.  All languages that are mutable state programming languages (yes, you can apply immutability to them and I’m getting to that) and although (perhaps) easier to learn can lead to some hard problems down the line when you have to start thinking about scalability and parallelism.  Josh Bloch, of Effective Java fame, has said that unless you have a really good reason to make a mutable class, you shouldn’t.  And if you have to make a mutable class, limit the scope of it’s mutability.

Now, as the title of the post implies, I’m going to talk about how to make immutable objects in Java and touch on some of the issues that you might run into along with how to make a builder class to instantiate this new immutable object.  There are a few conventions that you apply to an object that will normally make it immutable with a few small exceptions.

  • make the class final
  • make all fields final and private
  • if a field is mutable make a defensive copy on a get
  • only set the fields in the constructor
  • do not allow setter methods

Now, these steps will get you there but, there are a few gotchas that people normally don’t think about.  For instance, most classes with the Iterable interface or an interface that allows removal from a set or list even if it is defined as final in the class if you pass it out to the caller using this pattern:

public Iterable<SomeType> getSomething() {
  return this.myIterableSomething;
}

are in for a big surprise (unless you’re using an immutable list) because the caller can then use the remove() method on that Iterable list that you returned.

Now that you’ve got this wonderful (and hopefully) immutable class, another awesome thing you can do is make a builder class to help construct the object.  This is especially helpful if your class takes a large number of inputs into the constructor.  There are many ways to make builder classes but I’m going to demonstrate my favorite one: a static class inside of the class you want to create.

Creating the builder is really very simple.  First, have a class you want to make a builder for, in this case, let’s use SimpleClass.

final public class SimpleClass {
  private final int a;
  private final int b;

  public SimpleClass(int a, int b) {
    this.a = a;
    this.b = b;
  }

  public int getA() { return this.a; }
  public int getB() { return this.b; }
}

Now, lets create the builder class inside of the SimpleClass, like this:

final public class SimpleClass {
  .. snip ..

  public static class Builder {
    private int a;
    private int b;

    public Builder() {
      //assign some default values...
      this.a = 0;
      this.b = 0;
    }

    public Builder setA(int a) { 
      this.a = a;
      return this;
    }

    public Builder setB(int b) {
      this.b = b;
      return this;
    }

    public SimpleClass build() { return new SimpleClass(this.a, this.b); }
  }
}

With this, we now have a very barebones builder class for SimpleClass.  In practice you’d take values that absolutely have to be set in the builder’s constructor and set reasonable defaults for the optional values.  You’d then use the set* methods to set the optional values for the class.  Additionally, if you only want the user to construct objects through the builder class you can set the constructor on the class to private, leaving you with a SimpleClass listing:

final public class SimpleClass {
  private final int a;
  private final int b;

  private SimpleClass(int a, int b) {
    this.a = a;
    this.b = b;
  }

  public int getA() { return this.a; }
  public int getB() { return this.b; }

  public static class Builder {
    private int a;
    private int b;

    public Builder() {
      //assign some default values...
      this.a = 0;
      this.b = 0;
    }

    public Builder setA(int a) { 
      this.a = a;
      return this;
    }

    public Builder setB(int b) {
      this.b = b;
      return this;
    }

    public SimpleClass build() { return new SimpleClass(this.a, this.b); }
  }
}

To actually instantiate this class in practice you’d make a call like this in your code:

  SimpleClass mySimpleClass = new SimpleClass.Builder().setA(10).setB(11).build();

And, whala! You’ve created an immutable class using a builder!

With this, you’ve taken the first step toward better coding in the real world and on problems that have you dealing with scale and parallelism.  I’ll hopefully write about scale and parallelism in later posts, so stay tuned, and if you have anything you think I should write about or a place where I’ve screwed up, let me know in the comments below! 🙂

If you’d like this source code in a nice form, check it out on GitHub.

2012 Goals – August Retrospective

Yeah, I’m a little late on getting this thing up, but I’ve been busy and have just now found the time to write this bad boy.

#1 Participate in Tough Mudder / Get in better shape

I feel I’ve been neutral on this, I haven’t improved, but I haven’t fallen backward.  I’m still going to do Tough Mudder and I’m still gonna beat it down, or at least try :).

#2 Propose PhD Topic

On my way to doing this.  I’ve gotten the proposal written and have a few changes left to be approved before all the paperwork fun time begins!  Oh, and I’ve got to write the presentation for the proposal.  Fun times ahead.

#3 Learn a new programming language

I’m diving deeper into Clojure and really loving it.  I’m also looking into Event Sourcing since it is a really neat idea.  Perhaps I’ll write something up about it.

#4 Housework

Removed some columns from inside my house, cleaning, etc.  It’s all going well.

#5 Learning Guitar

I’m taking guitar lessons and having fun.  If only I had a few hours a day to practice :).  I’m also sort of learning the piano as well, so soon I’ll be a multi-instrumentalist.

Overall

Things are going well.  I’m ready to rock and roll and as long as I can get the proposal presentation done and all the professors herded, I’ll be in awesome shape.

2012 Goals – July Retrospective

Well, I know this is a few days late, but it was because there was good news.

#1 Participate in Tough Mudder / Get in better shape

I’ve adjusted my eating habits, cutting out carbohydrates from my diet completely Monday through Friday, then only allowing myself to have them on the weekend (and not too many!).  It’s already made a noticeable change and I’m also doing at least a walk and/or a jog each day.

#2 Propose my PhD Topic

I was given the ok to propose my PhD topic this semester.  I’m putting the finishing touches on the proposal document and the presentation.  My goal is to propose the before October 5th.  I’m sure I’m gonna be pulling some all-nighters pretty soon to make sure it looks awesome.

#3 Learn a new programming language

I’m still messing around with Clojure, although not as much as I’d like (the PhD basically takes over as #1 goal no matter what :).

#4 Housework

The crape myrtle trees I’ve planted are doing well so that is a good thing.  I’ve also cleaned up some vines that were growing on my fence and that is an even better thing since I now have a nice section of my yard back without having to dodge the vines.

Overall

I’ve got a few articles sitting here on my blog that I’m working on finishing up and publishing, it’s just taking some time since other more important things keep coming up (gotta love school).  Once I get past the PhD proposal, I’m sure it’ll feel like a large weight was taken off of my chest.  To be replaced by an even heavier weight that is my goal to graduate. 🙂