XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Stay away from Design Patterns; master Value, Principles and Basics Skills first

Thursday, June 7th, 2012

Unfortunately many developers think they already know enough values and principles, so its not worth spending anytime learning or practicing them. Instead they want to learn the holy grail of software design – “the design patterns.”

Values Principles and Patterns

While the developers might think, design patterns is the ultimate nirvana of designing, I would say, they really need to learn how to think in their paradigm plus internalize the values and principles first. I would suggest developers should focus on the basics for at least 6 months before going near patterns. Else they would gain a very superficial knowledge about the patterns, and won’t be able to appreciate its true value or applicability.

Any time I get a request for teaching OO design patterns, I insist that we start the workshop with a recap of the values and principles. Time and again, I find developers in the class agreeing that they are having a hard time thinking in Objects. Most developers are still very much programming in the procedural way. Trying to retrofit objects, but not really thinking in-terms of objects and responsibilities.

Recently a student in my class shared that:

I thought we were doing Object Oriented Programming, but clearly its a paradigm shift that we still need to make.

On the first day, I start the class with simple labs, in the first 4-5 labs, you can see the developers struggle to come up with a simple object-oriented solution for basic design problems. They end up with a very procedural solution:

  • main class with a bunch of static methods or
  • data holder classes with public accessors and other or/er classes pulling that data to do some logic.
  • very heavy use of if-else or switch

Its sad that teams don’t understand nor give importance to the following important OO concepts:

  • Data and Logic together – Encapsulation (Everyone knows the definition of encapsulation, but how to put it in proper use, is always a big question mark.) Many developers write public Getters/Setters or Accessors by default on their classes. And are shocked to realize that it breaks encapsulation.
  • Inheritance is the last option: It is quite common to see solutions where slight variation in data is modeled as a hierarchy of classes. The child classes have no behavior in them and often leads to a class explosion.
  • Composition over Inheritance – In various labs, developers go down the route of using Inheritance to reuse behavior instead of thinking of a composition based design. Sadly, inheritance based solutions have various flaws that the team can’t realize, until highlighted. Coming up with a good inheritance based design, when the parent is mutable, it extremely tricky.
  • Focus on smart data-structure: The developers have a tough time coming up with smart data-structure and putting logic around it. Via various labs, I try to demonstrate how designing smart data-structures can make their code extremely simple and minimalistic.

I’ve often noticed that, when you give developers a problem, they start off by drawing a flow chart, data-flow diagram or some other diagram which naturally lends them into a procedural design.

Thinking in terms of Objects requires thinking of objects and responsibilities, not so much in terms of flow. Its extremely important to understand the problem, distill it down to the crux by eliminating noise and then building a solution in an incremental fashion. Many developers have a misconception that a good designs has to be fully flushed out before you start. I’ve usually found that a good design emerges in an incremental fashion.

Even though many developers know the definition of high-cohesion, low-coupling and conceptual integrity, when asked to give a software or non-software example, they have a hard time. It goes to show that they don’t really understand the concept in action.

Developers might have read the bookish definition of the various Design Principles. But when asked to find out what design principles were violated in a sample design, they are not able to articulate. Also often you find a lot of misconception about the various principles. For example, Single Responsibility, few developers say that each method should do only one thing and a class should only have one responsibility. What does that actually mean? It turns out that SRP has to do more with temporal symmetry and change. Grouping behavior together from a change point of view.

Even though most developers raise their hands when asked if they know code smells, they have a tough time identifying them or avoiding them in their design. Developers need a lot of hands-on practice to recognize and avoid various code smells. Once you learn to recognize code smells, the next step is to learn how to effectively refactor away from them.

Often I find developers have the most expensive and jazzy tools & IDEs, but when you watch them code, they use their IDEs just as a text-editor. No automated refactoring. Most developers type “Public class xxx” instead of writing the caller code first and then using the IDE to generate the required skeleton code for them. Use of keyboard shortcuts is as rare as seeing solar eclipse. Pretty much most developers practice what I call mouse driven programming. In my experience, better use of IDE and Refactoring tools can give developers at least 5x productivity boost.

I hardly remember meeting a developer who said they don’t know how to unit test. Yet time and again, most developers in my class struggle to write good unit tests. Due to lack of familiarity or lack of practice or stupid misconceptions, most developers skip writing any automated unit tests. Instead they use Sysout/Console.out or other debugging mechanism to validate their logic. Getting better at their unit testing skills and then gradually TDD can really give them a productivity boost and improve their code quality.

I would be extremely happy if every development shop, invested 1 hour each week to organize a refactoring fest, design fest or a coding dojo for their developers to practice and hone their design skills. One can attend as many trainings as they want, but unless they deliberately practice and apply these techniques on job, it will not help.

OO Design Principles

Thursday, June 7th, 2012

Following Object Oriented Design Principles have really helped me designing my code:

Along with these principles, I’ve also learned a lot from the 17 rules explained in the Art of Unix Programming book:

  • Rule of Modularity: Write simple parts connected by clean interfaces
  • Rule of Clarity: Clarity is better than cleverness.
  • Rule of Composition: Design programs to be connected to other programs.
  • Rule of Separation: Separate policy from mechanism; separate interfaces from engines
  • Rule of Simplicity: Design for simplicity; add complexity only where you must
  • Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do
  • Rule of Transparency: Design for visibility to make inspection and debugging easier
  • Rule of Robustness: Robustness is the child of transparency and simplicity
  • Rule of Representation: Fold knowledge into data so program logic can be stupid and robust
  • Rule of Least Surprise: In interface design, always do the least surprising thing
  • Rule of Silence: When a program has nothing surprising to say, it should say nothing
  • Rule of Repair: When you must fail, fail noisily and as soon as possible
  • Rule of Economy: Programmer time is expensive; conserve it in preference to machine time
  • Rule of Generation: Avoid hand-hacking; write programs to write programs when you can
  • Rule of Optimization: Prototype before polishing. Get it working before you optimize it
  • Rule of Diversity: Distrust all claims for “one true way”
  • Rule of Extensibility: Design for the future, because it will be here sooner than you think

What heuristics do you use to decide Long Method Smell?

Friday, March 25th, 2011

I find myself using the following heuristics:

More details: Long Method Smell: When is a method too big?

Long Method Smell: When is a method too big?

Wednesday, August 20th, 2008

Unfortunately most people still measure size of code in number of Lines of Code (LoC). We all know LoC is a professional malpractice. Now, how do you objectively identify a long method? If we are not supposed to count LoC, then how can we define a long method?

Some people say, if the code does not fit in one screen and if you have to hit page down, then the method is long. How many times have you looked at code that fits in one screen, but still felt that code was long? Happens to me all the time.

Joshua Kerievsky says “If one cannot quickly and easily understand what a method does and how the method does it, it is a long method”. I really like this definition. But is a little wage to me and I don’t quite understand the theory behind why and when can something be hard to easily understand.

One approach I’ve found to rationalize long method smell is by using the Single Responsibility Principle (SRP). If the method violates SRP, there is a good chance that its Long Method.

If I need to parse the method’s code more than once, then its a good indication that the method is complicated to understand.

Cyclomatic  Complexity can also give some interesting data points to under/measure when a piece of code is long. Usually large methods have a higher CC.

Recently I stumbled upon “The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information“, a 1956 paper by the cognitive psychologist George A. Miller of Princeton University’s Department of Psychology.

In this paper, Miller showed a number of remarkable coincidences between the channel capacity of a number of human cognitive and perceptual tasks. In each case, the effective channel capacity is equivalent to between 5 and 9 equally-weighted error-less choices: on average, about 2.5 bits of information. – Source WikiPedia

What does this mean? In a layman’s world, this means that 7+/-2 is the number of things (concepts) we can hold in our brain. So when I look at a piece of code and if it has more than 9 things in there, it exceeds my brain capacity to hold it in my memory and actually understand what is going on. I often notice that 7 or less things in the code is easy to manage. Once it starts cross that number, its gets exponentially difficult to hold it in my mind and to understand what is going on.

So if you are thinking of deleting elements from an array if they match a set of to-be-deleted elements, then that’s a good method for me. Why? Coz : I have an array, a set, an iterator, a loop, current values, a comparator and a delete operation. Around 7 things. That’s the max I can hold in my brain. But now if all of a sudden you throw thread synchronization into this, I may end up taking the loop, matching the current elements and the deletion out into another method.

So size has nothing to do with LoC, its a measure of related concepts that you need to hold in your brain.

    Licensed under
Creative Commons License