Скажімо, наприклад, у вас є додаток із широко поширеним класом, який називається User
. Цей клас розкриває всю інформацію про користувача, його Id, ім'я, рівні доступу до кожного модуля, часовий пояс тощо.
Дані користувача, очевидно, широко посилаються у всій системі, але з будь-якої причини система налаштована так, що замість того, щоб передати цей об’єкт користувача в класи, які залежать від нього, ми просто передаємо йому окремі властивості.
Клас, який потребує ідентифікатора користувача, просто вимагатиме GUID userId
як параметр, іноді може знадобитися і ім’я користувача, так що він передається як окремий параметр. У деяких випадках це передається індивідуальним методам, тому значення взагалі не утримуються на рівні класу.
Кожен раз, коли мені потрібен доступ до іншої інформації з класу User, я повинен вносити зміни, додаючи параметри, і якщо додавання нової перевантаження не підходить, я також повинен змінювати кожне посилання на метод або конструктор класів.
Користувач - лише один приклад. Це широко практикується в нашому коді.
Я маю рацію, думаючи, що це порушення принципу "Відкрито / закрито"? Не просто акт зміни існуючих класів, але їх налаштування в першу чергу, щоб в майбутньому, швидше за все, були потрібні широкі зміни?
Якби ми щойно перейшли в User
об’єкт, я міг би внести невелику зміну до класу, з яким працюю. Якщо мені доведеться додати параметр, можливо, мені доведеться внести десятки змін до посилань на клас.
Чи порушено цю практику якісь інші принципи? Можливо, інверсія залежності? Хоча ми не посилаємось на абстракцію, існує лише один вид користувачів, тому реальної потреби у користувальницькому інтерфейсі немає.
Чи порушуються інші, несолідні принципи, такі як основні принципи оборонного програмування?
Чи повинен мій конструктор виглядати так:
MyConstructor(GUID userid, String username)
Або це:
MyConstructor(User theUser)
Редагування публікації:
Запропоновано відповісти на запитання у "Передати ідентифікатор чи об'єкт?". Це не дає відповіді на питання про те, як рішення піти в будь-якому випадку впливає на спробу слідувати принципам SOLID, що лежить в основі цього питання.
I
в SOLID
? MyConstructor
в основному каже зараз "мені потрібно Guid
і string
". То чому б не мати інтерфейс, що забезпечує a Guid
і a string
, нехай User
реалізує цей інтерфейс і нехай MyConstructor
залежить від екземпляра, що реалізує цей інтерфейс? І якщо потреби MyConstructor
змінити, змінити інтерфейс. - Це мені дуже допомогло думати про інтерфейси, щоб «належати» споживачеві, а не постачальнику . Тому подумайте, "як споживач мені потрібен щось, що робить це і те", а не "як постачальник, я можу робити це і те".