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


93

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

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


1
Якщо у вас є конкретні приклади, ви можете отримати більш безпосередньо корисні відповіді
brabster

Відповіді:


55

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

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

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

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

Коли мова заходить про передачу даних навколо класу, важко сказати, що ви робите, це хороша практика, не бачачи коду. Іноді працювати безпосередньо з даними екземпляра - це нормально; в інших випадках це не так. На мій погляд, це те, що приходить із досвідом - ви розвиватимете певну інтуїцію в міру вдосконалення ваших об’єктно-орієнтованих навичок мислення.


Я відповів би на додавання цієї відповіді до відповіді H-Man2 (протягом усього життя). Він повинен бути атрибутом члена тоді і тільки тоді, коли це стійкий стан об'єкта. Тобто значення має сенс саме по собі поза межами поточного стеку методів.
Девід Родрігес - dribeas

Моя реакція в кишечнику полягає в тому, щоб погодитися з Девідом та H-MAn2. Однак я читаю "чистий код" Роберта Мартіна, і в розділі 3 він рефакторирует код, щоб перемістити щось із параметра методу до змінної-члена, оскільки наявність багатьох параметрів - це погано. Зрештою, я думаю, якщо ваш клас несе лише одну відповідальність, то час життя об’єкта такий самий, як і час цього обчислення, тож, можливо, фактична відповідь така: якщо вам потрібно задати це питання, то ваш клас занадто великий?
Енді,

@ DavidRodríguez-dribeas, що ви маєте на увазі під стеком методів?
здійснив

@committedandroider: якщо значення переживає поточний виклик функції
Девід Родрігес - dribeas

46

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

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


21

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

Ось приклад:

myCircle = myDrawing.drawCircle(center, radius);

Тепер дозволяє візуалізація класу myDrawing використовує 15 допоміжних функцій для створення об’єкта myCircle, і кожна з цих функцій потребуватиме центру та радіуса. Їх все одно не слід встановлювати як змінні екземпляра класу myDrawing. Тому що вони більше ніколи не будуть потрібні.

З іншого боку, класу myCircle потрібно буде зберігати як центр, так і радіус як змінні екземпляра.

myCircle.move(newCenter);
myCircle.resize(newRadius);

Для того, щоб об'єкт myCircle знав, яким є його радіус і центр, коли робляться ці нові виклики, їх потрібно зберігати як змінні екземпляра, а не просто передавати функціям, які їх потребують.

Отже, в основному, змінні екземпляра - це спосіб зберегти "стан" об'єкта. Якщо змінної не потрібно знати стан об'єкта, то вона не повинна бути змінною екземпляра.

А що стосується оприлюднення всього. Це може полегшити вам життя в даний момент. Але це повернеться переслідувати вас. Піз не робіть.


Ви можете просто визначити переміщення для використання параметрів (oldCenter, newCenter).
obesechicken13

4

ІМХО:

Якщо змінна є частиною стану екземпляра, тоді вона повинна бути змінною екземпляра - classinstance HAS-A instancevariable.

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

Сподіваюся, це допоможе


3

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

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

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

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

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


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