Например, у вас есть приложение с широко используемым классом, которое называется User
. Этот класс предоставляет всю информацию о пользователе, его идентификаторе, имени, уровнях доступа к каждому модулю, часовом поясе и т. Д.
Очевидно, что пользовательские данные широко используются во всей системе, но по какой-то причине система настроена таким образом, чтобы вместо передачи этого пользовательского объекта в классы, которые зависят от него, мы просто передавали отдельные свойства из него.
Класс, который требует идентификатор пользователя, просто потребует GUID userId
в качестве параметра, иногда нам также может понадобиться имя пользователя, чтобы оно передавалось как отдельный параметр. В некоторых случаях это передается отдельным методам, поэтому значения вообще не хранятся на уровне класса.
Каждый раз, когда мне нужен доступ к другой части информации из класса User, я должен вносить изменения, добавляя параметры, и там, где добавление новой перегрузки не подходит, я должен также изменять каждую ссылку на метод или конструктор класса.
Пользователь - только один пример. Это широко практикуется в нашем коде.
Правильно ли я считаю, что это нарушение принципа Open / Closed? Не просто акт изменения существующих классов, но в первую очередь их настройка, чтобы в будущем потребовались широкомасштабные изменения?
Если бы мы только передали User
объект, я мог бы внести небольшое изменение в класс, с которым я работаю. Если мне нужно добавить параметр, мне может потребоваться внести десятки изменений в ссылки на класс.
Какие-либо другие принципы нарушаются этой практикой? Возможно, инверсия зависимостей? Хотя мы не ссылаемся на абстракцию, существует только один вид пользователей, поэтому нет особой необходимости иметь пользовательский интерфейс.
Существуют ли другие, не твердые принципы, которые нарушаются, такие как базовые принципы защитного программирования?
Должен ли мой конструктор выглядеть так:
MyConstructor(GUID userid, String username)
Или это:
MyConstructor(User theUser)
Редактировать сообщение:
Было предложено ответить на этот вопрос в «Pass ID или Object?». Это не отвечает на вопрос о том, как решение пойти в ту или иную сторону влияет на попытку следовать принципам SOLID, что лежит в основе этого вопроса.
I
дюйма SOLID
? MyConstructor
в основном говорит сейчас "мне нужно Guid
и string
". Так почему бы не иметь интерфейс, обеспечивающий a Guid
и a string
, позволить User
реализовать этот интерфейс и позволить MyConstructor
зависеть от экземпляра, реализующего этот интерфейс? А если нужно MyConstructor
поменять, поменяйте интерфейс. - Это очень помогло мне придумать интерфейсы, которые «принадлежат» потребителю, а не поставщику . Поэтому подумайте: « Мне как потребителю нужно то, что делает то-то и то-то», а не как поставщику, я могу делать то-то и то-то ».