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


60

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

я можу зробити

[view1 setAlpha:0.0f];
[view2 setAlpha:0.0f];

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

[view3 setAlpha:1.0f];

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

Якщо дзвінок дуже важкий, очевидно, краще не телефонувати, коли це не потрібно, але мені було цікаво про такі дрібні речі, як мій приклад.

Відповіді:


134

У вас інваріант:

Лише один перегляд (із 3) завжди активний (і видимий).

Тоді я пропоную вам надати функцію одночасно перемикати активність та видимість ВСІХ переглядів:

[setActiveView viewID:2]

Ця функція:

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

Він має багато переваг щодо необмеженого дзвінка setVisibility:

  • доброзичливий: зателефонувавши до нього, це не створює проблем із продуктивністю
  • оборонний: його єдиний параметр набагато складніше отримати, тоді як для setVisibilityцього важче запам’ятати, що діапазон значень є 0.0f - 1.0fі що лише один повинен бути встановлений1.0f
  • стійкий: наступний хлопець не може випадково забути один із поглядів
  • адаптується: додавання / видалення подання не вимагає ретельного вивчення всього коду програми, щоб знайти місце перемикачів, одну функцію (цю) потрібно оновити

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


Чудова пропозиція. Я зроблю це своїм сучасним прикладом. Але що робити, коли така конструкція неможлива / бажана? Або ви вирішили на місці, який найкращий спосіб впоратися з цим?
Кевін

4
@Kevin: Це дійсно залежить. Іноді ви можете вирішити проблему, повторивши колекцію, іноді ні, але ключовим принципом є уникнення дублювання та полегшення збереження інваріантів. Чим більше «ручних» дій потрібно пам’ятати, щоб вони працювали належним чином, тим менше шансів на те, що вони працюватимуть належним чином. Я ненавиджу тут бути розпливчастим, але є так багато різних ситуацій, що я боюся, що "загальне" правило просто зведе вас з пустощів.
Матьє М.

23
"полегшити збереження інваріантів" - це загальне правило, яке варто пам'ятати.
Гусдор

1
@Tonny: Я не знаю, чи заохочувати використання глобальної змінної "це правильно", але якщо ви точно знаєте, яка раніше була активна, вам потрібно оновити лише два представлення. Ще одне рішення полягає в тому, щоб кожен вид пам’ятав свою видимість і setVisibilityне робити нічого, якщо видимість вже є такою, яку вимагають, а це знижує відповідальність.
Матьє М.

1
@MatthieuM. Я писав поспіхом, але насправді я теж мав на увазі. Якщо ви знаєте попередній стан, вам потрібно буде оновити не більше 2 переглядів. Як запам'ятати цей стан - інша справа ;-). Що стосується перенесення відповідальності вниз: Якщо клас перегляду не передбачає цього, вам потрібно буде перенести клас в інший об’єкт, просто щоб додати це властивість. Це чисте рішення, але, можливо, трохи надмірне.
Тонні

12

Альтернативна ідея: якщо ваша мета полягає в тому, щоб запобігти помилкам , що походять з - за люди забувають , що є три види , і зробити що - то з тільки два з них , що вони дійсно повинні робити з усіма з них, а потім зробити функцію , яка робить неможливим забути:

setViewVisibilities(0.0f, 0.0f, 1.0f)

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

Для випадку , коли view3не потрібно це видимість змінилася, ви можете додати деякий поведінку , де проходять спеціальне значення , як -1.0і nilчи що - то вздовж цих ліній означає «не змінити видимість перегляду на всіх». Це обходить проблему встановлення видимості без необхідності.


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

3
@ChrisCirefice: Якщо кількість переглядів зростає, ви можете створити якийсь об’єкт / клас "ViewState", який застосовує цей інваріант. Потім використовуйте це для перемикання тощо. При такій кількості переглядів, якийсь об’єкт менеджера, мабуть, має сенс все одно.
sleske

8

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

(можливо, той факт, що дзвінок непотрібний, або що вам потрібен коментар з цього приводу, може бути запахом коду)


1
@Niall Якщо можливо, твердження було б навіть краще, ніж коментар.
200_успіх

9
Коментарі не є рішенням незрозумілого та нечитабельного коду
dj18

2
@Kevin або ви можете написати код, який ідеально читається без коментарів.
січня

1
@Jan Коментарі - це більше, ніж просто пояснення, що робить код .......
Кевін

2
@Kevin Я б сказав, що коментарі ніколи не повинні існувати, щоб пояснити, що робить код, а краще пояснити, чому він це робить. І в таких ситуаціях часто рефактор отримує наміри, не потребуючи коментаря (це звучить як точка Яна).
RJFalconer

4

У цьому конкретному випадку @Mattieu M. має правильне рішення.

У більш загальному випадку, коли не існує ніякого подібного перетворення, ви повинні запитати себе: Чи є якийсь - небудь шанс , майбутній програміст може зіпсувати це?

Відповідь, як правило, так. Що означає, так, вам слід додати дзвінок. Можливо, якась майбутня версія фреймворку починається з усіх переглядів OFF, а не ON.

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