A 'SOLID' Foundation: Single Responsibility Principle In Swift


By Shantaram Kokate

Software development process is never straightforward. It’s a maze, to say the least. One that’s ridden with challenges such as:

  1. A class having lot of things and responsibilities, which ultimately leads to not being able to understand the code flow. Then, the only way to understand the code would be to debug it. This becomes a time consuming process.
  2. If a future change or a bug fix is to be made, one will have to make a change in the class which processes it. When a change is made in the class, it might sometimes not work and these changes might affect other functionality.
  3. Due to some factors, systems that were developed by a previous team may not be available. Sometimes, project documentation could be out of sync or non-existent. These factors too, influence the maintainability of the system.

The SOLID principles, intended to make a software more flexible and understandable, were introduced by Uncle Bob.

Single-responsibility Principle
Open-closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle

In this blog, we’ll tackle the first challenge, with the first principle above. Let’s see how Single Responsibility Principles can be applied in Swift.

Reducing the Massive App Delegate

A Massive App Delegate has a lot of responsibilities:

  1. Set initial ViewController
  2. Initialise core data or databases
  3. Initialise analytics
  4. Initialise push notifications
  5. Initialise third party library
  6. Handle background operation
  7. Initialise tracking log

… and it goes on!

A massive number of responsibilities make it difficult to change, expand, and test.

In the above class, it has more than one role and there are multiple reasons for changing the class. So, if a class has more than one role, and if a role is changed, the other roles that the class plays may also be affected — resulting in problems.

Solution

‘SOLID’ principles and command design pattern play a crucial role in building a robust system where:

  • Each class and module focus on a single task at a time
  • Everything in class should be related to a single purpose
  • Single responsibility principle classes become smaller and cleaner, and code becomes concise

For example:

Now, encapsulate all commands in AppDelegateCommandBuilder class:

This solution now ensures:

  • Each (entity) command has a single responsibility
  • It’s easy to add new commands without changing the AppDelegate code
  • Commands can be easily tested in isolation

Pros

  1. Class functionality can be easily extended
  2. Other functionalities aren’t affected
  3. The class will be smaller, hence easier to understand
  4. Easy to identify a problem and fix it on time
  5. If a new team is working on the code, it’s easier since it’s well organised.

Cons

  1. Each of the classes may have references to other classes as member fields or method parameters
  2. Separation of classes makes a relationship of classes more complex. This in turn might result in generation of classes that have too many references to other classes as members

If you have any questions or recommendations, feel free to post them in the comments. Or, you could get in touch with me directly, here: Medium, LinkedIn, Twitter.

References:

Clean Coder Blog, Single Responsibility Principle: A Recipe for Great Code, Command.

Click here to read more stories from the vault. Also, we’re hiring!