MVC-Spagetti – Et gammelt problem i nye patterns

Udgivet: 17. oktober 2009

Tænk dig, hvordan vi ville se ud i hovedet, hvis en sagde til os, for bare ganske få år siden, at code-tags i din HTML ville vende tilbage, og lige pludselig blive hyldet? Det er jo nærmest det der er sket idag - og jeg så det ikke komme. Denne post handler om disse code-tags og om at vi må tage nye metoder ibrug, for at holde spegetti-koden i skak.

ASP.NET MVC er for mange frelsen fra Webforms. Webforms ses af mange, som en fejltagelse. Jeg giver dem dog ikke ret i at det var en fejltagelse, at prøve at tage et andet perspektiv på webudvikling. Tænk hvor vi havde været uden at lære af webforms, og tænk hvor mange fede ting der er lavet i webforms, og bliver udviklet i webforms i fremtiden? Webforms er og bliver en god platform, og denne post handler dog ikke om webforms, men om MVC.

Jeg er stadig ikke solgt til at kode også høre til i HTML'en. I mine øjne høre HTML til i HTML'en, og kode til i kode-filer. Men jeg er dog klar over at vi selvfølgelig bliver nød til at have nogle hooks, for at få disse ting til at spille sammen. I Webforms, var det server kontroller som var disse hooks. I ASP.NET MVC, er de de så kaldte HtmlHelpers, og vores det velkendte foreach loop. Jeg giver folk ret i at det ene kan være lige så godt som det andet. Det genialle ved webforms server kontroller er bare det, at de ikke er særligt fleksible. I MVC Views, kan vi alt for let komme til at "se lyset", og lige pludselig kode kompleks logik i vores HTML. Jeg siger ikke at det er umuligt at skrive pæne views i ASP.NET MVC, men det er bare meget sværre at lade sig rive med, og lige pludselig have if-statements over det hele.

Derfor er vi nød til at holde os selv lidt mere i ørene, for at få noget godt HTML, vi kan vedligeholde i MVC. Tilgengæld får vi også 100% det vi beder om – hvilket er et stort plus for os, som føler os godt hjemme i HTML. Dog vil jeg gerne have jer til at tænke på seperation of concerns. Det er et af de punkter som skulle være rigtig godt i MVC, men mange glemmer dette, når de laver deres views.

Javascript er vores nye code-behind

En af de ting som kan hjælpe os meget med denne problemstilling er Javascript. Her snakker jeg ikke om AJAX, og andre pletfjernere, men om at bruge Javascript til at generere og styre din HTML. De fleste kender jQuery, og diverse demo’er, med at en liste lige pludselig bliver til et galleri, bare fordi du giver dit tag en class attribute. Når du ser disse demoer, så læg mærke til hvor lidt HTML du har behov for at skrive og vedligeholde. Javascript står altså for at transformere dit plain-html dokument til noget fedt. Denne tankegang kan give dig effektive web-applikationer som er lette at vedligeholde, fordi vores kode, i vores views, nu kun skal skrive så lidt ud i HTML, som er nødvendigt for at få dit resultat.
Galleriet er et godt eksempel på hvor simpelt du kan lave noget, ved at javascript står for en del af din HTML-genering. Men hvad med alt det i din kode, som ikke er et galleri? Her kommer en liste med normale ting du normalt skriver en del kode i dit view for at opnå, og løsningerne ved at bruge javascript:

  • Alternating-items: Vi kender alle det, at vi ønsker zebra striber på vores tabeller. Vi skriver typisk en del kode, som gør at vi kan give hver anden række en bestemt CSS-klasse, som vi så kan give en anden farve. Ved at bruge jQuery, kan vi gøre dette på en linie javascript: $(“.myTable:even”).addClass(“alt”)
  • Conditional HTML eller styling: Vi har typisk en problemstilling hvor noget HTML skal vises hvis en bestemt condition er opfyldt. Dette kan f.eks. være at hvis en bestemt person har været syg i en uge, så skal hans profil vises med rød. Dette kan give en masse if-sætninger i din kode. I javascript kan du løse dette ved at kigge på de data der er printet ud, og derefter lave beslutningen om han skal være rød. På denne måde, er det nemt at tilføje at han skal være gul efter en periode, uden at dit view bliver endnu mere rodet, da javascriptet er gemt væk i sin egen fil – faktisk lidt ligesom vores code-behind fil. :)
  • Gentaget HTML: Tit har man en liste, hvor hver række indeholder en masse delt HTML. Dette kunne f.eks. være at alle items i listen kan redigeres, slettes osv. Dette producere en masse HTML, som javascript nemt kan generere. Tænk hvis du bare kunne skrive din tabel således:
    <table class="updateable deletable stripes">
        <tr>
            <td>1</td>
            <td>Jesper</td>
            <td>Jensen</td>
        </tr>
        <tr>
            <td>2</td>
            <td>Knud</td>
            <td>Hansen</td>
        </tr>
    </table>

Som du kan se, så har vi meget simpel HTML, men vores javascript vil nu sørge for at tilføje det HTML der er nødvendigt for at tilføje et update-link og et delete-link. Bemærk også at hvis du har en liste med 100 items eller mere, så kan det faktisk blive en ganske god del af HTML du spare per gang personen besøger denne side, og selve javascript transformationen kan meget vel gå hen at tage kortere tid, end at hente HTML’en.

Er jeg nu frelst for spagetti kode?

Nej desvære ikke helt. Man skal hele tiden opveje hvor meget javascript der skal til, for at gøre ens views bare en lille smule mere neme at vedligeholde. Du skal jo huske at vores javascript også skal vedligeholdes, og det er vigtigt at veje begge løsninger, før du laver en beslutning – bare husk at dine views, skal være nemme at vedligeholde – lige som resten af din kode.

Happy shooting coding

Kommentarer

  • Troels Thomsen skrev den 17. oktober:

    Først en enkelt kommentar vedrørende Web Forms: Det er altid positivt at forsøge sig at gøre tingene anderledes, men derfor kan forsøget stadig munde ud i en fejltagelse (hvad Web Forms i mine øjne er). Udvikling af webapplikationer og af klientapplikationer er meget forskellig af natur (HTTP er stateless, modsat afviklingen af en proces, ligesom HTML/CSS/JavaScript skal virke på flere platforme, hvor klientapplikationer (for Microsofts vedkommende) historisk har været knyttet til én). Derfor giver det ikke mening at tvinge udviklingsmodellen fra den ene ned over den anden. Web Forms har i forhold til overholdelse af standarder på internettet været den nyere tids FrontPage.

    ... og nu til det væsentlige: Jeg mener ikke, at JavaScript er løsningen på de fleste af de problemer, du nævner. Faktisk mener jeg, at JavaScript blot skaber nogle andre problemer - og i stil med dem, Web Forms skaber. Det primære er relateret til begrebet graceful degradation. Jeg har fuld forståelse for, at man bruger JavaScript til at smide "odd"/"even" på rækker, fordi det blot giver nogle bedre muligheder i de browsere, der ikke understøtter den samme mulighed i CSS. Jeg har derimod svært ved at forstå, at man for at slippe for at smide et par ekstra kolonner (mulighed for at opdatere/slette) med i sin egen kode, vil pålægge brugerens browser at gøre det (hvilket jo også betyder, at man mister muligheden for at generere routes, men må basere sit JavaScript på, at de er opbygget på en bestemt måde).

    Hvad er løsningen så? Jeg mener ganske simpelt, at det er at bruge en anden form for skabelon - altså en view engine. Det er klart, at standardvalget Web Forms jo vil minde meget om ens kode, da det er samme sprog. Et decideret sprog til den slags er klart at foretrække, også så man ikke behøver at være udvikler for at kunne rette i visningen. Der må gerne være dynamik i viewet, men med en ordentlig view engine er det så begrænset, at man ikke kan gøre det i overdrevet grad. Jeg kan fx anbefale NDjango.

  • Deldy skrev den 18. oktober:

    Hej Troels,

    Først og fremmest tak for din kommentar. Som jeg skriver sidst i posten, så er Javascript ikke løsningen på alt. Jeg giver dig meget ret i, at man skal passe meget på, med f.eks. at bruge Javascript til at give funktionaliteter, som man ønsker clienter uden javascript skal benytte. Dog er clienter uden javascript faktisk ikke så udbredt i dag, og derfor synes jeg at man skal passe på med at vægte graceful degradation for højt. Men igen, det handler om at overveje fordele og ulemper.

    Ang. en anden view engine, så har jeg endnu ikke set en, som løser dette på en pæn måde. Django's template engine, er stadig spegetti kode i mine øjne - dog løser den nogle af disse problemer lidt mere pænt end f.eks. den normale view engine.

    Jeg synes det kunne være fedt med et sprog, som gav mig mulighed for at manipulere min HTML i stil med Javascript, men samtidig gav mig mulighed for at holde min kode og HTML adskilt.

  • Troels Thomsen skrev den 18. oktober:

    Vi er til dels enige mht. graceful degradation. Jeg mener ikke, at man skal arbejde dobbelt så meget for at tilbyde alt til dem, der selv har valgt at deaktivere JavaScript, men omvendt mener jeg, at det er "god stil" at lave, så de helt basale ting virker uden (og sjældent sværere). Det får man også meget ud af selv. Hvis man nu havde en fejl i sit JavaScript, ville man ikke mangle nogle funktioner, og i forhold til søgemaskineoptimering giver det også mening at sende indholdet direkte i stedet for at kræve, at brugerens browser bearbejder det.

  • Deldy skrev den 18. oktober:

    Vi er fuldkommen enige. Hvis man har behov for at Google kan indeksere sit indhold, så er det vigtigt at huske på, at den ikke kan eksekvere javascript. Dette er dog noget, som mere kommer til udtryk ved AJAX kald.

    Det man dog lige skal have i tankerne når man laver det stunt med delete og update links, er at f.eks. blinde, ikke vil kunne bruge dit site, da de vist endnu ikke har så god javascript support i deres screenreaders? Det er dog et område jeg ikke er så meget inde i - desvære.

  • Janus007 skrev den 5. november:

    Hej Deldy og Troels

    Jeg forstår hvad I skriver og sikkert også jeres tanker for at skrive sådan... jeg er til gengæld af en helt anden overbevisning, jeg synes websiden gerne må være en rodebunke af spaghettikode - ja I læste rigtigt :).. fyr den af med inline tags, javascript og hvad ved jeg. I min verden handler det om produktivitet og ikke lige hvordan man mixer html og kode sålænge man bare holde det i præsentationslaget er alt fjong i min optik. Ofte bruges der alt for lang tid på trivielle ting, jeg husker tydeligt de gode gamle ASP-dage hvor man bankede et website sammen på nul-komma-fem og rettelser tog man on-the-fly :)

    En optimal verden for mig vil være en fælles browserstandard, MVC og så ellers en pæn struktur i servicelaget og datalaget!

  • Troels Thomsen skrev den 20. februar:

    Jeg er helt enig i, at produktivitet er vigtig Janus, men jeg synes ikke, den skal have et så stort offer, som du er villig til acceptere.

    Vi har nogle fælles browserstandarder, og det er vigtigt at overholde dem. Man behøver selvfølgelig ikke, ligesom man heller ikke som ejer af et supermarked behøver at tage hensyn til, at handicappede kan komme rundt i butikken. Det er bare helvedes usympatisk ikke at tage de hensyn, når indsatsen for at gøre det alt andet lige er begrænset.

Skriv en kommentar


Du kan bruge Markdown formatering