Created by Stan on 18-04-2023
The Single Responsibility Principle (SRP) is one of the five principles of object-oriented programming and design known as SOLID. SRP states that a class should have only one reason to change, meaning it should have only one responsibility. Adhering to the Single Responsibility Principle leads to a more maintainable, flexible, and modular codebase. In this article, we will explore the SRP and demonstrate its application in Ruby.
The SRP revolves around the idea that a class should focus on a single task or responsibility. By limiting a class to a single concern, you can create a codebase that is easier to understand, maintain, and modify. When a class has multiple responsibilities, changes in one area of functionality might inadvertently affect other areas, leading to unintended consequences and increased complexity.
Let's illustrate the Single Responsibility Principle using a Ruby example. Imagine we have a system that sends notifications to users through various channels like email and SMS.
We can use the mail
gem for sending emails and the twilio-ruby
gem for sending SMS messages. First, you'll need to install these gems:
gem install mail twilio-ruby
Here's an initial implementation without considering the SRP:
require 'mail' require 'twilio-ruby' class NotificationSender def initialize(user, message) @user = user @message = message end def send_email(from_email) Mail.deliver do from @from_email to user.email subject 'Notification' body message end end def send_sms(account_sid, auth_token, from_phone_number) client = Twilio::REST::Client.new(account_sid, auth_token) client.messages.create( from: from_phone_number, to: @user.phone_number, body: @message ) end end
The problem with this implementation is that the NotificationSender
class has multiple responsibilities, handling both email and SMS notifications. This violates the Single Responsibility Principle.
To refactor this code and adhere to the SRP, we can separate the notification logic into different classes:
class NotificationSender def initialize(user, message, notifier) @user = user @message = message @notifier = notifier end def send_notification @notifier.send(@user, @message) end end
require 'mail' class EmailNotifier def initialize(from_email) @from_email = from_email end def send(user, message) Mail.deliver do from @from_email to user.email subject 'Notification' body message end end end
require 'twilio-ruby' class SmsNotifier def initialize(account_sid, auth_token, from_phone_number) @client = Twilio::REST::Client.new(account_sid, auth_token) @from_phone_number = from_phone_number end def send(user, message) @client.messages.create( from: @from_phone_number, to: user.phone_number, body: message ) end end
Now, each class has a single responsibility: NotificationSender
is responsible for managing notifications, EmailNotifier
is responsible for sending email notifications, and SmsNotifier
is responsible for sending SMS notifications.
This refactored code adheres to the Single Responsibility Principle, as each class focuses on a single task.
Now you can use the NotificationSender
class to send notifications through different channels:
user = OpenStruct.new(email: '[email protected]', phone_number: '+1234567890') message = 'Hello, this is a notification.' email_notifier = EmailNotifier.new('[email protected]') sms_notifier = SmsNotifier.new('<your_twilio_account_sid>', '<your_twilio_auth_token>', '<your_twilio_phone_number>') notification_sender = NotificationSender.new(user, message, email_notifier) notification_sender.send_notification notification_sender = NotificationSender.new(user, message, sms_notifier) notification_sender.send_notification
The example code above demonstrates how to use the NotificationSender
class and the specific notifier instances to send notifications through email and SMS. Note that this is a basic implementation, and you may need to adjust the code depending on your specific requirements.
Coding
Posted on 07 Apr, 2023Coding
Posted on 07 Apr, 2023Coding
Posted on 07 Apr, 2023