SlideShare a Scribd company logo
Essential	
  OO	
  Best	
  Practices	
  	
  
1. Provide a consistent and intuitive class interface.
!Clients of the class should only need to know how to use a class and should not be forced to know how it provides
the functionality. To achieve this, a class should provide a consistent interface that there is no ambiguity in using the
class interface; it should also be intuitive to understand to avoid mistakes by the clients.
!2. Provide common properties of classes in a base class.
!The common properties of various classes should be identified and should be provided in a common base class
(which can be an abstract class, concrete class, or interface). Providing methods in the base class interface is the
basis of runtime polymorphism; it also avoids code duplication and unnecessary downcasts.
!3. Do not expose implementation details in the public interface of the class.
!The public interface is meant for external users. If the class interface exposes only implementation details of the
class, it violates the rules of class abstraction; also any changes to internal details of the class can affect the interface
of the class, which is highly undesirable.
!4. Consider providing helper classes while designing large classes.
!Consider separating the logical parts of the implementation detail or functionality from larger class and provide
them as smaller helper classes. Also, when a small helper class is meaningful only in a limited context, and is used
by a single class, prefer making that class as an inner/nested class of the class that uses it.
!5. Keep the data members private.
!Every object has an identity, state and behaviour. For objects, name and type provides identity, data members
provide state and methods provide behaviour. Data members (that is, the state of the object) are considered as an
implementation detail; so it is better to keep them private and expose only methods (that is, behaviour) as methods
are preferable to be part of the public interface of a class.
!6. Provide lowest possible access to methods.
!Providing minimal access to the members of a class promotes encapsulation by hiding implementation details. By
providing lowest possible access to the class members, the class is more cohesive and more decoupled from other
classes; the internal implementation can also be more easily changed if the limited access is provided to the
members.
!7. Strive for loose coupling between classes.
!Classes should either be independent of other classes or should use only the public interface of other classes. Strive
for such loose coupling between classes because such classes are easy to understand, use, maintain and modify.
!8. Beware of order of initialization problems.
!Many subtle problems can happen because of order of initialization issues. Avoid code that depends on particular
order of implementation as provided by the compiler or the implementation.
!9. Write unit tests for classes.
!An application that is built using various classes can be expected to work fine only if it is ensured that the classes
work fine in isolation. Write unit tests to ensure robust implementation of individual classes.
!10. Avoid low-level code.
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  
!Using low-level code is convenient for many situations, such as making use of legacy code, accessing platform
specific features, efficiency etc. However, low-level code compromises portability, hampers software maintenance
and reuse, and makes the application unsafe and un-secure. So, avoid writing or using low-level code.
!11. Avoid calling virtual functions of the same class from constructors.
!Constructors do not support runtime polymorphism fully as the derived objects are not constructed yet when base
class constructor executes. So, avoid calling virtual functions from base-class constructors, which might result in
subtle bugs in the code.
!12. Consider providing factory methods.
!Factory methods have many advantages over constructors. Depending on the situation, consider providing factory
methods instead of constructors or in addition to existing constructors.
!13. Make constructor private if there are only static members in the class.
!When there are only static members in the class, there is no need to instantiate it; enforce this by making the default
constructor of that class private.
!14. Avoid creating unnecessary temporary objects.
!Programming in object oriented way tends to introduce lots of temporary objects. To a large extent, programmers
can consciously avoid creating such temporary objects. The techniques that can be used to avoid such temporary
object creation are mostly language specific as languages differ on the ways and situations in which temporary
objects are created.
!15. Prefer creating immutable objects.
!Immutable objects help us in avoiding bugs because of modifying the state, when it shouldn’t be done. Immutable
objects have many advantages over the usual mutable objects, so it is recommended to use immutable objects
whenever possible.
!16. Consider creating and using null objects.
!Providing sanity checks to avoid null pointer access or special casing the code to check for null condition can be
avoided for container/utility classes by creating and using null objects.
!17. Provide special objects with read only access in the class itself.
!Consider providing specific special objects that are often required by the application readily in the class itself as
read-only static fields. There is no need to create new objects of such special objects provided in the class and those
objects can be used all over in the application safely.
!18. Overload functions only if it is intuitive and unambiguous to the users.
!Function overloading should improve the readability of the code and make the programming convenient. If the users
find the overloading ambiguous or unintuitive, then it is not recommended to overload the functions.
!19. Overload functions only if the functions do semantically the same thing.
The methods that are semantically same should have syntactically same name, so use overloading; methods that
differ semantically should have syntactically different names, so provide descriptive names.
!20. Overload operators only if it is natural and improves the readability of code.
!Operator overloading is meant for convenience in using user defined types like primitive types and it is also meant
for improving the readability of the code. Overload operators only if the meaning of the operator is evident, un-
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  
ambiguous, natural, and intuitive for a given user-defined type; otherwise it will adversely affect the readability of
the code.
!21. Overload symmetrical operators or family of operators together.
!When overloading an operator, if there are any related operators, overload those operators also.
!22. Do not use inheritance when structure and behaviour are same for related classes.
!Often beginners make the mistake of using inheritance relationship to model relationship of classes that differ in
some value, when the class structure and behaviour remain the same. The correct solution is to keep that value as a
data member in a class.
!23. Prefer object composition over inheritance.
!In many cases, inheritance and composition can provide equivalent functionality. Class inheritance is white-box
reuse whereas object composition is black-box reuse. Since object composition is a better reuse model than class
inheritance, favour composition over inheritance.
!24. Avoid inheriting from multiple classes.
!Understanding, supporting and using multiple inheritance to solve design problems can be complicated. The
situations in which multiple inheritance is required are less-common and it is possible to arrive at equivalent
solutions with single class inheritance itself. It is better to avoid using multiple inheritance.
!25. Prohibit inheriting from a standalone class if the class is not meant for inheritance.
!It is a good practice to make stand-alone utility classes as non-inheritable if the classes are not designed with
inheritance in mind.
!26. Consider making concrete leaf classes non-inheritable.
!Base classes (or root classes) are designed having inheritance in mind for providing a common interface to the
inheritance hierarchy whereas concrete (or leaf classes) are written for providing implementation and hence not for
inheritance or for providing an interface. It is a well-known practice to consider making base classes abstract, but it
is also equally important to consider making leaf classes as non-inheritable.
!27. Write code referring to generic interfaces of classes.
!Keep generality in mind and write the code for interfaces, rather than specific implementations; in this way, the code
becomes extensible. In specific, when there is an abstract class or an interface available in a class hierarchy, prefer
writing code in terms of referring to that interface instead of using any of the concrete classes directly in the code.
!28. Beware of versioning problems in evolving base classes.
!Evolving base classes can introduce versioning problems: Later versions of a base class might end up inadvertently
overriding a method in the derived class in the client, which will result in breaking the client code. Beware of
possible versioning problems in evolving base classes and avoid introducing virtual methods in later versions of
base classes.
!29. Avoid deep inheritance hierarchies.
!It might be sometimes convenient to develop deep inheritance hierarchies. However, it is very difficult to
understand, use, maintain and test classes in such hierarchies, so creating such deep inheritance hierarchies should
be avoided.
!30. Consider making common base classes as abstract classes.
!
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  
The abstract classes and interfaces help us to think about design in conceptual terms rather than worrying about
implementation details. Instead of thoughtlessly mapping the application requirements into concrete classes to get
the work done, it is better to spend time in finding the common properties in the concrete classes and map them into
a abstract base class design and create reusable, extensible and flexible software.
!31. Use abstract classes for modelling abstract properties and sub-classing.
!Sub-classing refers to reusing interface and the implementation of a class; use abstract classes for modelling sub-
classing. For related classes, provide the common functionality in an abstract base class and provide different
implementations in separate concrete classes inheriting from it.
!32. Provide default implementation class(es) with abstract classes or interfaces.
!Abstractions have their own place in object oriented analysis and design. But without concrete classes, abstract
classes or interfaces are not of much use. If you’re providing abstract classes or interfaces, ensure that you are
providing at least one default implementation to make use of the abstract class or interface.
!33. Use interfaces for sub-typing and multiple inheritance.
!Sub-typing refers to reusing only the interface of a class; use interfaces for modelling sub-typing. Use pure interface
classes to bind unrelated classes for some common functionality. Also prefer interfaces for supporting multiple
inheritance.
!34. Consider providing adaptor classes for interfaces.
!Concrete classes that implement interfaces should provide the implementation of 'all' the methods, which is
inconvenient in many situations. Provide adaptor classes for such interfaces providing the default implementation
for the methods; this is for convenience as those adaptor classes will be easier to use.
!35. Keep in mind that interfaces are difficult to evolve.
!Pure class interfaces are difficult to evolve: Once clients have started using a pure interface class by implementing it,
it is not possible to add or delete method declarations or make any modifications to the old method signatures; any
such changes will break the client code. So strive for designing interfaces with an emphasis on establishing stability
in the contract it provides.
!36. Use virtual functions instead of chained if-else or switch statements.
!Programmers from structured programming background tend to use extensive use of control structures. Whenever
you find cascading if-else statements or switch statements checking for types or attributes of different types to take
actions, consider using inheritance by replacing the if-else or switch code with virtual method calls.
!37. Follow Liskov’s Substitution Principle (LSP).
!Follow Liskov’s Substitution Principle (LSP), which is one of the cardinal rules to follow in object oriented
programming.
!38. Avoid using reflection extensively.
!Reflection is a powerful feature, but using reflection exposes internal details of the classes. So, using reflection
should be strictly avoided for solving high-level programming problems; it should be used only when knowing
internal details of the classes at runtime is required.
!39. Prefer using higher-level language features instead of reflection.
!For most of the higher-level design problems, it is possible to provide acceptable solutions without using reflection.
So, prefer using virtual functions or some other language features to achieve the same functionality instead of using
reflection.
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  
!40. Avoid using RTTI extensively.
!Other than safe uses such as performing downcasts and event-driven programming, RTTI should not be used for
solving higher-level programming problems. Extensive use of RTTI when not necessary indicates that the design is
bad and the implementation is brittle and un-maintainable.
!41. Prefer using virtual functions instead of RTTI.
!Extensive use of RTTI can potentially make maintaining the code difficult. Whenever you find cascading if-else
statements for matching particular types to take actions, consider redesigning it by using virtual functions instead.
!42. Use namespaces for avoiding name-clashes and organizing the software.
!The techniques and approaches used for programming in large are considerably different from programming in
small. One of the major objectives in programming in large is to support modular software and avoid name-clashes
and versioning problems. By using namespaces effectively, programmers can create logical modules (set of related
class) facilitating software distribution and maintenance.
!43. Hierarchically partition the namespace.
!One of the major benefits that object orientation provides is the ability to write reusable classes that can be used for
wide range of projects instead of just providing code that will solve the specific needs. One of the widely used ways
to organize such reusable software is in the form of class libraries that are organized (or partitioned) in a hierarchical
format. Namespaces can be effectively used to provide a hierarchical organization of the software.
!44. Selectively introduce only the specific namespace members you need to the code.
!In general, it is a good programming practice to selectively introduce the names from a namespace to the code. This
will avoid name-clashes that happen because of introducing all the members of namespace to the code. This will
also avoid breaking the programs because of independent additions in the original namespace/package.
!45. Selectively expose the types to the clients.
!Namespaces play an important role in organizing software. One of the important ways in which namespaces help in
organizing the software is to provide control to the programmers on the classes that are exposed to the clients. A
programmer should use namespaces for providing public access, limited access or hiding the names in the
application to the clients.
!46. Avoid hiding of names in different scopes.
!Hiding of names in different scopes is unintuitive to the readers of the code and using name hiding extensively can
affect the readability of the program. Though hiding of names is a convenient feature, it is recommended to avoid
name hiding as it can result in subtle defects and unexpected problems.
!47. Strive for eliminating all forms of code duplication.
!Code duplication is unnecessary and it can create major maintenance problems. There is no reason for any form of
duplication of code and alternative approaches and solutions should be used for eliminating code duplication.
!48. Use design patterns whenever appropriate.
!Many of the problems in large-scale programming happen because of tight coupling between various software
components. Design patterns reduce dependencies between the components; so, use them appropriately to create
more flexible and reusable software.
!49. Provide frameworks for effective reuse of architectural design.
!
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  
Frameworks can be very useful in providing solutions in specific application domains. Since frameworks support
higher level architectural design reuse, it is preferable to provide frameworks or consider reusing existing
frameworks.
!50. Provide class libraries for any set of related reusable classes.
!Instead of providing specific solution to the given problem, consciously identify reusable components and provide it
as a class library.
!
©2006-­‐2014.	
  All	
  rights	
  reserved.	
  Ganesh	
  Samarthyam.	
  
Based	
  on	
  "60	
  Tips	
  on	
  Object	
  Oriented	
  Programming",	
  Tata	
  McGraw-­‐Hill,	
  2006. 	
  

More Related Content

PPTX
Java ocjp level_2
PDF
Pocket java
PDF
Reoprt on indutrial training
PDF
Advance Java - 2nd Unit
PDF
Java J2EE by Fairline
PDF
JAVA Training in Bangalore
PPT
Bartlesville Dot Net User Group Design Patterns
PDF
Budget Travel: Kualalumpur with Kids
Java ocjp level_2
Pocket java
Reoprt on indutrial training
Advance Java - 2nd Unit
Java J2EE by Fairline
JAVA Training in Bangalore
Bartlesville Dot Net User Group Design Patterns
Budget Travel: Kualalumpur with Kids

Viewers also liked (11)

PDF
Writing an Abstract - Template (for research papers)
PDF
Refactoring guided by design principles driven by technical debt
PDF
MIDAS: A Design Quality Assessment Method for Industrial Software
PPTX
Introduction to Continuous Delivery (BBWorld/DevCon 2013)
PDF
Let's Go: Introduction to Google's Go Programming Language
PDF
Micro Anti-patterns in Java Code
PDF
Refactoring for Software Architecture Smells - International Workshop on Refa...
PPTX
Continuous delivery applied (RJUG)
PDF
Continuous Delivery at Netflix, and beyond
PPTX
Zero to the Cloud with @NetflixOSS
PDF
Bangalore Container Conference 2017 - Poster
Writing an Abstract - Template (for research papers)
Refactoring guided by design principles driven by technical debt
MIDAS: A Design Quality Assessment Method for Industrial Software
Introduction to Continuous Delivery (BBWorld/DevCon 2013)
Let's Go: Introduction to Google's Go Programming Language
Micro Anti-patterns in Java Code
Refactoring for Software Architecture Smells - International Workshop on Refa...
Continuous delivery applied (RJUG)
Continuous Delivery at Netflix, and beyond
Zero to the Cloud with @NetflixOSS
Bangalore Container Conference 2017 - Poster
Ad

Similar to Object Oriented Best Practices - Summary (20)

PDF
Android interview questions
PDF
Android interview questions
PPTX
Class Members Access/Visibility Guide (Checklist)
PDF
20 most important java programming interview questions
DOC
PPTX
Template pattern
PPTX
Effective Java - Chapter 4: Classes and Interfaces
PDF
‏‏‏‏‏‏oop lecture 6_١٢٥٩٤٧taiz univercity.pdf
PDF
When & Why: Interfaces, abstract classes, traits
DOCX
Core java questions
PDF
PPTX
Object-oriented programming 3.pptx
PDF
Solid principles, Design Patterns, and Domain Driven Design
PPTX
what is differance between abstract class and interface ppt
DOCX
C# interview quesions
DOC
MC0078 SMU 2013 Fall session
DOCX
PDF
Domain Driven Design Thoughts Mat Holroyd
PDF
Core_Java_Interview.pdf
PDF
What is Interface in Java | How to implement Multiple Inheritance Using Inter...
Android interview questions
Android interview questions
Class Members Access/Visibility Guide (Checklist)
20 most important java programming interview questions
Template pattern
Effective Java - Chapter 4: Classes and Interfaces
‏‏‏‏‏‏oop lecture 6_١٢٥٩٤٧taiz univercity.pdf
When & Why: Interfaces, abstract classes, traits
Core java questions
Object-oriented programming 3.pptx
Solid principles, Design Patterns, and Domain Driven Design
what is differance between abstract class and interface ppt
C# interview quesions
MC0078 SMU 2013 Fall session
Domain Driven Design Thoughts Mat Holroyd
Core_Java_Interview.pdf
What is Interface in Java | How to implement Multiple Inheritance Using Inter...
Ad

More from Ganesh Samarthyam (20)

PDF
Wonders of the Sea
PDF
Animals - for kids
PDF
Applying Refactoring Tools in Practice
PDF
CFP - 1st Workshop on “AI Meets Blockchain”
PDF
Great Coding Skills Aren't Enough
PDF
College Project - Java Disassembler - Description
PDF
Coding Guidelines - Crafting Clean Code
PDF
Design Patterns - Compiler Case Study - Hands-on Examples
PDF
Bangalore Container Conference 2017 - Brief Presentation
PDF
Software Design in Practice (with Java examples)
PDF
OO Design and Design Patterns in C++
PDF
Bangalore Container Conference 2017 - Sponsorship Deck
PPT
Google's Go Programming Language - Introduction
PDF
Java Generics - Quiz Questions
PDF
Java Generics - by Example
PDF
Software Architecture - Quiz Questions
PDF
Docker by Example - Quiz
PDF
Core Java: Best practices and bytecodes quiz
PDF
Advanced Debugging Using Java Bytecodes
PDF
Java Class Design
Wonders of the Sea
Animals - for kids
Applying Refactoring Tools in Practice
CFP - 1st Workshop on “AI Meets Blockchain”
Great Coding Skills Aren't Enough
College Project - Java Disassembler - Description
Coding Guidelines - Crafting Clean Code
Design Patterns - Compiler Case Study - Hands-on Examples
Bangalore Container Conference 2017 - Brief Presentation
Software Design in Practice (with Java examples)
OO Design and Design Patterns in C++
Bangalore Container Conference 2017 - Sponsorship Deck
Google's Go Programming Language - Introduction
Java Generics - Quiz Questions
Java Generics - by Example
Software Architecture - Quiz Questions
Docker by Example - Quiz
Core Java: Best practices and bytecodes quiz
Advanced Debugging Using Java Bytecodes
Java Class Design

Recently uploaded (20)

PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
medical staffing services at VALiNTRY
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
Essential Infomation Tech presentation.pptx
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
ai tools demonstartion for schools and inter college
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
medical staffing services at VALiNTRY
wealthsignaloriginal-com-DS-text-... (1).pdf
Which alternative to Crystal Reports is best for small or large businesses.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
How Creative Agencies Leverage Project Management Software.pdf
PTS Company Brochure 2025 (1).pdf.......
Navsoft: AI-Powered Business Solutions & Custom Software Development
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Design an Analysis of Algorithms II-SECS-1021-03
Essential Infomation Tech presentation.pptx
How to Migrate SBCGlobal Email to Yahoo Easily
ai tools demonstartion for schools and inter college
Reimagine Home Health with the Power of Agentic AI​
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Operating system designcfffgfgggggggvggggggggg
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...

Object Oriented Best Practices - Summary

  • 1. Essential  OO  Best  Practices     1. Provide a consistent and intuitive class interface. !Clients of the class should only need to know how to use a class and should not be forced to know how it provides the functionality. To achieve this, a class should provide a consistent interface that there is no ambiguity in using the class interface; it should also be intuitive to understand to avoid mistakes by the clients. !2. Provide common properties of classes in a base class. !The common properties of various classes should be identified and should be provided in a common base class (which can be an abstract class, concrete class, or interface). Providing methods in the base class interface is the basis of runtime polymorphism; it also avoids code duplication and unnecessary downcasts. !3. Do not expose implementation details in the public interface of the class. !The public interface is meant for external users. If the class interface exposes only implementation details of the class, it violates the rules of class abstraction; also any changes to internal details of the class can affect the interface of the class, which is highly undesirable. !4. Consider providing helper classes while designing large classes. !Consider separating the logical parts of the implementation detail or functionality from larger class and provide them as smaller helper classes. Also, when a small helper class is meaningful only in a limited context, and is used by a single class, prefer making that class as an inner/nested class of the class that uses it. !5. Keep the data members private. !Every object has an identity, state and behaviour. For objects, name and type provides identity, data members provide state and methods provide behaviour. Data members (that is, the state of the object) are considered as an implementation detail; so it is better to keep them private and expose only methods (that is, behaviour) as methods are preferable to be part of the public interface of a class. !6. Provide lowest possible access to methods. !Providing minimal access to the members of a class promotes encapsulation by hiding implementation details. By providing lowest possible access to the class members, the class is more cohesive and more decoupled from other classes; the internal implementation can also be more easily changed if the limited access is provided to the members. !7. Strive for loose coupling between classes. !Classes should either be independent of other classes or should use only the public interface of other classes. Strive for such loose coupling between classes because such classes are easy to understand, use, maintain and modify. !8. Beware of order of initialization problems. !Many subtle problems can happen because of order of initialization issues. Avoid code that depends on particular order of implementation as provided by the compiler or the implementation. !9. Write unit tests for classes. !An application that is built using various classes can be expected to work fine only if it is ensured that the classes work fine in isolation. Write unit tests to ensure robust implementation of individual classes. !10. Avoid low-level code. ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.  
  • 2. !Using low-level code is convenient for many situations, such as making use of legacy code, accessing platform specific features, efficiency etc. However, low-level code compromises portability, hampers software maintenance and reuse, and makes the application unsafe and un-secure. So, avoid writing or using low-level code. !11. Avoid calling virtual functions of the same class from constructors. !Constructors do not support runtime polymorphism fully as the derived objects are not constructed yet when base class constructor executes. So, avoid calling virtual functions from base-class constructors, which might result in subtle bugs in the code. !12. Consider providing factory methods. !Factory methods have many advantages over constructors. Depending on the situation, consider providing factory methods instead of constructors or in addition to existing constructors. !13. Make constructor private if there are only static members in the class. !When there are only static members in the class, there is no need to instantiate it; enforce this by making the default constructor of that class private. !14. Avoid creating unnecessary temporary objects. !Programming in object oriented way tends to introduce lots of temporary objects. To a large extent, programmers can consciously avoid creating such temporary objects. The techniques that can be used to avoid such temporary object creation are mostly language specific as languages differ on the ways and situations in which temporary objects are created. !15. Prefer creating immutable objects. !Immutable objects help us in avoiding bugs because of modifying the state, when it shouldn’t be done. Immutable objects have many advantages over the usual mutable objects, so it is recommended to use immutable objects whenever possible. !16. Consider creating and using null objects. !Providing sanity checks to avoid null pointer access or special casing the code to check for null condition can be avoided for container/utility classes by creating and using null objects. !17. Provide special objects with read only access in the class itself. !Consider providing specific special objects that are often required by the application readily in the class itself as read-only static fields. There is no need to create new objects of such special objects provided in the class and those objects can be used all over in the application safely. !18. Overload functions only if it is intuitive and unambiguous to the users. !Function overloading should improve the readability of the code and make the programming convenient. If the users find the overloading ambiguous or unintuitive, then it is not recommended to overload the functions. !19. Overload functions only if the functions do semantically the same thing. The methods that are semantically same should have syntactically same name, so use overloading; methods that differ semantically should have syntactically different names, so provide descriptive names. !20. Overload operators only if it is natural and improves the readability of code. !Operator overloading is meant for convenience in using user defined types like primitive types and it is also meant for improving the readability of the code. Overload operators only if the meaning of the operator is evident, un- ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.  
  • 3. ambiguous, natural, and intuitive for a given user-defined type; otherwise it will adversely affect the readability of the code. !21. Overload symmetrical operators or family of operators together. !When overloading an operator, if there are any related operators, overload those operators also. !22. Do not use inheritance when structure and behaviour are same for related classes. !Often beginners make the mistake of using inheritance relationship to model relationship of classes that differ in some value, when the class structure and behaviour remain the same. The correct solution is to keep that value as a data member in a class. !23. Prefer object composition over inheritance. !In many cases, inheritance and composition can provide equivalent functionality. Class inheritance is white-box reuse whereas object composition is black-box reuse. Since object composition is a better reuse model than class inheritance, favour composition over inheritance. !24. Avoid inheriting from multiple classes. !Understanding, supporting and using multiple inheritance to solve design problems can be complicated. The situations in which multiple inheritance is required are less-common and it is possible to arrive at equivalent solutions with single class inheritance itself. It is better to avoid using multiple inheritance. !25. Prohibit inheriting from a standalone class if the class is not meant for inheritance. !It is a good practice to make stand-alone utility classes as non-inheritable if the classes are not designed with inheritance in mind. !26. Consider making concrete leaf classes non-inheritable. !Base classes (or root classes) are designed having inheritance in mind for providing a common interface to the inheritance hierarchy whereas concrete (or leaf classes) are written for providing implementation and hence not for inheritance or for providing an interface. It is a well-known practice to consider making base classes abstract, but it is also equally important to consider making leaf classes as non-inheritable. !27. Write code referring to generic interfaces of classes. !Keep generality in mind and write the code for interfaces, rather than specific implementations; in this way, the code becomes extensible. In specific, when there is an abstract class or an interface available in a class hierarchy, prefer writing code in terms of referring to that interface instead of using any of the concrete classes directly in the code. !28. Beware of versioning problems in evolving base classes. !Evolving base classes can introduce versioning problems: Later versions of a base class might end up inadvertently overriding a method in the derived class in the client, which will result in breaking the client code. Beware of possible versioning problems in evolving base classes and avoid introducing virtual methods in later versions of base classes. !29. Avoid deep inheritance hierarchies. !It might be sometimes convenient to develop deep inheritance hierarchies. However, it is very difficult to understand, use, maintain and test classes in such hierarchies, so creating such deep inheritance hierarchies should be avoided. !30. Consider making common base classes as abstract classes. ! ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.  
  • 4. The abstract classes and interfaces help us to think about design in conceptual terms rather than worrying about implementation details. Instead of thoughtlessly mapping the application requirements into concrete classes to get the work done, it is better to spend time in finding the common properties in the concrete classes and map them into a abstract base class design and create reusable, extensible and flexible software. !31. Use abstract classes for modelling abstract properties and sub-classing. !Sub-classing refers to reusing interface and the implementation of a class; use abstract classes for modelling sub- classing. For related classes, provide the common functionality in an abstract base class and provide different implementations in separate concrete classes inheriting from it. !32. Provide default implementation class(es) with abstract classes or interfaces. !Abstractions have their own place in object oriented analysis and design. But without concrete classes, abstract classes or interfaces are not of much use. If you’re providing abstract classes or interfaces, ensure that you are providing at least one default implementation to make use of the abstract class or interface. !33. Use interfaces for sub-typing and multiple inheritance. !Sub-typing refers to reusing only the interface of a class; use interfaces for modelling sub-typing. Use pure interface classes to bind unrelated classes for some common functionality. Also prefer interfaces for supporting multiple inheritance. !34. Consider providing adaptor classes for interfaces. !Concrete classes that implement interfaces should provide the implementation of 'all' the methods, which is inconvenient in many situations. Provide adaptor classes for such interfaces providing the default implementation for the methods; this is for convenience as those adaptor classes will be easier to use. !35. Keep in mind that interfaces are difficult to evolve. !Pure class interfaces are difficult to evolve: Once clients have started using a pure interface class by implementing it, it is not possible to add or delete method declarations or make any modifications to the old method signatures; any such changes will break the client code. So strive for designing interfaces with an emphasis on establishing stability in the contract it provides. !36. Use virtual functions instead of chained if-else or switch statements. !Programmers from structured programming background tend to use extensive use of control structures. Whenever you find cascading if-else statements or switch statements checking for types or attributes of different types to take actions, consider using inheritance by replacing the if-else or switch code with virtual method calls. !37. Follow Liskov’s Substitution Principle (LSP). !Follow Liskov’s Substitution Principle (LSP), which is one of the cardinal rules to follow in object oriented programming. !38. Avoid using reflection extensively. !Reflection is a powerful feature, but using reflection exposes internal details of the classes. So, using reflection should be strictly avoided for solving high-level programming problems; it should be used only when knowing internal details of the classes at runtime is required. !39. Prefer using higher-level language features instead of reflection. !For most of the higher-level design problems, it is possible to provide acceptable solutions without using reflection. So, prefer using virtual functions or some other language features to achieve the same functionality instead of using reflection. ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.  
  • 5. !40. Avoid using RTTI extensively. !Other than safe uses such as performing downcasts and event-driven programming, RTTI should not be used for solving higher-level programming problems. Extensive use of RTTI when not necessary indicates that the design is bad and the implementation is brittle and un-maintainable. !41. Prefer using virtual functions instead of RTTI. !Extensive use of RTTI can potentially make maintaining the code difficult. Whenever you find cascading if-else statements for matching particular types to take actions, consider redesigning it by using virtual functions instead. !42. Use namespaces for avoiding name-clashes and organizing the software. !The techniques and approaches used for programming in large are considerably different from programming in small. One of the major objectives in programming in large is to support modular software and avoid name-clashes and versioning problems. By using namespaces effectively, programmers can create logical modules (set of related class) facilitating software distribution and maintenance. !43. Hierarchically partition the namespace. !One of the major benefits that object orientation provides is the ability to write reusable classes that can be used for wide range of projects instead of just providing code that will solve the specific needs. One of the widely used ways to organize such reusable software is in the form of class libraries that are organized (or partitioned) in a hierarchical format. Namespaces can be effectively used to provide a hierarchical organization of the software. !44. Selectively introduce only the specific namespace members you need to the code. !In general, it is a good programming practice to selectively introduce the names from a namespace to the code. This will avoid name-clashes that happen because of introducing all the members of namespace to the code. This will also avoid breaking the programs because of independent additions in the original namespace/package. !45. Selectively expose the types to the clients. !Namespaces play an important role in organizing software. One of the important ways in which namespaces help in organizing the software is to provide control to the programmers on the classes that are exposed to the clients. A programmer should use namespaces for providing public access, limited access or hiding the names in the application to the clients. !46. Avoid hiding of names in different scopes. !Hiding of names in different scopes is unintuitive to the readers of the code and using name hiding extensively can affect the readability of the program. Though hiding of names is a convenient feature, it is recommended to avoid name hiding as it can result in subtle defects and unexpected problems. !47. Strive for eliminating all forms of code duplication. !Code duplication is unnecessary and it can create major maintenance problems. There is no reason for any form of duplication of code and alternative approaches and solutions should be used for eliminating code duplication. !48. Use design patterns whenever appropriate. !Many of the problems in large-scale programming happen because of tight coupling between various software components. Design patterns reduce dependencies between the components; so, use them appropriately to create more flexible and reusable software. !49. Provide frameworks for effective reuse of architectural design. ! ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.  
  • 6. Frameworks can be very useful in providing solutions in specific application domains. Since frameworks support higher level architectural design reuse, it is preferable to provide frameworks or consider reusing existing frameworks. !50. Provide class libraries for any set of related reusable classes. !Instead of providing specific solution to the given problem, consciously identify reusable components and provide it as a class library. ! ©2006-­‐2014.  All  rights  reserved.  Ganesh  Samarthyam.   Based  on  "60  Tips  on  Object  Oriented  Programming",  Tata  McGraw-­‐Hill,  2006.