0% found this document useful (0 votes)
5 views

SOLID Principles

Uploaded by

Prajwal Machado
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

SOLID Principles

Uploaded by

Prajwal Machado
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

SOLID Design Principles

By - Mohit Tripathi
SOLID Principles
The SOLID Principles are five principles of Object-Oriented class design. They are a set of rules
and best practices to follow while designing a class structure.

S - The Single Responsibility Principle


O - The Open Closed Principle
L - The LisKov Substitution Principle
I - The Interface Segregation Principle
D - The Dependency Inversion Principle
Background
The SOLID principles were first introduced by the famous Computer Scientist Robert J. Martin (a.k.a
Uncle Bob) in his paper in 2000. But the SOLID acronym was introduced later by Michael Feathers.
Uncle Bob is also the author of bestselling books Clean Code and Clean Architecture, and is one
of the participants of the "Agile Alliance".
Therefore, it is not a surprise that all these concepts of clean coding, object-oriented architecture,
and design patterns are somehow connected and complementary to each other.

They all serve the same purpose:

"To create understandable, readable, and testable code that many developers can
collaboratively work on."
Single Responsibility Principle -
The Single Responsibility Principle states that a class should do one thing and therefore it should have
only a single reason to change.

you can apply the SRP by ensuring that a class or method has a single, well-defined responsibility.

Example -

public class AccountManager {


public void createNewAccount(Account account) {
// Logic for creating a new account in the database
}

public void sendEmailNotification(Account account, String message) {


// Logic for sending email notifications
}
}
To adhere to the SRP, you should split the responsibilities into separate classes. For example:

public class AccountManager {


public void createNewAccount(Account account) {
// Logic for creating a new account in the database
}
}

public class EmailNotifier {


public void sendEmailNotification(Account account, String message) {
// Logic for sending email notifications
}
}

But there are still few grey areas as with apex most of the time we will have situations where a
class will have multiple methods so will that be violation of SRP?
Is it a class level principle or it is applied to methods as well?
Answers -

The Single Responsibility Principle (SRP) primarily focuses on class-level responsibilities, but it also
applies to method-level responsibilities to some extent.

At the class level, SRP suggests that a class should have one and only one reason to change. In
other words, a class should have a single, well-defined responsibility or concern. This means that
the class should encapsulate all the data and methods necessary to fulfil that responsibility. If a
class tries to do too much and has multiple responsibilities, it can become difficult to maintain and
understand.

The SRP is primarily concerned with ensuring that a class or module has one reason to change. If
your class has multiple methods, each handling a separate responsibility, and these responsibilities
are related to the overall purpose of the class, then it doesn't violate SRP.
In other words, SRP is not about having a class with only one method; it's about organising your
code in a way that each class and method has a clear, well-defined role or responsibility, and
that those responsibilities are logically related to the purpose of the class.
The Open Closed Principle -
The Open-Closed Principle (OCP) is one of the SOLID principles of object-oriented design, and it states
that software entities (such as classes, modules, and functions) should be open for extension but closed
for modification. In other words, you should be able to add new functionality to a module without altering
its existing code.

Example -

Let's say you have a class that calculates the total cost of an order with different types of items.

public class OrderCalculator {


public Decimal calculateTotalCost(List<OrderItem> items) {
Decimal totalCost = 0;
for (OrderItem item : items) {
totalCost = TotalCost + Item.Price__c;
}
return totalCost;
}
}
Now Let’s say you want to introduce a new item type called ‘Special Offer’.

You have 2 option now-


First , you can edit the existing class and introduce a new if else logic statement to offer special
discount for this new ‘Special offer’. As you are modifying existing class, it will be a violation of Open
Closed Principle.
Second, you can create another class and extend the base class for normal discount like this-

public class SpecialOfferOrderCalculator extends OrderCalculator {


public Decimal calculateTotalCost(List<OrderItem> items) {
Decimal totalCost = 0;
for (OrderItem item : items) {
if (item.getType() == 'SpecialOffer') {
totalCost += item.price__c * 0.5; // Apply a 50% discount for special offers
} else {
totalCost += super.calculateTotalCost(new List<OrderItem>{item});
}
}
return totalCost;
}
}
Question-
how it is different that creating all together a new class for discounted opportunities, what advantage
does it bring?

The Main Advantage of adhering to the open-closed principle by creating a subclass for
extended functionality is when you expect that further extensions or different types of
functionality might be added in the future.

In real-world scenarios, the choice between directly modifying a class and creating a subclass for
extensions depends on the specific context, requirements, and anticipated changes. If you don't
expect future extensions or if the extension is relatively simple, it may be reasonable to add the
functionality directly to the base class. However, for more complex or potentially varied
extensions, adhering to the Open-Closed Principle can lead to a more maintainable and flexible
codebase over time.
Liskov Substitution Principle -
The principle in the simple terms says that all the subclasses of a super class should be able to
implement all the methods without an error occurring.

let’s say we have an Animal super class which have a method called Roar. Now we have our
subclasses for example Dog and Bear extending the super class Animal.Now we know that Dogs
don’t roar but Bears do, so we’ll have to throw an exception that Dogs can’t roar. So, in here you
have a sub class(Dog) that actually can’t use one of the method of Super class, then we have
violated the principle.
Interface Segregation Principle -
Segregation means keeping things separated, and the Interface Segregation Principle is about
separating the interfaces.

The principle states that many client-specific interfaces are better than one general-purpose
interface. Clients should not be forced to implement a function they do no need.
Dependency Inversion Principle -
The Dependency Inversion Principle (DIP) is one of the SOLID principles of object-oriented programming,
which promotes loose coupling between software modules.

In the context of Salesforce, you can apply the Dependency Inversion Principle to make your code
more flexible and maintainable. Here's a simple example:

Let's say you have a Salesforce Apex class that sends email notifications to customers when a new
opportunity is created. You might initially write the code like this:

public class OpportunityService {


public void createOpportunity(Opportunity newOpportunity) {
// Create the opportunity
// Send email notifications to customers
}
}

In this example, the OpportunityService class has a high-level module that directly depends on a low-level
module for sending email notifications. This is not in accordance with the Dependency Inversion
Principle.
To adhere to the Dependency Inversion Principle, you can introduce an interface or abstract class to define the contract for
sending notifications, and then inject this dependency into the OpportunityService:

public interface NotificationService {


void sendNotification(String message, String recipient);
}

public class EmailNotificationService implements NotificationService {


public void sendNotification(String message, String recipient) {
// Send email notification
}
}

public class OpportunityService {


private NotificationService notificationService;

public OpportunityService(NotificationService notificationService) {


this.notificationService = notificationService;
}

public void createOpportunity(Opportunity newOpportunity) {


// Create the opportunity
// Use the injected notificationService to send notifications
notificationService.sendNotification("New opportunity created", newOpportunity.CustomerEmail__c);
}
}
Ask me Anything ????
Want to Reach out to me ??
 Linkdin - https://www.linkedin.com/in/mtripathi347/
 YouTube - https://www.youtube.com/@Mtripathi347
 Topmate - https://topmate.io/mohit_tripathi10
 Website - https://bit.ly/3JLKd3V

Thank you

You might also like