Design Principles:
Design principles are fundamental guidelines that help developers create well-structured, maintainable, and flexible software systems. Following these principles ensures that the codebase is scalable, robust, and easier to understand and modify. Four essential design principles are discussed below:
Interface Segregation Principle (ISP)
The Interface Segregation Principle states that clients should not be forced to depend on interfaces they do not use. In simpler terms, it suggests that a class should not be burdened with implementing methods that are irrelevant to its intended functionality.
Example: Suppose we have an interface called Vehicle
with methods startEngine()
, accelerate()
, stopEngine()
, and refuel()
. In an ISP-violating scenario, a class representing an electric car must implement the refuel()
method, which is irrelevant to electric vehicles since they do not require traditional refueling. To adhere to ISP, the Vehicle
interface can be segregated into smaller interfaces, like EnginePoweredVehicle
and FuelPoweredVehicle
, which are then implemented by relevant classes.
Advantages: By adhering to ISP, we achieve higher cohesion and lower coupling in our code. Classes become more focused on their specific responsibilities, making the codebase easier to maintain, extend, and refactor. This principle also encourages better code organization and improves overall code readability.
Dependency Inversion Principle (DIP)
The Dependency Inversion Principle suggests that high-level modules should not depend on low-level modules. Instead, both should depend on abstractions (interfaces or abstract classes). Additionally, abstractions should not depend on details; details should depend on abstractions.
Example: Consider a scenario where a Customer
class directly depends on a CustomerRepository
class for database access. In a DIP-compliant design, we would introduce an interface ICustomerRepository
, which both the Customer
class and the CustomerRepository
class would depend on. The Customer
class will interact with the ICustomerRepository
interface, allowing for easier swapping of different repository implementations without modifying the Customer
class.
DRY (Don't Repeat Yourself)
DRY is a software development principle that advocates avoiding code duplication by abstracting common functionalities into reusable components. DRY promotes code reusability and reduces the chances of inconsistencies and bugs caused by redundant code.
Example for DRY (Don't Repeat Yourself):
Suppose you are building a web application that requires data validation for user inputs in multiple forms. Instead of writing separate validation codes for each form, you can follow the DRY principle by creating a reusable validation function or class.
KISS (Keep It Simple, Stupid)
The KISS principle suggests that simplicity should be a key goal in software design. Simple solutions are easier to understand, maintain, and extend than complex ones. KISS encourages avoiding unnecessary complexity, convoluted code structures, or over-engineering.
Example for KISS (Keep It Simple, Stupid):
Let's consider a scenario where you need to implement a function to calculate the average of a list of numbers. The straightforward and simple approach is to iterate through the list and calculate the sum and then divide by the number of elements.
The second implementation follows the KISS principle by using the built-in sum
function to calculate the sum of the numbers in the list and directly dividing by the length of the list to calculate the average. This approach is simpler, more concise, and easier to understand compared to the first implementation.
By adopting the KISS principle, you can avoid unnecessary complexities in your code, resulting in more maintainable and efficient solutions. Keeping the code simple also reduces the chance of introducing bugs and makes it easier for other developers to understand and collaborate on the project.
By incorporating these design principles (ISP, DIP) and development principles (DRY, KISS) into our software design process, we can create more reliable, maintainable, and scalable applications. Adhering to these principles enhances code quality and ensures that the software remains adaptable and resilient to future changes.
Assessment: https://www.bosscoderacademy.com/blog/lld-3-assessment