Solid principles: 1. Single responsibility principle

Sławomir Kowalski
5 min readApr 30, 2018

The principle of single responsibility says that each class should be responsible for one specific thing, there should be only one reason to modify the class.

This is the most important SOLID principle, thanks to it we will not have classes of monsters after 2000 lines, which will be responsible for everything, but we will have many small classes responsible for different parts of the program.

Large classes are always harder to maintain, develop and refactorize, building large classes always sooner or later leads to problems such that if our project will be a class and will be responsible for everything in the future expansion of this class, changing its functionality will also affect completely different areas of this class, which in large projects leads to the fact that they are simply impossible to expand and modify.

However, by creating many small classes, you increase readability, ease of expansion and, generally speaking, ease of managing the project code.

Let’s move to practical examples, an example of a class that breaks the principle of a single responsibility is the one given in the introduction:

class Products
{
public List<string> ProductsInBag { get; set; }
public int NumberProductsInShop { get; set; }
public int NumberClientsInShop { get; set; }
public List<string> TypesProductsInBag { get; set; }
public int NumberOrders { get; set; }
public string FirstNameClient { get; set; }
public string LastNameClient { get; set; }
public string ZipCodeClient { get; set; }
public int NumberProductsInBag { get; set; }
public int NumberDrinksInBag { get; set; }
public int NumberCandysInBag { get; set; }
public double PriceAllProductsInBag { get; set; }

public Products(int numberproductsinShop)
{
NumberProductsInShop = numberproductsinShop;
}

public void IfClientWentToShop()
{
NumberClientsInShop += 1;
}

public string AddProduct(double priceproduct, string product, string typeproduct)
{
ProductsInBag.Add(product);
if (TypesProductsInBag.Contains(typeproduct))
{
Console.WriteLine("This type of product is already in the cart!");
}
else
{
TypesProductsInBag.Add(typeproduct);
}

if (typeproduct == "candys")
{
NumberCandysInBag += 1;
}
else if (typeproduct=="drink")
{
NumberDrinksInBag += 1;
}

PriceAllProductsInBag += priceproduct;
return product;
}

public string GiveOrders(string firstnameclient, string lastnameclient, string zipcodeclient)
{
NumberOrders += 1;
FirstNameClient = firstnameclient;
LastNameClient = lastnameclient;
ZipCodeClient = zipcodeclient;

NumberProductsInBag = ProductsInBag.Count;

return "Order placed!";
}

public double BuyProducts(double mywallet)
{
return mywallet - PriceAllProductsInBag;
}
}

What we have here… Products class, which is responsible for everything, for placing orders, customers, calculating products, adding products, number of variables at the top of the class also does not look inviting, I forgot to mention that the single responsibility principle applies not only to classes, but also to methods, so that one or several methods do not do everything, you also have to try to do the shortest methods, preferably only perform one operation.

And we have here a few methods that do everything. If we were to make a practical project, we could not leave it that way, it should look like this:

namespace SingleResponsibility
{
class Product
{
public void PriceProduct(double price)
{
Console.WriteLine("This product costs: " + price);
}
}
class Client
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string ZipCode { get; set; }
private double _myWallet;
public double MyWallet { get => _myWallet; set => _myWallet = value; }
public Client(string firstname, string lastname, string zipcode, double myWallet)
{
FirstName= firstname;
LastName = lastname;
ZipCode = zipcode;
_myWallet = myWallet;
}
}
class Shop
{
public int NumberProducts { get; set; }
public int NumberClient { get; set; }
public Shop(int numberproducts)
{
NumberProducts = numberproducts;
}
public void NewClient()
{
NumberClient += 1;
}
}
class ClientCart
{
public List<string> Products { get; set; }
public List<string> TypesProducts { get; set; }
public int NumberProducts { get; set; }
public int NumberDrinks { get; set; }
public int NumberCandys { get; set; }
public double PriceAllProducts { get; set; }
public void SaveTypeProducts(string typeproduct)
{
if (TypesProducts.Contains(typeproduct))
{
Console.WriteLine("This type of product is already in the cart!");
}
else
{
TypesProducts.Add(typeproduct);
}
CheckTypeProducts(typeproduct);
}
private void CheckTypeProducts(string typeproduct)
{
if (typeproduct == "candys")
{
GetCandysCount();
}
else if (typeproduct == "drink")
{
GetDrinksCount();
}
}
private void GetCandysCount()
{
NumberCandys += 1;
}
private void GetDrinksCount()
{
NumberDrinks += 1;
}
public double SumProductsPrice(double priceproduct)
{
return PriceAllProducts += priceproduct;
}
public int GetProductsCount()
{
return NumberProducts = Products.Count;
}
public void AddProduct(string product)
{
Products.Add(product);
}
}
class Order
{
public int NumberOrder { get; set; }
public void AddOrder()
{
NumberOrder += 1;
}
public string GiveOrder()
{
return "Order placed!";
}
}
}

And whether it does not look better? We have specific classes and methods that are responsible for a specific part of the store’s logic, the code has become much more readable, easier to understand and modify, we also the names of classes and methods have been improved. Of course, you can probably improve something in every code, no matter how well it would be written, how easy it would be to read, if all the rules of programming were met, not only SOLID, you can always improve something.

But you will admit that this is a much better solution than the one in which the Single Responsibility principledoes not apply.

And below the call in the Main function:

namespace SingleResponsibility
{
class Program
{
static void Main(string[] args)
{
double MyWallet = 30;
Client client = new Client("Slawomir", "Kowalski", "81-198", MyWallet);
ClientCart clientCart = new ClientCart(); clientCart.Products = new List<string>();
clientCart.TypesProducts = new List<string>();
Shop shop = new Shop(100); shop.NewClient();
clientCart.AddProduct("cola");
clientCart.SaveTypeProducts("drink");
clientCart.SumProductsPrice(5.6);
clientCart.AddProduct("sprite");
clientCart.SaveTypeProducts("drink");
clientCart.SumProductsPrice(3.5);
clientCart.AddProduct("candy");
clientCart.SaveTypeProducts("candys");
clientCart.SumProductsPrice(1.4);
Order order = new Order(); Console.WriteLine(order.GiveOrder() +
"\nThe number of products in the cart: " + clientCart.GetProductsCount() +
"\nOrder placed by: " + client.FirstName + " " + client.LastName
+ "\nNumber of drinks in the cart: " + clientCart.NumberDrinks
+ "\nThe number of sweets in the cart: " + clientCart.NumberCandys
+ "\nPrice of all products: " + clientCart.PriceAllProducts);
Console.WriteLine("It's in my wallet: " + (client.MyWallet - clientCart.PriceAllProducts) + " PLN"); Console.ReadKey();
}
}
}

Result:

Summary

In the next lesson, as you probably guessing, there will be discuss SOLID principle, open-closed.

Link to github with the whole code from this article: https://github.com/Slaw145/SingleResponsibility

This content also you can find on my steemit blog https://steemit.com/solid/@slawas/solid-principles-1-single-responsibility-principle

And on my blog devman: http://devman.pl/programtech/solid-principles-1-single-responsibility-principle/

As a standard, I remind you about the newsletter, which I send notifications about new entries and additional information about the IT world in general.

And NECESSERILY join the DevmanCommunity community on fb, part of the community is in one place

– site on fb: Devman.pl-Sławomir Kowalski

– group on fb: DevmanCommunity

Ask, comment underneath at the end of the post, share it, rate it, whatever you want.

--

--