Solid Principles

Solid Principles

Solid Principles are the time tested principles for writing clean and high quality code in object oriented programming.

Why should you study SOLID Principles?

Studying the SOLID principles is essential for software developers because they provide a clear framework for designing software that's easy to maintain, scalable, and resilient against bugs. You will find a major difference in your code quality once you learn these principles as they are time tested.

The Open Closed Principle (OCP) states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. In other words, the behavior of a component should be extendable without modifying its source code.

Here is an example in pseudocode that demonstrates the Open Closed Principle:

```
class Shape {
function area() {
// Common logic for calculating area of a shape
}
}

class Rectangle extends Shape {
function area() {
// Specific logic for calculating area of a rectangle
}
}

class Circle extends Shape {
function area() {
// Specific logic for calculating area of a circle
}
}

// Client code
shapes = [new Rectangle(), new Circle()]
totalArea = 0

foreach shape in shapes {
totalArea += shape.area()
}

print totalArea
```

In the above pseudocode, we have a base `Shape` class with a generic `area()` function. It contains the common logic for calculating the area that can be used by any shape.

The `Rectangle` and `Circle` classes extend the `Shape` class and provide their own specific implementation of the `area()` function to calculate the areas of rectangles and circles, respectively.

The client code can create instances of any shape, add them to an array, and then iterate over each shape to calculate its area using the `area()` function. It does not need to modify the base `Shape` class or any existing shape classes to add new shapes or calculate their areas.

By adhering to the Open Closed Principle, we can easily add new shapes (e.g., `Triangle`, `Square`) without modifying the existing code, ensuring that the codebase remains extensible and maintainable.

Code Example

Without Open Closed Principle Principle


// Without Open/Closed Principle

function calculate_area(shapes_list):
    total_area = 0
    for shape in shapes_list:
        if shape.type == "circle":
            // Logic to calculate the area of a circle
            area = 3.14 * shape.radius * shape.radius
        elif shape.type == "square":
            // Logic to calculate the area of a square
            area = shape.side * shape.side
        // For any new shape, we'll have to come back and modify this function
        total_area += area
    return total_area

With Open Closed Principle Principle


// With Open/Closed Principle

// First, we declare an interface for our shapes to implement. Each shape will know how to calculate its own area.
interface Shape:
    function calculate_area()

class Circle implements Shape:
    // Constructor and other properties like radius...
    function calculate_area():
        return 3.14 * self.radius * self.radius

class Square implements Shape:
    // Constructor and other properties like side...
    function calculate_area():
        return self.side * self.side

// Any new shape can simply implement the Shape interface without the need to change existing code.

function calculate_total_area(shapes_list):
    total_area = 0
    for shape in shapes_list:
        // Now, the calculate_area method is part of the shape object, adhering to the Open/Closed Principle.
        total_area += shape.calculate_area()
    return total_area
The Open-Closed Principle (OCP) in software development suggests that classes should be open for extension but closed for modification. Here are the key points for implementing the OCP using pseudocode:

1. Define an abstract base class or interface that defines common behaviors or operations.

2. Create concrete subclasses that inherit from the base class or implement the interface.

3. Keep the original code untouched, without making any modifications.

4. When new functionality is needed, create a new subclass or implementation of the base class or interface.

5. Add a mechanism to dynamically choose the appropriate subclass or implementation based on requirements (e.g., factory pattern or dependency injection).

6. Utilize polymorphism to allow the use of the new subclass without modifying existing code.

Here's an example pseudocode implementation:

```
// Step 1: Define base class or interface
abstract class Shape {
abstract float area();
}

// Step 2: Create concrete subclasses
class Circle : Shape {
float radius;

Circle(float radius) {
this.radius = radius;
}

float area() {
return 3.14 * radius * radius;
}
}

class Rectangle : Shape {
float length;
float width;

Rectangle(float length, float width) {
this.length = length;
this.width = width;
}

float area() {
return length * width;
}
}

// Step 3: Original code remains untouched

// Step 4: Create new subclass
class Triangle : Shape {
float base;
float height;

Triangle(float base, float height) {
this.base = base;
this.height = height;
}

float area() {
return (base * height) / 2;
}
}

// Step 5: Choose appropriate subclass dynamically
Shape shape;
if (userInput == "circle") {
shape = new Circle(5);
} else if (userInput == "rectangle") {
shape = new Rectangle(4, 6);
} else if (userInput == "triangle") {
shape = new Triangle(3, 7);
}

// Step 6: Utilize polymorphism
float shapeArea = shape.area();
```

This example demonstrates the open-closed principle by allowing new shapes (e.g., Triangle) to be added without modifying the existing code, and by dynamically selecting the appropriate subclass based on user input.
Common mistakes when implementing the Open-Closed Principle in pseudocode can include the following:

1. Not defining clear and explicit interfaces: The Open-Closed Principle emphasizes creating well-defined interfaces to allow easy extension. Failing to define interfaces can make it difficult to extend and maintain code.

2. Violating the Single Responsibility Principle (SRP): Open-Closed Principle works closely with SRP. If a class has multiple responsibilities, it becomes harder to extend without modifying existing code. Ensure that each class has a single responsibility and only one reason to change.

3. Not using proper abstraction: Abstraction is crucial to the Open-Closed Principle. Failing to use appropriate abstractions can lead to tightly-coupled code, where changes in one class require modifications in multiple places.

4. Overcomplicating the design: Sometimes, developers tend to over-engineer and make code more complex than necessary to adhere to the Open-Closed Principle. Simplicity is key – strive for a design that solves the problem at hand without unnecessary complexity.

Best practices for implementing the Open-Closed Principle in pseudocode:

1. Identify areas likely to change: Analyze the requirements and identify areas that are prone to change so that you can encapsulate those areas in separate classes or interfaces.

2. Define clear and explicit interfaces: Use interfaces to define contracts that classes must adhere to. This allows you to easily extend functionality without modifying existing code.

3. Use inheritance or composition: Inheritance and composition are common ways to achieve the Open-Closed Principle. Inheritance allows classes to be extended through a subclass, while composition involves creating new classes that rely on existing ones.

4. Apply the dependency inversion principle (DIP): DIP suggests that high-level modules should depend on abstractions, not on concrete implementations, to facilitate extensions. Inject dependencies through interfaces to achieve loose coupling.

5. Use polymorphism: Polymorphism allows different classes to provide different behaviors while adhering to a common interface. Leveraging this can make your code open for extension but closed for modification.

6. Test your implementation: Ensure you have proper unit tests in place to validate that the Open-Closed Principle is being followed. This will help identify any violations or deviations.

7. Refactor when necessary: As requirements change, regularly review your code and refactor if needed to ensure compliance with the Open-Closed Principle. This helps maintain a clean and maintainable codebase.

SolidPrinciples is a website dedicated to SOLID Principles. We want to ensure developers really the understand SOLID Principles and understand how to apply them in their code. It is both beginner and intermediate level friendly.

SolidPrinciples

SolidPrinciples © 2024 All rights reserved.

email
email
email