Чому слід уникати форми успадкування?


9

Я пам’ятаю, як вивчив VB4 і перетягнув кнопку на форму, двічі клацнув на цій кнопці та ввів код у цей обробник подій, з яким я щойно був магічно благословлений. Починаючи від QBASIC, я був в захваті від "V" у "VB", візуальний дизайнер був буквально найкращим справою, оскільки нарізав хліб.

Звичайно, ти міг би зробити все це програмно, але магія "V" була такою привабливою, що ти просто не міг не перетягнути цю кнопку. Нас заохотили пройти цей маршрут.

Але потім кілька років тому я почав дізнаватися про C # та рамки .net і був захоплений тим, що все, що я думав, що знав, щойно вийшло з вікна. У VB6 відбувається багато магії, яка повністю розкрита в .net: візьмемо, наприклад, конструктори та InitializeComponentsметод. В останньому ви знайдете всі контрольні екземпляри, які ви перетягнули з панелі інструментів, усі події, які ви зареєстрували, та властивості, які ви встановили в дизайнері.

І це добре ... я здогадуюсь. Просто я відчуваю, що я не "володію" тим, що відбувається, цей код, який я можу змінити лише за допомогою дизайнера, дратує чорт з мене. Кожен раз, коли ви копіюєте кнопку, яка пише "Гаразд" з однієї форми в іншу (іноді разом із братом "Скасувати"), ви насправді копіюєте код, і це гріх, чи не так? СУХО, не повторюйте себе, каже Папа .

Якщо релігії та школи думки, окрім об'єктивності, не повинні ми замість цього отримувати форми з базових форм, а кнопка "Ок" (та всі її друзі) жити на базовій формі? Щось на зразок a, FormBaseз якого походить a DialogFormBase; всі класи, створені в найкоротші терміни ... ввівши код. Кнопки створюються залежно від способу інстанції класу (тобто аргумент перерахунку конструктора визначає, які кнопки потрібно створити), елементи управління розміщуються всередині розташування розділених панелей та панелей компонування потоку, введених у форму якContentщо вписується в основну панель вмісту. Хіба це не те, що ASP.net робить з головними сторінками та заповнювачами вмісту? Я отримав форму, коли мені потрібна нова "головна сторінка", але ця нова "головна сторінка" все ще походить від базового класу форм, тому візуальні зображення є узгодженими для всієї програми.

Для мене це набагато більше використання коду, ніж будь-що інше, що я коли-небудь робив з дизайнером в WinForms, і це було навіть не важко, і код не захаращений методом 200 рядків, над яким я не маю ніякого контролю, я можу розміщуйте коментарі там, де мені подобається, дизайнер їх не переписує. Я думаю, що це лише питання шаблонів та архітектури, саме це і привело мене до цього посилання: Найкращий дизайн для форм Windows, який матиме спільний функціонал , де я зрозумів, що я був на місці, крім відповіді там, підказує саме те, що я робити, але це радить не успадковувати форми через міркування дизайнера. Це частина, яку я не розумію .через міркування структури коду, особливо що стосується форми та спадкового контролю, що я не бачу причин уникати іншого, крім того, що це порушує дизайнера .

Всі ми не можемо бути просто ледачими, і яку частину я пропускаю?


Я не розумію. Ви маєте на увазі, що ми не повинні використовувати візуальних дизайнерів і писати весь код GUI вручну?
Ейфорія

Попередньо .NET, де був код, який контролював усі об’єкти, затягнуті у форму?
JeffO

1
@JeffO судячи зі старого коду, з яким я мав справу, я б сказав, що це прямо за формою, десь між спеціальним вбудованим SQL та бізнес-логікою. Справа в тому, що WinForms є .net; тож якщо дизайнер добре працює з тим, що нині пахне "поганим кодом" та "поганими звичками кодування" і насправді ламається, коли ви починаєте структурувати речі, я кажу, киньте дизайнера і розглядайте форми як такі, що вони є (класи!) .. і чим кодування шару інтерфейсу в C # настільки відрізняється від кодування шару інтерфейсу в ExtJS? Це "нудно" робити це в WinForms, оскільки "ей дивись, є дизайнер"? Чи кодування інтерфейсу ExtJS втомливе?
Матьє Гіндон

Я буду цитувати іншого користувача: CodeCaster; Обробник подій призначений для підключення GUI до вашої логіки бізнесу. Якщо у вас є текстове поле для введення імені користувача та кнопки Додати, натискання кнопки Додати повинно просто викликати _userRepository.AddUser (UsernameTextbox.Text). Ви не хочете ділової логіки в обробниках подій. stackoverflow.com/questions/8048196/…
Пітер Б

@Pieter чи не ставить залежність DAL у ваш презентаційний шар?
Матьє Гіндон

Відповіді:


9

Я протистоятиму вам із різною парадигмою: Композиція улюблена над спадщиною.

Навіть коли ви почнете писати GUI-код вручну і використовувати спадщину для обміну поведінкою та візуальними формами між формами, ви зіткнетесь з тією ж проблемою, що і з звичайним дизайном OOP. Скажімо, у вас є DialogForm, який має кнопки ОК / Скасувати та GridForm, що має сітку. Ви отримуєте всі діалоги від DialogForm та всі форми з Grid від GridForm. І тоді ви дізнаєтесь, що хочете форму з обома. Як би ви вирішили це? Якщо ви використовуєте успадкування форми, то вирішити це не існує. З іншого боку, якщо ви використовуєте UserControls, ви можете просто поставити GridControl у свою форму і виконати її. І ви все одно можете використовувати дизайнер з UserControls, тому вам не доведеться витрачати час на написання нудного коду GUI.


Добре, що базова форма просто має SplitContainer з фіксованим Panel2, що містить FlowLayoutPanel, який називається BottomPanelі розміщує загальну поведінку Ok / Cancel / Apply / Close / Close; Panel1 містить SplitContainer з фіксованою панеллю1 (для розміщення загальної мітки "інструкцій" або меню, панелей інструментів, що завгодно) і Panel2, що містить захищену панель, що називається MainContent; кожна реальна реалізація вирішує, як її заповнити. Весь вміст може бути введено в реалізацію, і так, це може бути контроль користувача, зроблений з дизайнером, щоб заощадити час, хороший результат .. але що з самою формою?
Матьє Гіндон

Проблема тут - масштабність. Якщо ви приймаєте заявку на 10 форм, то мати єдину загальну форму - це не велика справа. Проблеми починаються, коли у вас є додатки з десятками або сотнями форм. Тоді у вас з’являться форми, які мають спільні шматки, але їх ніколи недостатньо для створення базової форми. У вашому випадку може статися, що ви хочете використовувати інший макет або різні кнопки, але зберігати все інше однаково. І ось тоді починаються проблеми.
Ейфорія

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

2
@MasonWheeler У мене був прямо протилежний досвід. Ми намагалися використовувати успадкування форм в одному з наших додатків, і кожного разу, коли ми навіть мало змінювали базові форми, вся справа виходила з ладу, і нам довелося вручну виправити всі інші форми. Також дизайнер поводиться дивно, коли ви працюєте з успадкованою формою.
Ейфорія

1
@Euphoric: Який дизайнер? Ми використовуємо Delphi, і його дизайнер прекрасно працює з успадкованими формами. І знову: у вас немає проблем, якщо у вас хороший дизайн . Якщо ви нічого не плануєте, звичайно, це все буде крихким і зламається, коли ви торкаєтесь цього, але це не відрізняється від будь-якого іншого коду.
Мейсон Уілер

2

Значна частина цього пов'язана з вибором технології.

WinForms і WPF можуть бути як .NET UI рамками, але сильно відрізняються тим, як ви досягаєте кінцевої мети. Деякі парадигми рухаються між технологіями просто чудово, але інші - ні, і не варто намагатися застосовувати парадигму просто тому, що ви вважаєте, що це призначено існувати у всіх рамках. Є причина, що MVVM орієнтована на WPF / SL, а MVC є окремою концепцією в ASP.NET від WebForms тощо. Певні технології краще працюють із певними парадигмами.

Майте на увазі, що згенерований код, як правило, повинен бути видалений із ваших проблем із DRY. Хоча це застосовується в деяких випадках, його частіше за все слід ігнорувати. Концепції DRY, безумовно, повинні залишатися в центрі уваги поза вашим шаром презентації, але генерований код шару презентації найчастіше є побічним продуктом тієї рамки, в якій ви працюєте. Це не означає, що ви не можете застосовувати принципи DRY у своєму підході, але залишаєтесь обережний. Чи можете ви створити базову форму та успадкувати її на невизначений термін? Так. Чи можете ви перетягувати компоненти в новій формі кожен раз, коли потрібно? Так. Не забудьте зосередитись на кінцевій цілі, уникаючи потенційних дефектів, полегшуючи рефакторинг вниз за течією та масштабованість, працюючи в межах вибору технологічного стеку.


0

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

Набагато кращою альтернативою було б групувати пов'язані елементи управління в один або кілька елементів управління UserControl. Вам просто потрібно трохи логіки, щоб внести в неї відповідні дані.


0

Я повністю згоден з Мейсоном Уілером, хоча через три роки, можливо, навіть сам передумав.

Я намагаюся шукати альтернативи для переходу з виконуваних файлів Delphi до веб-сторінки.

До сих пір я вирішив себе для UNIGUI, тому що я все ще можу використовувати успадкування форми. Мені б хотілося, щоб у Дельфі були такі Мікіни, як Дарт, оскільки це дозволило б мені мати менших предків. Але я відчуваю, що люди пишуть набагато більше коду в MVC, ніж у наслідування Visual Form, оскільки більша частина навігації, закликів до правил перевірки в модулі даних (аплікації), критеріїв фільтрації sql, пошуку набору даних клієнта, все написано в 5, можливо 6 Форма предків.

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

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