Question About how to implement the "small class" rule of SRP

Fred1511

New member
Joined
Nov 4, 2018
Messages
4
Programming Experience
10+
Hello,
I used to write big classes. And for few days, trying to be a better programmer, I am thinking and reading about design.
Considering SRP (Single Responsability Principle), Uncle Bob recommend tiny classes.
So, I began with my big class A (not the real name of course). As starter, considering that it dealt with hosting datas, UI, and IO, I cut the class A into 3 smaller class : A_datas, A_UI and A_IO.

But then I faced a problem : A_UI et A_IO need a read/write access to A_datas (most of) instances variables. For there is no « friend class » in c#, those variables need to be public (or there accessors).
And, having all my datas accessibles for anybody is a little bit disturbing for me.

I could use nested class (A_UI and A_IO into A_datas) but it doesn’t look like the good direction for they would all be too related.
I’m currently considering that having the instance variables of A_datas as public is may be not so dramatic.
Inside my own assembly, it is not dramatic because I can forbid access to A_datas from outside.
But if I work in a team and into the same assembly, it may be …

So, how do you deal with the "small classes" rule ?

Thank you in advance,
 
It's hard to say what the best solution is with so little information about the actual requirements and design but maybe you need another class to hold data that two or three of the other classes can all use. A specific design requires knowledge of specific requirements.
 
It's hard to say what the best solution is with so little information about the actual requirements and design but maybe you need another class to hold data that two or three of the other classes can all use. A specific design requires knowledge of specific requirements.

In fact, it was in purpose that I wasn't more specific for it is a very general question for me.
And the following article emphasis similar issue, talking about "encapsulation [which] has been destroyed by the need to make everything public in order for the class fragments to be able to communicate" (https://hackernoon.com/you-dont-understand-the-single-responsibility-principle-abfdd005b137)

By the way, the A_datas class is already hosting datas for A_UI and A_IO. Therefore almost all it's instance variables are public.
 
It seems like you already have the general principles if you have read that article so you don't need that from us. If you want specific advice on your specific scenario then we need specific details. I would agree with hat article that the SRP is not about performing a certain action. For instance a service class's single responsibility might be managing all aspects of retrieving and persisting a single entity. That would mean possibly multiple Get and Save methods and child entities may be involved in either direction. To separate such a class into one for each action would not be a good idea.
 
It seems like you already have the general principles if you have read that article so you don't need that from us. If you want specific advice on your specific scenario then we need specific details. I would agree with hat article that the SRP is not about performing a certain action. For instance a service class's single responsibility might be managing all aspects of retrieving and persisting a single entity. That would mean possibly multiple Get and Save methods and child entities may be involved in either direction. To separate such a class into one for each action would not be a good idea.

Thank you.
I will try to be more specific and quick.
It is a Form application. The unique class A_datas instance host few datas
namespace A_repository
{
public class A_datas
{
public string m_name;
public List<string> m_listOfStrings;
}
}

In the form code, I have some controls to display the datas and to add / remove string from m_listOfStrings.
But I don't want the form code to be able to modify directly the A_datas instance.
So I have an other class :
namespace A_repository
{
public class A_UI
{
public static A_datas m_repository = new A_datas();

public string GetName()
{​
return m_repository.m_Name;
}
public IList<string> GetListOfString()
{​
return m_repository.m_listOfStrings.AsReadOnly();
}

[...] other methods to modify m_repository
}

public class A_IO
{
[...] some methods to read/write into xml files using the reference A_UI.m_repository
}
}

So ... I need the instance A_UI.m_repository to be public, therefore the class A_IO can work with it.
But I would like to prevent the form code to use directly A_UI.m_repository and, as an exemple, call a A_UI.m_repository.m_listOfStrings.Clear();

After a day of thinking and tests, I found only 2 ways to achieve that :
  • use nested class which would host all A class (datas, UI and IO) and A_datas would be private.
  • use internal access specifier and put all class A (datas, UI and IO) in a differente project.

I hope those details will help.
 
In fact, so far, I have always been positively surprised by C# over C++.
And the issue I raised in this thread is the first disappointing thing about C#.
It is really disturbing to not control the access of his own datas (when you slice your big class into multiples tiny class).

But, considering that the guys who made C# are not stupid, I guess that I'm missing an important philosophical point.
 
Back
Top Bottom