A philosophy of software design


My notes from the book  "A philosophy of software design".   this helps for me as a quick refresher and also can help others who do not find book reading interesting but are ok to read a blog post in few minutes.


1. Cognitive load 

How  long does it take a new hire to push his first serious commit? is it day 1 or day 2?    if it is few weeks to months, then you got a serious problem.  Its cognitive load, if we need to burn lot of brain power to understand something, then it's a problem. Make it simple, don't pretend it to be simple. It is not about you, it's about other developer(s). 


2. Tactical programming

Just in time fixes that meet the current bug or need without worrying about complete design or long term aspects add more debit.  You get things working quickly, happy. But please note your code starts the clock and counts the interest. You or  your successor(s) have to pay back or go bankrupt.    

Instead of tactical programming, we need to look for a cleaner design  that leads to strategic programming. You think of future and cleaner solution.

The time vs total progress line chart for tactical and strategic.





3. Modular design

Modules need to be deep. general purpose modularity is deeper.  This can be applied to micro services as well. If  there is explosion of services leads into communication chaos, that is not going to be cool.   

  • Simple interface over simple implementation
  • Ensure protect information as needed, you may be leaking in more ways than you can see.
  • Use composition over implementation inheritance when possible.Inheritance, while it seem logical , makes it hard for class explosion and make it difficult, designing elegant composition for code re-use is always a better option. 
  • If logic needs it, let the class be bigger.  Artificial slicing is not always the best thing.


4. Layered issues

  • Each layer should provide a different abstraction, if there are multiple layers with similar functionality or one is a shallow layer on top of other , then it is a red signal. Pass through layers are bad unless a cases like   dispatcher.
  • Avoid meaningless decorators. Even Java has overrated decorated issues like BufferedInputStream, you always need to initialize input stream and then BufferedInputStream


5. Exceptions

Often we push too much into exceptions, we mishandle errors that we may not see in normal conditions, we may consume and don't do anything or write too much of exception code than the actual business logic. It just means one thing. You need to design well. Make your design address possible conditions into logic instead of letting  critical decisions happening at development time. 


  • Define errors out of existence. Best way to deal with exception conditions is to avoid by addressing the conditions and adding validations as necessary.
  • Exceptions are Exceptions and should not be treated as common logic.
  • If you think the caller will handle the error, you are not just sinking but bringing the caller down as well. 
  • Design for errors.

6. Comments

  • DRY, Do not repeat what code is doing and saying.  
  • Comments at Interface level should not talking about implementation details.
  • Explain what and why and not "How".
  • Comments should bring intuition, lower level or higher level.  Comments are not for translation of code into english line by line.
  • Write comments as part of the design.

7. Naming

  • Follow naming that is not confusing.
  • Follow same convention everywhere.
  • If it is hard to name something (method or variable) it means it is not designed right. Get back to design.

8. Design

  • Design multiple, your first design may not be the best. 
  • Do not get into biased design.  
  • Review design with others and get critical review.  Remember code or design, it is not fool proof because Mr/Mrs X has done it.  
  • Design level fixes save countless number of hours and people from suffering in the future.
  • When using TDD, make sure you design good upfront, do not get into tunnel vision of just fixing code.

9. Legacy code

  • Do not use tactical programming approach, just in time code to fix the issue as you understood may cause more issues than it solves.
  • Always leave the code better than you found it

10. Consistency

  • If you are working on a legacy source code and you feel like you want to bring better design and implement part of the code into something different.  It may do more harm than good.   Consistency is a mandatory thing. 
  • Variable naming, method naming, indentation , Commenting style and even spacing etc need to be consistent. In some remote case, your code may follow some unconventional and not recommended approach and as long as it is uniform across, it brings order and validity to the code.


Comments

Popular posts from this blog

The Mumbai trip

Indiatoday book club lottery - a 419 cheating

Friends Forever