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


15

Тож мій вчитель каже мені, що дуже важливо в одних і тих же класах не інкапсулювати програмний код та код графічного інтерфейсу, а зберегти їх повністю незалежними. Зараз я пишу гру в iphone із сіткою. для мене має набагато більше сенсу створювати і графічну сітку, і технічний код у тому ж класі "Grid". Чи на це нахмуриться інший програміст? Чи справді дуже важливо підтримувати графічний інтерфейс та код незалежними. Які проблеми виникнуть, якщо я цього не зробив?

Дякую!

EDIT: спасибі, хлопці! Було б нормально, щоб спершу написати проект, а потім скопіювати код, щоб сформувати розділення дизайну проблем. Я знаю, що це може повністю перемогти мету, але так само, як практика ... Тож наступного разу я зможу застосувати цю схему дизайну з самого початку?

Відповіді:


17

Концепція, до якої посилається ваш вчитель, - це щось, що називається відокремлення проблем.

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

Управління інтерфейсом має стосуватися лише малювання того, що йому сказано, логіка сітки повинна стосуватися лише того, що є в сітці, а не як її намалювати.

Чи допомагає це?


Спасибі це допомогло. Річ у тім, що мені набагато простіше уявити свій кінцевий продукт, коли я інкапсулюю обидва в класі. Чи є для цього поважною причиною не слідувати "роз'єднанню проблем"? Або це абсолютно необхідно, і я не міг назвати себе належним програмістом: p?

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

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

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

1
@John: Деякі з нас навчаються найкраще, роблячи справи. Якщо припустити, що цей проект не такий великий, спробуйте написати його як єдиний клас та налагодити його роботу на iPhone. Тепер перенесіть його на Android, відслідковуючи ваші "больові точки". Нарешті, перепишіть це так, як запропонував Russ C. Я думаю, ви побачите, чому розділення логіки та викладу - це шлях.
Пітер Роуелл

4

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

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

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


3

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

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



0

Щоб спиратися на інші відповіді та наводити приклад, вам слід якось дозволити собі вводити свою логіку / дані у вашу сітку чи навпаки.

Ваша система керування сіткою може викрити Renderметод або DataBindметод.

class GridControl
{
    public Render(GridData data) { ... }
}

або

class GridControl
{
    public DataBind(GridData data) { ... }
}

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

Ваш GridLogic також повинен мати посилання на GridControl, щоб він міг прив'язувати до будь-якого вводу / події, що відбувається.

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

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


0

Настійно рекомендую поглянути на архітектуру MVC .

Це уточнення згаданої вами концепції (відокремлення програмного коду та графічного інтерфейсу). MVC розшифровується як Model-View-Controller. Тут Модель - це дані, Вид - код графічного інтерфейсу, а COntroller - код, який обробляє дані.

Таким чином ви створили три частини своєї програми. Кожну частину можна замінити, не вимагаючи змін в інших двох частинах.


0

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

Де MVC виграє, якщо зміни обмежуються V частиною, або "Вид".

На мій досвід, набагато ймовірніше, що зміни торкнуться всіх трьох частин, тому краще, якщо вони не будуть розділені. Щоб показати, що я маю на увазі, я давно використовував методику, яку я розробив під назвою " Динамічні діалоги" , в якій нова вимога, наприклад "дозволити користувачеві редагувати ім'я, і ​​коли завершиться XYZ", вводиться у вихідний код як єдиний блок текст:

if(deTextEdit(&sName)){
  // do XYZ
}

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

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

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

Це не безкоштовно. Він вводить одноразову криву навчання для програміста.


0

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

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