Post Details

SOLID Principles in C Sharp .Net with Examples - Dot Net | Real-World Examples and Best Practices using C Sharp .Net ? | what are SOLID Principle

np

Fri , Aug 04 2023

np

To understand SOLID Principles in easy language, i want to share this article in easy to understand language, i hope this will help you in understanding Solid Priciples Quickly:

SOLID principles are a set of design principles for object-oriented programming or any software which requires clean and scalable system, Solid principle aims to make software more maintainable, extensible, and testable.

SOLID stands for

  • Single-responsibility principle: A class should have only one reason to change and only one responsibility.
  • Open-closed principle: A class should be open for extension but closed for modification. This means that new functionality can be added to a class without changing its existing code.
  • Liskov substitution principle: This principle says that if you have a class that inherits from another class, you should be able to use objects of the subclass wherever objects of the superclass are expected, without causing any problems. In other words, the subclass should behave like the superclass in all cases. This makes it easier to write code that works with different types of objects without having to worry about their specific implementation details.

  • Interface segregation principle: The Interface Segregation Principle (ISP) is a principle of object-oriented design that states that no object should be forced to depend on methods it does not use. In other words, an interface should be designed in such a way that it only includes methods that are relevant to the objects that use it. This makes the interface more focused and easier to understand, and it also makes it less likely that changes to one part of the system will affect other parts of the system.

    For example, let’s say you have an interface called IAnimal that has two methods: Walk() and Fly(). If you have a class called Dog that implements IAnimal, it will be forced to implement both Walk() and Fly(), even though dogs cannot fly. This violates the ISP because the Dog class is forced to depend on a method it does not use. A better design would be to split the IAnimal interface into two separate interfaces: IWalkable and IFlyable. Then, the Dog class can implement only the IWalkable interface, and other classes that can fly can implement the IFlyable interface. This way, each object depends only on the methods it needs, and changes to one part of the system will not affect other parts of the system.

  • Dependency inversion principle: This principle says that high-level modules should not depend on low-level modules. Instead, both should depend on abstractions. This means that you should define interfaces or abstract classes for your low-level modules, and have your high-level modules depend on these abstractions instead of the concrete implementations. This makes it easier to change the implementation of your low-level modules without affecting your high-level modules.

    To illustrate these principles, let’s take an example of a simple calculator application that can perform basic arithmetic operations. Here is a possible design of the calculator using SOLID principles:


    // An interface for arithmetic operations

    public interface IOperation

    {

        double Calculate(double x, double y);

    }


    // A class that implements the addition operation

    public class AddOperation : IOperation

    {

        public double Calculate(double x, double y)

        {

            return x + y;

        }

    }


    // A class that implements the subtraction operation

    public class SubtractOperation : IOperation

    {

        public double Calculate(double x, double y)

        {

            return x - y;

        }

    }


    // A class that implements the multiplication operation

    public class MultiplyOperation : IOperation

    {

        public double Calculate(double x, double y)

        {

            return x * y;

        }

    }


    // A class that implements the division operation

    public class DivideOperation : IOperation

    {

        public double Calculate(double x, double y)

        {

            if (y == 0)

            {

                throw new DivideByZeroException();

            }

            return x / y;

        }

    }


    // A class that performs the calculation using an operation

    public class Calculator

    {

        private readonly IOperation _operation;


        // The constructor takes an operation as a parameter and assigns it to the field

        public Calculator(IOperation operation)

        {

            _operation = operation;

        }


        // The method takes two numbers as parameters and returns the result of the operation

        public double Execute(double x, double y)

        {

            return _operation.Calculate(x, y);

        }

    }

    This design follows the SOLID principles in the following ways:

    • Each operation class has only one responsibility: to perform a specific calculation. This follows the single-responsibility principle.
    • The calculator class is open for extension but closed for modification. If we want to add a new operation, we can simply create a new class that implements the IOperation interface and pass it to the calculator constructor. We do not need to change the existing code of the calculator or the other operations. This follows the open-closed principle.
    • The operation classes can be substituted for each other without affecting the functionality of the calculator. The calculator does not care about the concrete implementation of the operation, it only cares about the abstraction defined by the IOperation interface. This follows the Liskov substitution principle.
    • The IOperation interface is small and specific. It only defines one method that is relevant for arithmetic operations. It does not include any unrelated methods that might be needed by other types of operations. This follows the interface segregation principle.
    • The calculator class depends on an abstraction rather than a concretion. It does not depend on any specific operation class, but on the IOperation interface. This makes the calculator more flexible and decoupled from the low-level details of the operations. This follows the dependency inversion principle.

    I hope this example helps you to understand how SOLID principles can improve your software design, To read more about similar kind of articles, Please Register with LifeDB.in and get latest update about all articles.

    Leave a Reply

    Please log in to Comment On this post.