DEV Community

vinaykumar0339
vinaykumar0339

Posted on • Edited on

#1 Single Responsibility Principle ['S' in SOLID]

SRP - Single Responsibility Principle
The Single Responsibility Principle is the first principle in the Solid Design Principles.

  1. A class should have only one reason to change.
  2. Each class should focus on a single job or responsibility.

Violating SRP:

class BankAccount { var accountNumber: String var balance: Double init(accountNumber: String, balance: Double) { self.accountNumber = accountNumber self.balance = balance } func deposit(amount: Double) { balance += amount print("Deposited \(amount). New balance is \(balance)") } func withDraw(amount: Double) { if (balance >= amount) { balance -= amount print("Withdrew \(amount). New balance is \(balance)") } else { print("Handling the insufficient balance.") } } func printStatement() { print("Account Statement for \(accountNumber): Balance is \(balance)") } func notifyUser() { print("Notifying user of transaction for account \(accountNumber)") } } // Usage print("Before Applying SRP:") let bankAccount = BankAccount(accountNumber: "BANK123", balance: 1000) bankAccount.deposit(amount: 100) bankAccount.withDraw(amount: 500) bankAccount.withDraw(amount: 3000) bankAccount.printStatement() bankAccount.notifyUser() 
Enter fullscreen mode Exit fullscreen mode

Adhering to SRP
To adhere to SRP, separate the responsibilities into different classes:

class BankAccountWithSRP { var accountNumber: String var balance: Double init(accountNumber: String, balance: Double) { self.accountNumber = accountNumber self.balance = balance } func deposit(amount: Double) { balance += amount print("Deposited \(amount). New balance is \(balance)") } func withDraw(amount: Double) { if (balance >= amount) { balance -= amount print("Withdrew \(amount). New balance is \(balance)") } else { print("Handling the insufficient balance.") } } } class StatementPrinter { func printStatement(for account: BankAccountWithSRP) { print("Account Statement for \(account.accountNumber): Balance is \(account.balance)") } } class NotificationService { func notifyUser(for account: BankAccountWithSRP) { print("Notifying user of transaction for account \(account.accountNumber)") } } // Usage print("\n\nAfter Applying SRP:") let bankAccountSRP = BankAccountWithSRP(accountNumber: "BANK123", balance: 1000) bankAccountSRP.deposit(amount: 500) bankAccountSRP.withDraw(amount: 700) bankAccountSRP.withDraw(amount: 3000) let statementPrinter = StatementPrinter() let notificationService = NotificationService() statementPrinter.printStatement(for: bankAccountSRP) notificationService.notifyUser(for: bankAccountSRP) 
Enter fullscreen mode Exit fullscreen mode

Benefits of Adhering to SRP:

  1. Improved Readability:

    • Each class has a clear and focused responsibility, making the code easier to understand.
  2. Enhanced Maintainability:

    • Changes to statement printing or notification logic do not affect the BankAccount class.
  3. Increased Reusability:

    • The StatementPrinter and NotificationService classes can be reused independently in other application parts.
  4. Simplified Testing:

    • Each class can be tested independently, making unit testing more straightforward.

Drawbacks:

  1. More Classes:
    • Can lead to many small classes.
  2. Complex Dependency Management:
    • More dependencies to manage.
  3. Design and Refactoring Overhead:
    • Requires more effort to design and refactor.
  4. Risk of Over-Engineering:
    • Can make simple problems overly complex.
  5. Performance Considerations:
    • More object creation and method calls.

Mitigating Drawbacks:

  1. Balanced Approach:
    • Apply SRP judiciously.
  2. Effective Documentation:
    • Clear Documentation helps navigate the codebase.
  3. Use Patterns and Frameworks:
    • Design patterns and dependency management tools can help.
  4. Team Alignment:
    • Ensure the team has a shared understanding of SRP.
  5. Performance Profiling:
    • Profile and optimize performance as needed.

Conclusion:
By understanding and applying the Single Responsibility Principle thoughtfully, you can create more maintainable, understandable, and flexible software.

Open/Close Principle
Check My GitHub Swift Playground Repo.

Top comments (0)