Practice
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Frontend UI Machine Coding
Resources
Career Advice and Roadmaps
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Backend Development
Frontend Development
Project Ideas for Software Developers
Core Computer Science
Companies
SDE Jobs & Internships
Interview Questions
Compare Companies
IDE
Online IDE
Collaborative IDE

Software Design Principles | Abstraction, Extensibility, Cohesion

Gaurav Chandak
Gaurav Chandak

Clean Code and Design Principles Complete Guide

  • Introduction to Clean Code and Software Design Principles
  • Writing Meaningful Variable Names
  • Designing Good Functions and Classes
  • Software Design Principles - I (DRY, YAGNI, KISS, etc)
  • Software Design Principles - II (Abstraction, Extensibility, Cohesion)
  • Software Design Principles - III (SOLID Principles)

We can write clean code by following a set of guidelines known as Software Design Principles. Software Design Principles is a set of guidelines proven to work over the years.

I've listed down some of the most popular and useful design principles. You should try to enforce them in your code with every iteration.

This is the second part of the Software Design Principles Series.

Hide Implementation Details

Hiding implementation details helps to make changes in a component without making changes in the other modules/clients using that component. This can be achieved by creating interfaces and using them instead of the concrete classes.

Encapsulation with proper access management should also be done to expose only the required public functions.

Separation of Concerns

Separation of concerns (SoC) is a design principle for separating a computer program into distinct sections such that each section addresses a separate concern.

A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by creating well-encapsulated classes that have well-defined interfaces.

We should strive to separate the program into separate sections such that the overlap is as minimal as possible. SoC helps maintenance and also code reuse.

Maximize Cohesion

Cohesion is the degree to how strongly related and focused are the various responsibilities of a module. It is a measure of the strength of the relationship between the class’s methods and data themselves. We should strive to maximize cohesion. High cohesion results in better understanding, maintaining, and reusing components.

Cohesion is increased if:

  • The functionalities embedded in a class, accessed through its methods, have much in common.
  • Methods carry out a small number of related activities, by avoiding coarsely grained or unrelated sets of data.
  • Related methods are in the same source file or otherwise grouped together; for example, in separate files but in the same sub-directory/folder.

Minimize Coupling

Coupling is the degree to which each module depends on other modules; a measure of how closely connected two modules are. We should strive to minimize coupling.

Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion and vice versa.

Tightly coupled modules have the following disadvantages:

  • Change in one module might break another module.
  • Change in one module usually forces a ripple effect of changes in other modules.
  • Reusability decreases as dependency over other modules increases.
  • Assembly of modules might require more effort and/or time.

Coupling can be reduced by:

  • By hiding inner details and interacting through interfaces.
  • Avoid interacting with classes that it can avoid directly dealing with.

Components in a loosely coupled system can be replaced with alternative implementations that provide the same services.

Law of Demeter/Principle of Least Knowledge

Code components should only talk to its direct relations and not to strangers. 

The Law of Demeter for functions requires that a method m of an object a may only invoke the methods of the following kinds of objects:

  • a itself;
  • m's parameters;
  • any objects instantiated within m;
  • a's attributes;
  • global variables accessible by a in the scope of m.

In particular, an object should avoid invoking methods of an object returned by another method. For many modern object-oriented languages that use a dot as a field identifier, the law can be stated simply as "use only one dot". That is, the code a.m().n() breaks the law where a.m() does not. As an analogy, when one wants a dog to walk, one does not command the dog's legs to walk directly; instead one commands the dog which then commands its own legs.

Command-Query Separation

Command-Query Separation (CQS) states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer.

Query: Returns a result without changing the state. Command: Changes the state but does not return any value.

This way the query method could be used anywhere without changing the data/state. We should apply naming conventions (get, set, add, etc.) to imply whether it is a command or a query.

References:

  • Extreme Programming
  • martinfowler.com
  • Wikipedia

---

Read next

  • Software Design Principles - III (SOLID Principles)
2
Gaurav Chandak
Gaurav Chandak
Gaurav is the co-founder of workat.tech and has previously worked at Flipkart and Microsoft. He intends to actively contribute to the future of education through workat.tech.
Related Content
Introduction to Clean Code and Software Design Principles
How to Write Meaningful Variable Names? | Writing Clean Code
How to Design Good Functions and Classes | Writing Clean Code
Software Design Principles (Basics) | DRY, YAGNI, KISS, etc
SOLID Design Principles | Software Design Principles | Uncle Bob
Machine Coding Round Practice Questions for Interviews | Flipkart, Uber, Swiggy, Udaan, Gojek
SDE Bootcamp - Become a software engineer at a product-based company
Practice Machine Coding
Learning Resources
Interview Prep Resources
Blog
  • Career Advice and Roadmaps
  • Data Structures & Algorithms
  • Machine Coding Round (LLD)
  • System Design & Architecture
  • Backend Development
  • Frontend Development
  • Awesome Project Ideas
  • Core Computer Science
Practice Questions
  • Machine Coding (LLD) Questions
  • System Design (HLD) Questions
  • Topic-wise DSA Questions
  • Company-wise DSA Questions
  • DSA Sheets (Curated Lists)
  • JavaScript Interview Questions
  • Frontend UI Machine Coding Questions
Online Compilers (IDE)
  • Online Java Compiler
  • Online C++ Compiler
  • Online C Compiler
  • Online Python Compiler
  • Online JavaScript Compiler
Topic-wise Problems
  • Dynamic Programming Interview Questions
  • Linked List Interview Questions
  • Graph Interview Questions
  • Backtracking Interview Questions
  • Arrays Interview Questions
  • Trees Interview Questions
Company-wise Problems
  • Amazon Interview Questions
  • Microsoft Interview Questions
  • Google Interview Questions
  • Flipkart Interview Questions
  • Adobe Interview Questions
  • Facebook Interview Questions
DSA Sheets (Curated Lists)
  • Top Interview Questions
  • FAANG Interview Questions
  • Most Asked Interview Questions
  • 6 month DSA Practice Sheet
  • 3 month DSA Practice Sheet
  • Last minute DSA Practice Sheet