I can't understand the Single Responsibility Principle)

In theory, everything is clear, but in practice there are always difficulties. They are related to the fact that it is not clear on what scale this "Single Duty"should be considered. Here I need to work with the database. If I create a class DataBaseInteracting can I assume that it will have one duty? But then it writes the data to the database and reads it from there and updates it. Maybe it's better to create 3 classes: DataBaseWriter, DataBaseReader and DataBaseUpdater?

Author: Kromster, 2015-11-26

4 answers

The principle of a single responsibility applies to almost any scale: method, class, module, subsystem, etc. When choosing a duty, as always, there must be some reasonableness. Moreover, it is sometimes possible to deviate from all the principles. This will come with experience.

In your example, I would say that there is no need to split the DataBaseInteracting class according to the actions. The duty of "ensuring data storage" is quite atomic, in my opinion, and it is not necessary to divide it into read/write/update. However, it makes sense to divide in other planes. For example, if this class contains code for building SQL queries, it should be placed in a separate class. Moreover, if you need support for multiple databases, then there should be several such classes.

So if there is a need for some high-level change in "data storage provision", you will change the DataBaseInteracting class. If you find a bug with building a suboptimal query, you will change the class that builds queries and you won't even touch DataBaseInteracting. If you need to support a new DB, you just add a new class. Do you understand?

All these classes should be in the DAL project. And this project should only contain what relates to the logic of interaction with the storage (DB in your case). This way you will support the SRP at the project level.

 8
Author: andreycha, 2015-11-26 15:23:14

The so-called "Sole Responsibility Principle" (SRP) actually has nothing to do with the number of features that an entity implements.

The SOLID principles are aimed at solving specific problems that arise when working with code, and in the case of SRP, this is the problem of multiple code changes when changing the terms of reference (TOR).

If the code responsible for the execution of the item TK is scattered across many sources, then when you change this item TK, you will have to edit the source code in many places. For this reason, the SRP recommends that we collect all the code responsible for a particular item of the TOR in one place. So that when the TK changes, you would have to edit only one place in the code (one module, or one file, or one class, or one function, or one line).

From this it follows that if several points of the TOR can be made with one piece of code - then this is normal, but the opposite situation - when one point of the TOR needs a lot of pieces of code - this is already bad. Responsibility is smeared on the source code, SRP is not respected, colleagues cry from commits of 40 files.

Therefore, if DataBaseInteracting is one small class, then from the point of view of SRP-there is no point in splitting it into DataBaseWriter, DataBaseReader and DataBaseUpdater. Another thing is that there are other principles, such as OCP (replacing some pieces of code with others), or the problem of isolating pieces of code during testing.

 5
Author: Abyx, 2016-01-26 22:23:06

The problem arises because large systems consist of multiple layers, and the level of detail on each layer is different.

Therefore, it is logical to define the only duty for the level of detail specific to the layer.

Since the DatabaseInteracting class seems to me too abstract, I suggest that we consider the well-known Repository pattern instead. There are several modifications of it, and in order not to be confused, let's take the modification as a basis, suggested by Evans in a book on DDD.

Evans writes that Storage provides long-term storage of domain domain objects - this is its responsibility. It is implemented through read, update, and delete operations (you can also add creation here, but this is different from the DDD canon).

Going to the level below (looking at the operations in detail), we understand that to speed up the work with the database, you can use the master-slave model, where one database is considered the main one, and a few more - subordinates. Subordinate databases constantly synchronize their content with the main database, so that all servers have the same data.

Writing always occurs in the main database, and you can read from any one. With a large number of reads, this organization of the application gives a significant increase in speed.

At this level of detail, we understand that our connections to the DB server will be of two types: read-only and write-read-only. Accordingly, the read operation will be create a connection of the first type, and update and delete operations of the second type.

You will have classes ReadOnlyConnection and ReadWriteConnection, but at the level of subject logic, you will only operate on Storage.

In my experience, I can say that the reason for unclear code is very often a mixture of levels of detail. Group discussions of the code or targeted work by leading programmers should help here.

 3
Author: Mark Shevchenko, 2015-11-26 14:47:05

First, this principle is very controversial and therefore almost not applicable in practice. There is almost never a technical specification for writing a software product. And if there is a detailed TOR, then it does not change. In addition, it is quite obvious that for any TK, you can easily come up with such an edit, because of which you will have to radically rewrite the program. After all, different parts of the program rely on the same ideas from the TOR, which may change.

Secondly, this principle contradicts the KISS principle (keep it simple stupid / the simpler the better), one of the few that really works in system design. If you break an object into parts, you complicate the program, instead of one class, you get 2, 3, 4, and more. As a result, often, if the original program could be easily understood, then the "improved" one is already difficult, because there are many objects in it and they all do not fit into the consciousness.

Read more here

 -1
Author: stiv, 2016-11-03 10:42:35