Це порушення відкритого закритого принципу для оновлення константи, що представляє цінність у реальному світі?


10

У мене клас обчислення чистого річного доходу працівників. Він має константу, що представляє відсоток податку. Але одного дня ставка податку змінилася, тому мені потрібно виправити код.

Чи вказує акт фіксації цієї константи про порушення принципу відкритого закриття, оскільки він постулює, що клас повинен бути закритий для модифікації?


10
Програмне забезпечення змінюється, оскільки змінюється реальний світ. З іншого боку, ставка податкового відсотка постійною є не стільки порушенням принципу відкритого закриття, скільки просто необізнаною справою. Податковий відсоток - це очевидно змінна стаття, яка повинна бути обмежена під час виконання.
Річард Чемберс

4
Я повністю погоджуюся з Річардом. Якщо вам доведеться змінити код, щоб виправити цю "константу", OCP - найменша з ваших проблем.
Роберт Харві

3
Те, що є порушенням OCP, є високо суб'єктивним, і вся справа в будь-якому разі є дещо застарілою (оскільки успадкування впровадження вже не найкраща практика). Це типове запитання, де ви повинні здогадатися, що думає людина, яка задає питання.
Роберт Брутігам

2
@DocBrown: що є "новою вимогою"? Ви покажете мені якийсь код, я можу вказати на нові вимоги, які неодмінно потребуватимуть зміни коду, незалежно від того, наскільки OCP відповідає вам це зробити. Тож повернемось до питання: Якщо розробник запитав у цього експерта бізнесу, і не очікували зміни ставки податку більше одного разу кожні пару років, немає сенсу робити його конфігурувальним чи ін'єкційним. Просто тримайте це просто і готуйтеся до того, що знаєте . І для цих речей обов'язково зробіть це зовнішнім для класу. Так це залежить .
Роберт Брутігам

1
@ RobertBräutigam: Моя думка, там, що в IMHO немає такого поняття, як "OCP match", є лише "OCP match у контексті певних категорій вимог". Напевно, може бути певна суб'єктивність, до яких категорій компонент повинен відповідати "OCP". Але у випадку, описаному в цьому питанні, як я це розумію, зміна вимоги вже була визначена, так що цей "клас обчислення доходу" явно не підпорядковується OCP в контексті цієї конкретної вимоги.
Док Браун

Відповіді:


14

OCP можна краще зрозуміти, коли мислять про класи або компоненти, надані постачальником A в якійсь бібліотеці чорних скриньок, для використання користувачами B, C і D (зауважте, це просто ментальна модель, яку я використовую для наочності, не має значення, чи насправді єдиним користувачем класу є сам A).

Якщо B, C і D можуть використовувати або повторно використовувати надані класи для різних випадків використання, не потребуючи модифікації вихідного коду бібліотеки, то компонент відповідає OCP ( стосовно категорії випадків використання ). Існують різні засоби для досягнення цього, наприклад

  • зробити клас успадковим (як правило, у поєднанні з шаблоном шаблону або шаблоном стратегії)

  • шляхом надання "точок введення" для ін'єкції залежності

  • шляхом надання параметрів конфігурації для класу або компонента (наприклад, за допомогою параметра конструктора "відсоток податку", як у вашому випадку, або за допомогою іншого механізму конфігурації)

  • можливо, іншими засобами, залежно від мови програмування чи екосистеми

Типові приклади, які ви знайдете в текстових книгах, часто бувають першого або другого типу (я думаю, тому що в очах авторів цих книг третій тип занадто тривіальний, щоб його варто згадати).

Як бачите, це не має нічого спільного з забороною будь-якої зміни вихідного коду від постачальника A (як, наприклад, виправлення помилок, оптимізація або додавання нових функцій у зворотно сумісний спосіб), що є абсолютно не пов'язаним з OCP. OCP полягає в тому, як A проектує інтерфейс і деталізацію компонентів в лібі, тому різні сценарії повторного використання (наприклад, перенастроювання з різними ставками оподаткування) автоматично не викликають вимог до змін.

Тож незважаючи на те, що вам тут говорять інші, відповідь однозначно «так» , це було б порушенням OCP.

EDIT: схоже, що між ними хтось написав докладну публікацію в блозі про цю тему. Хоча його частини можна було б краще сказати (як зазначав Дерек Елкінс), схоже, автор взагалі поділяє мою точку зору, що "виконання OCP" - це не абсолютна властивість, а щось, що може бути оцінено лише у певному контексті категорії змін вимог.


Гаразд, отже, OCP полягає у наданні розширеної поведінки для різних випадків використання одним із трьох перерахованих вами засобів, правда? Але що робити, якщо приклад ОП передбачав, що щось основне має змінитися? Я не знаю, з чого складається ОП, але в моїй країні ставка податку - це те, що змінюється не дуже часто. Це був поганий приклад, але, можливо, його навмисно витягували постійно, щоб наголосити на цьому. Я впевнений, що це не мало бути налаштованим чи розширеним. Тож, можливо, питання стосувалося "це не має нічого спільного з забороною будь-якої зміни вихідного коду постачальником A".
Вадим Самохін

Принаймні, я так зрозумів. Бідний хлопець, який видалив свою прийняту відповідь, зробив це так, або я гадаю. Ви бачили це трохи під іншим кутом зору - я розумію вашу думку і згоден з цим. Але, схоже, наймудріший коментар дав @Robert Bräutigam. До цих пір я не зрозумів, що OCP - це ТОЩО суб'єктивне.
Вадим Самохін

1
Я думаю, якщо мені коли-небудь зададуть одне і те ж питання, є одне запитання, яке я мушу задати у відповідь: "чи слід поведінку якось розширити чи налаштувати?". Якщо так - то безпосередньо пряма модифікація класу є порушенням OCP. Якщо ні - OCP просто не застосовується в цій ситуації.
Вадим Самохін

1
@Zadadlo: Я думаю, якщо компонент відповідає OCP для класу вимог , не дуже суб'єктивний - в більшості випадків досить зрозуміло, чи потрібна нова вимога модифікація вихідного коду компонента або якщо компонент підтримує цю вимогу "Можливі підходи до його впровадження не обмежуються першими 3 засобами, які я перерахував, див. Мою редакцію. Ваше поняття суб'єктивності може бути викликане тим, що OCP просто має оманливе ім'я і досить погано пояснюється у багатьох підручниках.
Док. Коричневий

Моє уявлення про суб’єктивність було викликане тим, що я не повністю зрозумів, що ви сказали, - але я думаю, що зараз. Дякую за проникливі коментарі та вашу відповідь.
Вадим Самохін

4

Як кажуть інші, в ідеалі клас доходів робітників дозволяв би параметризувати постійну, роблячи цей клас незалежним від цього значення.

Зрештою, викликає додаток може також допускати параметризацію з точки зору зовнішньої конфігурації (наприклад, файл). Щойно у нас є зовнішня конфігурація, ми можемо змінити ставку податку - хоча врахуємо, що якщо файл конфігурації читається лише один раз при запуску, тоді додаток доведеться перезапустити для оновлених відсотків податків, щоб набути чинності, щоб це було чим слід тримати розум. Ми можемо надати функцію програми, щоб перечитати конфігурацію, коли вам це дозволено, або ми можемо надати більш складний механізм, який помічає, коли файл конфігурації змінюється ...

В довгостроковій перспективі ви можете виявити, що податкові питання вимагають більше, ніж лише відсоток - наприклад, що одного дня податкове законодавство є складнішим і вимагає декількох відсотків і деяких констант (наприклад, сума в розмірі до 10 тис. Доларів США, оподатковується на X%, тоді як решта оподатковується у Y%).

Це, головним чином, пропонує використовувати схему стратегії, де головний клас, про який йдеться, приймає об'єкт стратегії для обчислення податку.

Різні стратегії (і% -і та $ -константи) мають бути обрані з конфігураційного файлу, і тепер для додавання нової стратегії потрібно додати якийсь новий код, але не обов'язково оновити існуючий код.

Кожна стратегія може знати, як аналізувати / інтерпретувати власні аргументи зовнішньої конфігурації, а також як обчислювати фактичний податок.

Динамічно податок може додатково залежати від місцевого управління, тому у вас може бути місце, пов’язане із заробітком або зі співробітниками (або обома). У зовнішній конфігурації ми можемо пов'язувати місцевість із податковою стратегією.


Також дивіться ін'єкцію залежності , де ми керуємо цими речами чітко.


1
Питання полягало не в тому, чи погана ідея закопувати в коді щось на зразок податкового відсотка, я впевнений, що це очевидно для більшості з нас тут (включаючи ОП). Питання полягало в тому, "чи це порушує OCP?" Тож я не бачу, як ваша відповідь стосується цього питання.
Док Браун

1

Якщо вам потрібно змінити клас, щоб змінити вартість податку, то його дизайн дійсно порушує OCP. Відповідна конструкція для того, що ви описали до цього, полягає в тому, щоб клас калькулятора взяв значення податку як параметр.

Якщо ваш клас інстальовано (це означає, що це не статичний клас), зробивши властивість класу змінних податків, значення якого вводиться через конструктор, ви також покращили б згуртованість класу.

Коротше кажучи, ваш сучасний дизайн робить ваш клас залежним від постійного значення, яке насправді не є постійним (визначаючи константу як величину, яка ніколи не зміниться незалежно від того, як, наприклад, значення PI). Це порушує OCP. Змініть дизайн, щоб отримати вартість податку як аргумент конструктора.


0

Цілком погоджуюся з @Becuzz, і я просто хочу підсумувати це: OCP - це пошук повторно використаних (отже, корисних) абстракцій, які вводяться в клас. Тож поведінка класу змінюється не шляхом зміни його коду, а шляхом надання йому різних реалізацій. Це чітко зрозуміло в книзі Роберта Мартіна " Agile Development Software, Principles, Patterns and Practices ", перевірте відповідний розділ "Принцип відкритого закриття", "Абстракція - ключ". З'ясовується ще одне хибне уявлення про те, що поведінку можна змінювати лише у спадок. Саме Бертран Мейєр запропонував у 1988 році у своїй книзі " Об'єктно-орієнтована побудова програмного забезпечення ", а не Роберт Мартін.


-2

Як я бачу, це не є порушенням принципу відкритого закритого типу. Тим не менш, той факт, що щось, що може змінитись у часі (наприклад, відсоток податку), є постійною вадою дизайну: ви не повинні змінювати значення константи, а як обробляти відсоток податку. Це має бути якийсь тип налаштувань, який можна змінити без перекомпіляції всієї речі.


"Недолік дизайну" полягає в тому, що він порушує відкритий закритий принцип, оскільки вам потрібно перекомпілювати код, щоб змінити константу?
Ердрік Айронроз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.