#c# #oop #solid-principles #single-responsibility-principle
Вопрос:
Я пытаюсь написать плагин для Autocad, и там у них есть эти словари расширений, в которых вы можете сохранять данные в объект Autocad, чтобы при закрытии файла чертежа сохраненные данные сохранялись.
Теперь мне нужны 4 функции для управления словарем расширений:
- существует — для проверки наличия словаря расширений
- создать — для создания словаря расширений
- set — для настройки данных внутри словаря расширений
- get — для получения данных из словаря расширений
в настоящее время у меня есть расширение Doctorymanager.cs, которое частично разбито на 4 файла .cs, как это:
partial class ExtensionDictionaryManager
{
public bool Exist() {...}
}
partial class ExtensionDictionaryManager
{
public bool Create() {...}
}
partial class ExtensionDictionaryManager
{
public bool Set() {...}
}
partial class ExtensionDictionaryManager
{
public bool Get() {...}
}
Следует ли это Принципу Единой ответственности? Или мне следует разбить его еще больше на ExtensionDictionaryCreator
, ExtensionDictionaryChecker
, ExtensionDictionarySetter
и ExtensionDictionaryGetter
?
Меня беспокоит то, что если бы я разбил его на абсолютные отдельные обязанности, не группируя связанные функции вместе, и делал бы это последовательно на протяжении всей моей программы, у меня было бы так много объектов.
Какой был бы правильный способ сделать это?
Комментарии:
1. Частичное разделение класса в разных файлах не имеет никакого значения для кода, оно влияет только на то, как вы управляете файлами классов. Вы вносите ненужный шум в свой вопрос.
Ответ №1:
С SRP трудно справиться. См., например Message
, класс. Должен ли этот класс содержать Send()
метод? Может ли метод отправить сам себя? Или должен быть другой класс MessageSender
?
Некоторые люди используют SRP только для того, чтобы делать классы все меньше и меньше, что в конечном итоге может привести к классам, содержащим только один метод. Но методы, которые принадлежат друг другу, должны оставаться вместе. Хорошим подспорьем является то, как решить, что должно быть в одном классе: если мне нужно изменить функцию, часто мне приходится менять несколько методов. Эти методы должны принадлежать к одному классу. Если я всегда меняю одни и те же два класса одновременно, эти классы, возможно, следует объединить. Если я изменяю только одну часть класса или другую, но никогда не обе части одновременно, класс должен быть разделен. См. также https://hackernoon.com/you-dont-understand-the-single-responsibility-principle-abfdd005b137
Возвращаясь к примеру с сообщением: если механизм отправки сообщения совершенно не связан с данными, содержащимися в сообщении, то два класса Message
и MessageSender
могли бы быть лучше. Если формат сообщения тесно связан с тем, как отправить сообщение, возможно, было бы лучше иметь один класс. Но это всегда какое-то субъективное соображение.
И для вашего кода: я бы оставил его в одном классе. Смотрите, например List<T>
: Это один класс для работы со списком, а не ListAdder<T>
, ListInserter<T>
, ListRemover<T>
, … Если ваш autocad изменится, вам придется изменить алгоритм проверки того, существует ли что-то, создания и так далее, все одновременно. Вот почему они принадлежат к одному классу.