S.O.L.I.D PRINCIPLES
S.O.L.I.D Principles

S.O.L.I.D PRINCIPLES

In software development world, where several technological innovations and advancements prosper each passing minute, no matter which latest technology is used, foundation pillars should always adhere to well-designed and architected software built by following set of design practices and principles. Otherwise such software will perish over a period of time, when necessary enhancements are to be done but software is not easily extensible to fulfil ever-growing business demands in a competitive marketplace, in as much less time as possible.

No alt text provided for this image

SOLID (developed by Robert C. Martin) is a collection of programming practices used across object-oriented design spectrum. The purpose of these principles is to make software designs more understandable, easier to maintain and easier to extend. It is a coding standard which states that all developers should have a clear concept for developing software to avoid bad design. When applied properly, it keeps code more extendable, logical and easier to read.

When a developer builds a software following bad design, code becomes inflexible and more brittle, small changes in software result in bugs.

Bugs..Bugs..Just Bugs

Though it takes good amount of time and discipline to understand but writing code by adhering to these principles improves code quality gradually and will help to build most well-designed and scalable software. SOLID is a conglomerate of below listed 5 coding practices:

  1. S: Single responsibility principle
  2. O: Open/close principle
  3. L: Liskov substitution principle
  4. I: Interface segregation principle
  5. D: Dependency inversion principle

Single responsibility principle

A class should have one, and only one responsibility/ reason to change.

All methods and properties of a class should be cohesive i.e. directly relate to its responsibility, by working towards a common goal. When a class serves multiple purposes/ responsibilities, it becomes really difficult to read, repair or to expand it, at which point it should be made into a new class. This principle is very noticeable in case of an application that begins to grow with time, with enriched functionalities added to already existing classes and their capabilities.

Single Responsibility Principle

Example:

Problem: Employee class has to fulfil 3 different sets of responsibilities, all mixed up within one class namely Calculation logic, Database logic, Reporting logic

No alt text provided for this image

When there are multiple responsibilities combined into one class, it becomes difficult to change one part without breaking others. Mixing responsibilities also makes the class harder to understand and test thereby decreasing cohesion.

Solution: Split class into 3 different classes, each fulfilling only one responsibility namely CalculatePay, SaveEmployee, DescribeEmployee.

Open/close principle

Software entities should be open for extension, but closed for modification.

Software entities (classes, modules, functions, etc.) should be extendable without actually changing contents of class being extended. If this principle is followed strongly enough, it is possible to then modify behaviour of code without ever touching the piece of original code. The application must be ready for extensions, as it has to continuously evolve based on the changes of external system.

Open Closed Principle

Example:

Problem: For below class, new payment method to support credit card support needs to be added.

No alt text provided for this image

Adding an “if” statement would the simplest solution, but it will enforce a change to existing class violating OCP.

No alt text provided for this image

Solution: Definer an interface PaymentMethod, create 2 implementation classes namely CashPayment, CreditPayment where each class will handle appropriate payment method. With this approach, when another payment method must be added say Overdraft; a new class can be created OverdraftPayment, to handle the specific logic without necessitating any change to existing classes.

No alt text provided for this image

Liskov substitution principle

This principle was coined by Barbar Liskov regarding data abstraction and type theory. It also derives from the concept of Design by Contract (DBC) by Bertrand Meyer. Barbara Liskov and Jeanette Wing formulated it succinctly in 1994 paper as follows.

Let φ(x) be a property provable about objects x of type T. Then φ(y) should be true for objects y of type S where S is a subtype of T.

 A derived class is substitutable for its base class if:

  1. Preconditions cannot be strengthened in a subtype.
  2.  Postconditions cannot be weakened in a subtype.
  3. Invariants of the super-type must be preserved in a subtype.

Robert Martin made definition sound more concisely in 1996 :

Functions that use pointers of references to base classes must be able to use objects of derived classes without knowing it.

Or simply : Subclass/derived class should be substitutable for their base/parent class.

Any implementation of an abstraction (interface) should be substitutable in any place, that the abstraction is accepted. While coding using interfaces, there is not only have a contract of input which interface receives but also the output returned by different classes implementing that interface; they should be of the same type. Functions that use pointers or references to base classes must also be able to use class objects that inherit from base classes, without having a thorough knowledge of these objects.

Liskov Substitution Principle

Example:

Problem: The Square class derives from a Rectangle class and always assumes that width is equal with height. If Square object is used in a context where Rectangle is expected, then unexpected behaviour may occur because dimensions of a Square cannot (or rather should not) be modified independently.

No alt text provided for this image

Solution: Modify setter methods in Square class to preserve Square invariant (i.e., keep dimensions equal).

No alt text provided for this image

Interface segregation principle

Clients should not be forced to implement unnecessary methods which they will not use.

Break interfaces in many smaller ones, so they better satisfy exact needs of clients. Avoid ripple effect and repetition by dividing software into multiple, independent parts. Do not add additional functionality to an existing interface by adding new methods, instead create new interface and let appropriate class implement multiple interfaces if needed i.e. Many dedicated interfaces are better than one overall. The interface should give a specific shape to class and methods that must be implemented within the class, should be common to all implementation classes.

Interface Segregation Principle

Example:

Problem: The interface Messenger has several methods, where each method fulfils different piece of functionality. Classes which implements Messengers interface are forced to implement all methods, though some of them are not even needed or unwanted and which would only be applicable to other Classes.

No alt text provided for this image

Solution: Split Messenger interface into multiple interfaces each having cohesive set of functionalities.

No alt text provided for this image

Dependency inversion principle

Depend on abstractions, not on concretions.

High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.

With Dependency Inversion, lower-level modules can be easily changed by other modules just changing the dependency module and High-level module will not be affected by any such changes. Usually by abstraction, we mean an abstract class or interface. Essentially, this means that we are introducing a certain abstraction, which allows us to exchange individual elements of the program with other ones more suitable for a specific task. We try not to enter into classes depending on its smaller parts.

Dependency Inversion Principle

Example:

Problem/Solution: A program depends on Reader and Writer interfaces that are abstractions and Keyboard and Printer are details that depend on those abstractions by implementing those interfaces. CharCopier is oblivious to low-level details of Reader and Writer implementations, once can pass in any Device that implements Reader and Writer interface and CharCopier would still work correctly.

No alt text provided for this image

YAGNI - You ain’t gonna need it YAGNI on Wiki

Don't create functionality unnecessarily until it is actually needed, to avoid having code which is not going to be used in any way.

DRY - Don’t repeat yourself DRY on Wiki

The code must always be analysed and improved. By having several classes with similar properties, not only creates confusion but gives rise to redundancy issues. This is a sign which indicates that the code is common and must be separated into another class, which will deal with repetitive tasks in one single place. All the classes will use the same piece of code and thus the probability of error will drop eventually.

KISS - Keep It Simple, Stupid! KISS on Wiki

This rule is often discussed with regard to architecture evaluation. Its essence lies in striving to maintain, an elegant and transparent structure, without adding unnecessary elements.

SOC - Separation of Concerns SOC on Wiki

Create a system in which each part plays a significant role while maintaining the possibility of maximum adaptation to changes. SoC does not refer only to system architecture, but to various issues, e.g. to divide the application into layers namely Presentation, Business logic, Access to data, Database etc. The functionality of the application is divided into separate modules that overlap with as little functionality as possible, giving rise to module program. Each element of the system should have its separate and singular application.

CQS - Command Query Separation CQS on Wiki

Every method in the system should be classified into one of two groups:

  • Command - Methods which change state of the application and do not return anything.
  • Query - Methods which return something, but do not change state of the application.

Keep SOLID Principles in Your Toolbox

SOLID principles are valuable tools in your toolbox which you should keep in the back of your mind, when designing next feature or application. 

SOLID Design Principles

References:

  1. https://web.archive.org/web/20150906155800/https://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf

要查看或添加评论,请登录

Khaja Shaik的更多文章

  • The Art of Mastery: Blend of Dedication<->Perfection<->Excellence

    The Art of Mastery: Blend of Dedication<->Perfection<->Excellence

    As individuals at work each of us take up complete ownership of assigned responsibility for productive and predictable…

    1 条评论
  • Design Patterns

    Design Patterns

    Reusable solution for common recurring problems in software design used in engineering, not ready/finished design which…

  • Leadership Is a Choice: Lead It --> Live It !

    Leadership Is a Choice: Lead It --> Live It !

    Life is a never ending journey of Learning, "Tell me and I forget. Teach me and I remember.

  • Dealing Uncertainty in Software Projects !

    Dealing Uncertainty in Software Projects !

    After having worked on several projects over the past years, can confidently mention that "100% certainty in software…

  • Embracing Age: Keep Going, Growing & Glowing !

    Embracing Age: Keep Going, Growing & Glowing !

    Once a year, I celebrate that I am alive, I am lucky enough to live, I have come as far as today on this beautiful day.…

  • 35 Programming Principles !

    35 Programming Principles !

    Day-in Day-out, the prime role of Developers is to craft clean-quality code which aids to solve a real-time problem of…

  • ???? ????? | Rise Above And Beyond Potential!

    ???? ????? | Rise Above And Beyond Potential!

    'Shano Varuna’ — is a Sanskrit verse taken from ‘Taittiriya Upanishad’, which means 'May god of oceans be auspicious…

    1 条评论
  • 10 Commandments for Employee Well-being

    10 Commandments for Employee Well-being

    Day-in and Day-out, we do stretch ourselves to ensure planned deliveries are met towards the sustenance of Business…

  • Concurrency vs Parallelism: 2 sides of same Coin ?? ??.

    Concurrency vs Parallelism: 2 sides of same Coin ?? ??.

    Preface At the point when PCs didn’t have working frameworks yet, they executed just one program at a time. The program…

  • Up for Rugby or Relay race ?. As a Team we WIN, As a Team we FAIL

    Up for Rugby or Relay race ?. As a Team we WIN, As a Team we FAIL

    On any given day, if someone asks you a question, whether you would like to be a part of Relay race or Rugby game, what…

社区洞察

其他会员也浏览了