Як мага лепш пазбягаць напісання раздзьмутага кода GUI?

Я лічу, кожны раз, калі я працую з графічным кодам, код мае тэндэнцыю надзімацца хутчэй, чым іншыя віды коды. Акрамя таго, здаецца, цяжэй рэарганізаваць. У той час як у іншых відах кода я магу рэарганізаваць даволі лёгка - я знаходжу, што я магу раскласці шырокі клас на больш дробныя кавалкі функцыянальнасці - з большасцю рамак GUI я часта звязаны з рамкамі, якая патрабуе майго віджэт/кіравання/незалежна ад класа да рэалізаваць нашмат больш рэчаў, больш непасрэдна ў віджэце/кіравання/усе. Часам гэта адбываецца з-за неабходнасці альбо (а) атрыманне ў спадчыну ад некаторага базавага фішкі/кіравання/рэч, або (б) неабходны доступ да абароненым метадам.

Як правіла, я таксама, напрыклад, рэагаваць на вялікую разнастайнасць уваходаў праз сігналы/падзеі/незалежна ад рамак для рэалізацыі ўсіх рэжымаў ўзаемадзеяння з карыстальнікам. Я, магчыма, спатрэбіцца ў адным віджэце/кіравання для апрацоўкі вялікай разнастайнасці ўводу/высновы, якія могуць ўключаць у сябе:

  1. правай кнопкай мышы/кантэкстнае меню
  2. рэагуе на выбаркі з кантэкстнага меню - што можа быць шмат
  3. спецыяльны спосаб намаляваць GUI
  4. <�Літый> рэагуе на ўвод з клавіятуры </літый>
  5. кнопкі, сцяжкі,
  6. і г.д. і г.д.

... ўвесь час кіраваць класы пад GUI, які ўяўляе бізнес-логіку.

Просты прамалінейны GUI можа мець свой код расце даволі хутка, нават калі адлучаючы з Buisiness логікі і з дапамогай MVC, я знаходжу GUI код з'яўляецца вялікім магнітам для змены.

Ці ёсць спосаб кіравання GUI кода разумным чынам і не дазволіць яму стаць пабітым акном? Або маса выпадковых апрацоўшчыкаў падзей/перавызначаны метады сапраўды лепшае, што мы можам зрабіць для GUI код?

45
Якое ваша дакладнае вызначэнне «наваротаў»?
дададзена аўтар Adam Lassek, крыніца

10 адказы

Справа ў тым, каб памятаць пра GUI кодзе з'яўляецца тое, што ён кіруецца падзеі, і падзейны код заўсёды будзе мець выгляд масы выпадковым чынам арганізаваных апрацоўшчыкаў падзей. Дзе гэта становіцца сапраўды брудным, калі вы спрабуеце ўпіхнуць ня-кіраваныя падзеі кода ў клас. Вядома, гэта мае выгляд забеспячэнне падтрымкі апрацоўшчыкаў падзей, і вы можаце захаваць вашы апрацоўшчык падзей добрыя і невялікія, але ўсё, што дадатковы код падтрымкі плавае вакол робіць ваш крыніца GUI, здаецца разадзьмутым і брудна.

Так што вы можаце зрабіць з гэтай нагоды, і як вы можаце зрабіць рэчы прасцей рэарганізоўваць? Ну, я б спачатку змяніць маё вызначэнне рэфактарынгу ад чаго-то, што я раблю часам да нечага, што я раблю пастаянна, як я кода. Чаму? Таму што вы хочаце рэфактарынгу, каб дазволіць Вам лёгка змяняць свой код, а не наадварот. Я не проста прашу вас змяніць семантыку тут, але прашу вас замест таго, каб зрабіць трохі псіхічную гімнастыку для таго, каб убачыць код па-рознаму.

Тры метады рэфактарынгу, якія я знаходжу я выкарыстоўваю найбольш часта з'яўляюцца Перайменаваць Extract Method і Extract Class . Калі б я ніколі не даведаўся ніводнага іншага рэфактарынгу, тыя тры ўсё яшчэ дазваляюць мне трымаць мой код чыстай і добра структураваная, і ад зместу вашага пытання, гэта гучыць для мяне, як вы, верагодна, знайсці сябе, выкарыстоўваючы адны і тыя ж тры рэфактарынгу амаль пастаянна каб захаваць свой код GUI тонкі і чысты.

Вы можаце мець найлепшае падзел GUI і бізнес-логіку ў свеце, і да гэтага часу код GUI можа выглядаць як код шахта была падарваная ў сярэдзіне. Мая парада заключаецца ў тым, што не было б мець дадатковы клас або два, каб дапамагчы вам кіраваць GUI належным чынам, і гэта не абавязкова павінен быць вашым Прагляд класы, калі вы падаеце шаблон MVC - хоць часта вы знойдзеце прамежкавыя класы вельмі падобныя на ваш погляд, што вы часта будзеце адчуваць жаданне аб'яднаць іх для выгоды. Мой погляд на тое, што гэта на самай справе не перашкодзіць дадаць дадатковы пласт GUI спецыфічныя для кіравання ўсімі візуальнай логікі, але вы, верагодна, хочаце, каб ўзважыць выгады і выдаткі гэтага.

Таму мая парада:

  • Нічога не рабіць непасрэдна ззаду GUI, акрамя як для выкліку і вызначыць, як GUI зачэпіць у View (або прамежкавы пласт).
  • Не спрабуйце абутковага ражка кожны выгляд звязанай рэчы ў адзін клас - або нават асобны клас для кожнага акна GUI - калі гэта не мае сэнсу для вас, каб зрабіць гэта. Ваша альтэрнатыва стварыць шмат мала і лёгка кіраваць класамі для кіравання GUI логікі.
  • Калі вашы метады пачынаюць выглядаць трохі больш, чым 4-5 радкоў кода, праверце, калі гэта неабходна, і калі можна атрымаць метад або два, так што вы можаце трымаць свае метады бедны, нават калі гэта азначае, што клас з вялікай колькасцю больш метадаў.
  • Калі вашы класы пачынаюць выглядаць сапраўды вялікі, пачніце з выдалення ўсіх дубляванай функцыянальнасці, а затым паглядзець, калі вы можаце лагічна групаваць такія метады, якія вы можаце атрымаць яшчэ адзін клас або два.
  • Падумайце аб тым, рэфактарынг кожны раз, калі вы пішаце радок кода. Калі вы атрымліваеце радок кода, каб працаваць, калі вы можаце рэарганізаваць яго, каб пазбегнуць дублявання функцыянальнасці, або зрабіць яго крыху кампактней без змены паводзін.
  • Прыміце непазбежнае, што вы заўсёды будзеце адчуваць, што адна ці іншая частка ў вашай сістэме будзе пачаць адчуваць сябе крыху раздзьмутай, асабліва калі вы заняхайваеце рэфактарынг, як вы ідзяце. Нават з добра улічаны кодавай базай, вы можаце адчуваць сябе, як быццам ёсць больш, што вы можа рабіць. Гэта рэальнасць напісання праграмнага забеспячэння, што вы апыніцеся заўсёды адчувае, што нешта яшчэ можна было б зрабіць «лепш», так што вы павінны знайсці баланс паміж рабіць прафесійную працу, і залачэнне.
  • Прыміце, што прыбіральнік вы спрабуеце захаваць ваш код, тым менш раздзьмутай ваш код будзе здавацца.
36
дададзена
+1 Як гэта ці не, GUI клапоціцца аб мильоне дэталёвых аперацый і гэта азначае, што код.
дададзена аўтар hschober, крыніца
Распрацоўшчыкі павінны навучыцца выкарыстоўваць кадаваньне кіраваных падзей для графічнага інтэрфейсу карыстальніка.
дададзена аўтар David Gao, крыніца

Я думаю, што многія з праблем, якія вы выпрабоўваеце можа быць прасочаны да простай прычыне. <�Моцны> Большасць распрацоўнікаў не ставяцца да GUI код, як «рэальны» код. У мяне няма доказаў або статыстыкі тут, толькі маё пачуццё кішкі.

Можа быць, яны думаюць, што гэта « толькі прэзентацыі » і не важна. Там няма бізнес-логікі там ', яны кажуць,' чаму модульнага тэставання гэта '? Яны смяюцца, калі вы згадваеце арыентацыю аб'екта і пісаць чысты код. Яны нават не спрабуюць зрабіць рэчы лепш. Там няма структуры, каб пачаць з таго, што яны проста аплявуха код і хай гніюць, як іншыя дадаюць іх уласнае дотык на працягу доўгага часу. Выдатны беспарадак, графіці код.

GUI код мае свае унікальныя праблемы, таму варта ставіцца па-рознаму і з павагай. Ён мае патрэбу ў каханні і распрацоўшчыкі, якія хочуць , каб яго захаваць. Тыя, якія будуць трымаць яго тонкім і даюць яму добрую структуру і правільныя мадэлі.

22
дададзена
+1 Дзе я працую, мы часцяком не праглядаем код GUI - «гэта проста графічны інтэрфейс карыстальніка, прапусціце яго». І я вінаваты, як і ўсе. Дзіўна тое, што ў маіх асабістых праектах я праводжу шмат часу, калі спрабаваць атрымаць добры чысты код GUI. Думаю, гэта проста культура рэч.
дададзена аўтар Tim C, крыніца
+1 для намякаючы ўспрымання GUI кода, трактуецца па-рознаму, каб без графічнага інтэрфейсу кода. Я страціў рахунак, колькі разоў я чуў, хто-то сказаў, "не турбаваць, каб праверыць GUI, таму што гэта не з'яўляецца эканамічна эфектыўным і да таго ж гэта так цяжка зрабіць». Я звычайна пераводзіць «Гэта цяжка, і я занадта лянівы, каб даведацца, як гэта зрабіць!».
дададзена аўтар S.Robins, крыніца

Па нейкай прычыне GUI коды стварае мёртвую кропку ў распрацоўніках аб падзеле праблем. Можа быць, гэта таму, што ўсе падручнікі звальваць усё ў адным класе. Можа быць, гэта таму, што фізічнае ўяўленне робіць рэчы здаюцца больш цесна звязаныя паміж сабой, чым яны. Можа быць, гэта таму, што класы атрымліваюць убудаваныя павольна, каб людзі не прызнаюць, што яны маюць патрэбу рэфактарынг, як славуты жаба кіпячэння павольна падымаючы цёпла.

Які б ні была прычына, рашэнне, каб зрабіць вашыя класы нашмат менш. Я раблю гэта ўвесь час пытацца сябе, калі гэта магчыма, каб паставіць тое, што я друкую ў асобны клас. Калі гэта можна паставіць у іншы клас, і я магу думаць аб разумным і простае імя для гэтага класа, то я гэта раблю.

7
дададзена

Мой адказ складаецца з чатырох частак: структуры, прастаты тэставання і сінтаксісу.

Першыя тры сапраўды цяжка зрабіць!

Structure means paying a lot of attention to using the least amount of code and the maximum amount of frameworks, libraries etc.

Simplicity means keeping things simple from initial design to actual implementation. Keeping the navigation simple, using simple plugins, keeping the layout fairly 'plain' will all help here. They can now be 'sold' to clients/users that can quickly see the advantages of pages that work on pc's, ipad, mobile and other devices.

Testing means including browser-testing tools (webrat and capybara come to mind with my rails work) that catch cross-browser issues up front when better code can be designed to deal with them at the beginning as opposed to the frequent 'patching' of code by different developers as they are 'discovered' by users of different browsers.

Syntax. It's really helpful to use a code checker/IDE/editor-plugin, etc. for your HTML, CSS, Javascript, etc. The advantage that browsers have obtained through being able handle ill-formed HTML works against you when different browsers perform differently with it, so a tool that checks your HTML format is essential. Having well-formed HTML is very helpul in having unbloated HTML as bad code should have more visibility.

5
дададзена

Вы можаце захацець зірнуць на Model View Presenter/Passive Паглядзець шаблон. Рэй Раян даў добры размова на Google IO аб найлепшай практыцы архітэктуры для GWT.

http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html </а>

Лёгка абстрактныя ідэі для іншых структур і моў. Асноўная перавага MVP (на мой погляд) з'яўляецца блок-проверяемость. І вы атрымаеце толькі, што, калі ваш код, ня разадзьмуты, а не спагецці (мяркуючы па вашым пытанні, гэта тое, што вы хочаце). Ён працуе шляхам увядзення гледжання логікі пласта, званы вядучым. Фактычны выгляд адлучаецца ад гэтага праз інтэрфейс (і, такім чынам, можа быць лёгка высмейвалі ў выглядзе адзінкавых выпрабаванняў). Цяпер, так як ваша кропка гледжання логіка пласт (вядучы) вызваляецца ад вантроб бетоннай асновы графічнага інтэрфейсу карыстальніка, вы можаце арганізаваць яго як звычайны код, і вы не прывязаны да, напрыклад, Кругавая іерархіі атрымання ў спадчыну. У ідэале вы маглі б перайсці рэалізацыі графічнага інтэрфейсу ў розных структурах, калі яны адпавядаюць адным і тым жа інтэрфейсу.

5
дададзена
+1. MVP факусуюць менавіта на тым, як атрымаць логікі GUI у асобныя класы, якія часта моцна адрозніваюцца ад таго, што людзі разумеюць, калі яны кажуць аб MVC.
дададзена аўтар Peter LeFanu Lumsdaine, крыніца

Рашэнне, якое я знайшоў гэта дэкларатыўны код. Выкарыстоўваючы толькі працэдурны код з'яўляецца рэцэптам для спагецці GUI кода. Вядома, «спецыяльны спосаб намаляваць віджэт», верагодна, будзе заставацца кодам. Але гэта код ізаляваны ў класе. Апрацоўшчыкі падзей, гарачыя клавішы, памеры акна - усё, што брудны матэрыял лепш за ўсё абвешчаны.

4
дададзена

Там шмат вялікіх адказаў тут.

Адна рэч, якая дапамагла мне спрасціць код GUI, каб пераканацца, што GUI мае сваю ўласную мадэль дадзеных.

Возьмем просты прыклад, калі ў мяне ёсць графічны інтэрфейс з палямі ўводу 4 тэксту, то ў мяне ёсць асобны клас дадзеных, які захоўвае змесціва гэтых палёў уводу тэксту 4. Больш складаныя ГПІ патрабуюць больш класаў дадзеных.

Я распрацаваць графічны інтэрфейс у якасці мадэлі - выгляд. Мадэль графічнага інтэрфейсу кіруецца кантролерам прыкладанняў мадэлі прыкладання - выгляд - кантролер. Выгляд прымянення з'яўляецца мадэль GUI, а не сам код GUI.

4
дададзена

Такія прыкладання, як апрацоўка тэкстаў, графічных рэдактараў і г.д. маюць складаныя інтэрфейсы і іх код не можа быць простым. Тым не менш, для бізнес-прыкладанняў, графічны інтэрфейс не павінен быць настолькі складаным, але некаторыя, як гэта да гэтага часу.

Некаторыя з ключоў да спрашчэння графічнага інтэрфейсу (найбольш дастасавальныя да .NET):

  1. Імкніся да больш просты канструкцыі, калі гэта магчыма. Пазбягайце фантазіі паводзінаў, калі не выклікаецца ў бізнэсе.

  2. З дапамогай добрага пастаўшчыка элементаў кіравання.

  3. Не ствараць функцыі кіравання карыстацкімі ў самым кліенцкім кодзе. Замест таго каб стварыць карыстацкіх элементаў кіравання, які пашырае зыходны кантроль такім чынам, што вы можаце адлюстраваць вашыя канкрэтныя мадэлі паводзінаў у кантрольнай групе, а не ў кодзе з дапамогай формы/старонкі.

  4. З дапамогай рамкі (нават дома вырашчаны) для апрацоўкі інтэрнацыяналізацыі, кіраванне рэсурсамі, стылі і г.д., так што вы не паўтараць гэты код у кожным інтэрфейсе.

  5. <�Літый> <�р> Найміце кампанент (або рамкі) для навігацыі. </Р>
  6. Пабудаваць стандартныя дыялогі на наяўнасць памылак, папярэджанняў, пацверджанне і г.д ..

2
дададзена

Прымяненне аб'ектна-арыентаванага праектавання ў код, а таксама для распрацоўкі карыстацкага інтэрфейсу:

  1. Separate presentation and model Use a MV-whatever library/framework, or write your own, to help separate view/controller logic from data model. All communication with the backend should be done inside the model, and the model state should always be in-sync with the backend.
  2. Decoupling If object A knows about object B, then A can call methods on B, but B should not know about A. Instead A can listen to events from B. It makes sure there is no circular dependency. If your app has lots of events between components, then create an EventBus, or leverage an event-driven framework like Twitter Flight.
  3. Partial vs full render If your view is a table or list of items, your may be tempted to create methods like "add", "remove" to insert/delete one item into/from the collection. Your code could easily bloat when you have to support sorting and pagination. So my advice is: simply re-render the whole view even when there is a partial change. What about performance? well if your collection is big, then your should do pagination anyway. Web developer: make sure your event handlers are delegated to the view's root element which does not change.
  4. View model When your view's state becomes too complicated to maintain, for example, a Table view has to keep track of the row data, column data, sort order, currently checked rows (if it supports multi-check), etc, you should probably create a ViewModel object for those states. Your View object should call setters on the ViewModel if something changes on the UI (eg: user checks a row); and it should respond to ViewModel's change event by updating the UI. Usually you should avoid updating the UI if the change event is triggers by UI.

Here is a small but non-trivial app to help illustrate some of my points. You can find the code and view/model interaction diagram here: https://github.com/vanfrankie/pushpopbox

1
дададзена

Вы хочаце зірнуць на канцэпцыю «прывязкі дадзеных» . Гэта спосаб злучыць элементы карыстацкага інтэрфейсу ў абстрактныя элементы мадэлі дэкларатыўна такім чынам, што элементы мадэлі аўтаматычна сінхранізаваныя з змесцівам карыстацкага інтэрфейсу. Ёсць шмат пераваг такога падыходу, напрыклад, не маючы пісаць апрацоўшчык падзей самага для сінхранізацыі дадзеных.

Існуе падтрымка прывязкі дадзеных для многіх структур карыстацкага інтэрфейсу, напрыклад, .NET і < A HREF = "http://wiki.eclipse.org/index.php/JFace_Data_Binding" отн = "NOFOLLOW"> Зацьменне/JFace .

0
дададзена