Віддайте перевагу членам класу або передаючи аргументи між внутрішніми методами?


39

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

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

Редагувати:

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

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

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

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


1
Як використовується це значення? Це постійна? Це змінюється? Чи підлягають зміни між компіляціями?
Одід

Коли речі автоматично визначаються як однакові, простіше думати, що це не має значення. Що робити, якщо у вас була функція, яка потребувала скоригованого (x) значення, як x-1?
JeffO

Відповіді:


15

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

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


1
Я згоден - оригінальний дизайн / призначення класу повинен сказати вам, чи це повинна бути змінна члена або аргумент. Також варто подумати про кут нагнітання залежності.
Martijn Verburg

14

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

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


10

Дякую, що ви поставили запитання, я також хотів задати це питання.

Коли я думав про це, є деякі переваги в тому, чому слід передавати це як аргумент

  • простіше тестувати -> простіше в обслуговуванні (пов'язано з останньою точкою)
  • не має побічних ефектів
  • це легше зрозуміти

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

Я б сказав, що має бути назва цього анти-шаблону, чи не так? (не вказано тут )


Який анти-шаблон ви маєте на увазі?
Вахід Гадірі

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

1

Можливо, вам слід витягнути новий клас, що містить усі методи, що поділяють це значення. Звичайно, метод нового рівня буде публічним у новому класі. Це може бути корисно викрити цей метод для тестування.

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


1

Чи вважають за краще люди визначати це як змінну члена для класу або передавати його як аргумент кожному з методів - і чому?

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

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

Немає нічого поганого в оголошенні а private static finalдля визначення констант. Компілятор зможе використовувати це значення при розгляді деяких оптимізацій, і будучи константами, вони насправді не додають стану класу.

хоча якщо одне і те ж значення використовується неодноразово в методах класу ...

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


0

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

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