ASP MVC - from zero to hero (2), světlo na konci tunelu

Marian Benčat       02.10.2015       ASP.NET MVC, .NET       13368 zobrazení

 

Vítejte u druhého dílu seriálu ASP MVC – from zero to hero. Zatímco první díl byl takové seznámení se samotným seriálem, u tohoto dílu se koukneme na porovnání MVC vs. WebForms. Dále si v tomto díle ukážeme hlavní přednosti ASP MVC oproti ostatním platformám, které by mohly působit jako probuzení ze zlého snu. V dalším díle, který by měl snad přijít velmi brzy po tomto, si konečně připravíme vývojový stack, který by plně mohl uspokojit vaše potřeby spojené s vývojem webových aplikací.

<- předchozí díl

MVC jako základna

Pod minulým dílem se objevila poznámka, že některé zmíněné věci se neváží přímo a pouze k ASP MVC. Je tomu skutečně tak. Tento seriál nebude primárně pouze o ASP MVC. Budeme se věnovat i návrhovým vzorům, tomu jak zlepšit svoje vývojářské schopnosti a jak usnadnit čtení svého kód. ASP MVC využijeme jako hlavní platformy, na které všechny tyto činnosti budeme provozovat a budeme je provozovat tak, aby se nám to co možná nejvíce líbilo. Veselý obličej

Vývojář, který dělá léta ve WebForms, zde tedy nalezne informace u kterých si bude moci říct “ale vždyť to já používám u WebForms také” a bude mít pravdu. Seriál může sloužit i jako rozhled o MVC pro WebForms vývojáře, ale jak jsem již řekl, je určený i pro vývojáře z jiných jazyků.

Je nyní na místě určit, proč chci psát právě o ASP MVC, proč MVC upřednostňuji před WebForms.

 

Já umím to a ty zas tohle

Na internetu existuje mnoho informací o tom, co je zaručeně lepší. Tím pádem lze i najít spousty informací o tom, že je lepší MVC, nebo naopak WebForms. Takovéto porovnání naleznete například zde:

http://www.codeproject.com/Articles/821275/Webforms-vs-MVC-and-Why-MVC-is-better

http://www.webforms.cz/WebFormsNesmrdi.aspx

 

Já tu nehodlám soudit co je pravda a co ne, jelikož podle mého názoru je jediná správná odpověď ta, kterou řekl Tomáš Herceg na konci druhého odkazu. Jsou jiné. Osobně bych to ještě rozšířil o to, že každá se hodí pro né-něco jiného, ale pro někoho jiného.

Hlavní problém WebForms jsem již zmínil v minulém článku. WebForms jsou komponentově orientované, tedy přetáhnete nějakou komponentu do stránky (případně ji ručně zapíšete pomocí XML-like syntaxe) a máte práci z větší části hotovou. Je v ní rovnou naprogramována frontendová i backendová logika a obsahuje už i nastylování.

Pokud pracujete jako sólokapr a děláte si všechny vrstvy aplikace sám, gratuluji - našli jste skvělou platformu na tento způsob práce. Pokud potřebujete upravit logiku komponenty, projedete si dokumentaci, podědíte si danou komponentu, napíšete si “renderovací” adaptér, kterým upravíte, jak bude výsledný HTML kód vypadat, upravíte si nějakým “nahackováním” vygenerovaný javascript a upravíte si kaskádový styl.

Předem vám vzdávám poklonu, protože jste zřejmě schopni vše efektivně sami dělat. Já jsem schopný tuto práci do určité míry udělat také, ale zároveň jsem si jistý jednou věcí. Jsem .NET programátor, který umí do určité míry JS, CSS, HTML, ale nikdy… nikdy nezvládnu práci v těchto odvětvích s takovou rychlostí a kvalitou, jako můj kolega, kterého je to hlavní práce. Kolega, který již má s frontendem velké zkušenosti a ví, kde mu co půjde a v jakém prohlížeči mu to bude dělat neplechu atd.

Vezměme si příklad… budu vyvíjet ve WebForms a namísto obdélníčkového tlačítka v nějakém gridu pro resetování filtrů, budu chtít kolečko u kterého bude například checkbox, který mi poví, zda si přeji resetovat všechny filtry, nebo například jen poslední 3 (kdo by to chtěl, ale budiž). Pokud mám dostatečné znalosti a zkušenosti s Javascriptem, CSS, HTML, WebForms, C#, tak to pro mě jistě nebude problém.

Pokud ale tyto znalosti dostatečné nemáte, budete muset požádat o pomoc frontendistu, který zná skvěle JavaScript, CSS, HTML. Máte ale jistotu, že to sám nezvládne. Nezná totiž Webforms ani C#. De facto není ani schopný sám podsunout dané komponentě upravený JavaScript. Zároveň bude poněkud nesvůj i z kódu samotného View:

 

<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" AllowSorting="True"
    OnNeedDataSource="RadGrid1_NeedDataSource" AllowFilteringByColumn="True"
    OnItemCommand="RadGrid1_ItemCommand" CellSpacing="0" GridLines="None">
    <GroupingSettings CaseSensitive="false" />
    <MasterTableView AutoGenerateColumns="false" TableLayout="Fixed">
        <ColumnGroups>
            <telerik:GridColumnGroup Name="GeneralInformation" HeaderText="General Information"
                HeaderStyle-HorizontalAlign="Center" />
            <telerik:GridColumnGroup Name="SpecificInformation" HeaderText="Specific Information"
                HeaderStyle-HorizontalAlign="Center" />
            <telerik:GridColumnGroup Name="BookingInformation" HeaderText="Booking Information"
                HeaderStyle-HorizontalAlign="Center" />
        </ColumnGroups>
        <HeaderStyle Width="102px" />
        <Columns>
            <telerik:GridBoundColumn DataField="BrandName" HeaderText="Brand Name" UniqueName="BrandName"
                ColumnGroupName="GeneralInformation">
                <HeaderStyle Width="170px" />
                <FilterTemplate>
                    <telerik:RadComboBox ID="BrandNameCombo" DataSourceID="EntityDataSource1" DataTextField="BrandName"
                        OnDataBound="BrandNameCombo_DataBound" DataValueField="BrandName"
                        Height="200px" AppendDataBoundItems="true" SelectedValue='<%# ((GridItem)Container).OwnerTableView.GetColumn("BrandName").CurrentFilterValue %>'
                        runat="server" OnClientSelectedIndexChanged="BrandNameComboIndexChanged">
                        <Items>
                            <telerik:RadComboBoxItem Text="Select a Brand" />
                        </Items>
                    </telerik:RadComboBox>
                    <telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
                        <script type="text/javascript">
                            function BrandNameComboIndexChanged(sender, args) {
                                var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
                            tableView.filter("BrandName", args.get_item().get_value(), "EqualTo");
                        }
                        </script>
                    </telerik:RadScriptBlock>
                </FilterTemplate>
            </telerik:GridBoundColumn>
            <telerik:GridBoundColumn DataField="Model" HeaderText="Model" UniqueName="Model"
                ColumnGroupName="GeneralInformation" FilterControlWidth="60px">
                <HeaderStyle Width="115px" />
            </telerik:GridBoundColumn>
            <telerik:GridBoundColumn DataField="Classification" HeaderText="Classification" UniqueName="Classification"
                ColumnGroupName="GeneralInformation">
                <FilterTemplate>
                    <telerik:RadComboBox ID="ClassificationCombo" Width="90px" SelectedValue='<%# ((GridItem)Container).OwnerTableView.GetColumn("Classification").CurrentFilterValue %>'
                        runat="server" OnClientSelectedIndexChanged="ClassificationComboIndexChanged">
                        <Items>
                            <telerik:RadComboBoxItem Text="All" Value="" />
                            <telerik:RadComboBoxItem Text="Hatchback" Value="Hatchback" />
                            <telerik:RadComboBoxItem Text="Sedan" Value="Sedan" />
                            <telerik:RadComboBoxItem Text="SUV" Value="SUV" />
                            <telerik:RadComboBoxItem Text="MPV" Value="MPV" />
                        </Items>
                    </telerik:RadComboBox>
                    <telerik:RadScriptBlock ID="RadScriptBlock2" runat="server">
                        <script type="text/javascript">
                            function ClassificationComboIndexChanged(sender, args) {
                                var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
                            tableView.filter("Classification", args.get_item().get_value(), "EqualTo");
                        }
                        </script>
                    </telerik:RadScriptBlock>
                </FilterTemplate>
            </telerik:GridBoundColumn>
        </NestedViewTemplate>
        <PagerStyle PageSizes="5,10" PagerTextFormat="{4}<strong>{5}</strong> cars matching your search criteria"
            PageSizeLabelText="Cars per page:" />
    </MasterTableView>
    <ClientSettings EnableRowHoverStyle="true" EnablePostBackOnRowClick="true">
        <Selecting AllowRowSelect="true" EnableDragToSelectRows="false" />
        <Scrolling AllowScroll="true" UseStaticHeaders="true" ScrollHeight="" />
    </ClientSettings>
</telerik:RadGrid>

Jak vidíte, HTML je tu pomálu a co je nejhorší - ve výsledném HTML se vám z tohoto kódu nepropíše ani jedna řádka. Namísto toho dostanete vygenerovaný kód podobný kódu níže. Je tedy problém i určit, jaká část ASPX kódu generuje jaké HTML. Pro frontendistu.

 

image

 

,,Tak frontendáři, teď mi to prosím uprav.”  Tento postup – tzv. server komponent může pro vývojáře, který zvládne s přehledem všechny vrstvy webové aplikace, být velkou výhodou. Pokud ale děláte ve firmě, kde máte samostatného frontend vývojáře, který to upravuje, tak je pro něj úprava klientské funkce velmi často noční můrou, ze které ho vyvede až .NETář, který ho v tom lepším případě obejme a sdělí mu: ,,Tak já to nějak udělám”.

Frontend ve webforms

 

 

info

Podobných pocitů lze ale docílit u vašeho frontendáře i u ASP MVC, pokud budete používat tzv. HTML Helpery, tedy budete mít ve stránce kusy kódu uvedeného níže. S tím si frontendář příliš také neporadí. Z tohoto důvodu se pokusíme předcházet HTML helperům u finálního kódu. Přesto že jsou HTML helpery skvělé na rychlost vývoje a nějaké “mockupování” stránek, dosti často komplikují nějakou customizaci. U WebForms můžete také používat čisté HTML a úplně se zbavit serverových komponent. V tento okamžik jste se ale zbavili toho, co dělá WebForms, WebFormsy - tedy stavové, serverové komponenty.

@(Html.Kendo().Grid<KendoGridAjaxBinding.Models.Product>()
      .Name("grid")
      .DataSource(dataSource => dataSource // Configure the grid data source
          .Ajax() // Specify that ajax binding is used
          .Read(read => read.Action("Products_Read", "Home")) // Set the action method which will return the data in JSON format
       )
      .Columns(columns =>
      {
          // Create a column bound to the ProductID property
          columns.Bound(product => product.ProductID);
          // Create a column bound to the ProductName property
          columns.Bound(product => product.ProductName);
          // Create a column bound to the UnitsInStock property
          columns.Bound(product => product.UnitsInStock);
      })
      .Pageable() // Enable paging
      .Sortable() // Enable sorting
)

Toto je tedy přístup, který vám základní použití zjednoduší, ale zkomplikuje nějakou customizaci a především velmi zkomplikuje nějakou “dělbu práce”. Nakonec narazíte na nějakou věc, na kterou není toto FLUENT API připraveno a dopadnete stejně tak, že buďto opět podědíte a něco připíšete (.NETář), nebo se kouknete, jaké HTML to vygenerovalo, zkopírujete ho a ručně upravené vložíte přímo do kódu (pokud jste frontendista, co moc neví, jak WebForms funguje).

Serverem vygenerovaný HTML kód nemusí být vždy špatný, záleží ale velmi na situaci a především na tom, co generuje. Zároveň tu předem chci říct WebForms vývojářům, že v MVC budou pravděpodobně nějakou dobu postrádat právě tyto serverové komponenty.    Na oplátku můžete očekávat donášku snídaně od vašich kolegů, kteří pracují na frontendu.

Budeme se ale snažit psát náš kód takový, aby byl co nejblíže tomu, co se pak dostane na prohlížeč. Tím nemyslím to, že nějaké opakující se údaje budeme psát stylem  Ctrl+C –> 150x Ctrl+V, ale budeme se vyhýbat generování komponent na straně serveru.

 

Vlastnosti .Netu / MVC, které pravděpodobně velmi uvítáte

V této sekci se podíváme na to, čím by vás .NET a MVC mohlo potěšit, obzvláště pokud přicházíte z jiných technologií. Předem upozorňuji, že je opravdu nutné znát alespoň základy programování, nebudu zde totiž učit C#.

 

Někteří mají občas pocit, že mohou vyvíjet webové stránky bez jakékoliv

vědomosti o programování, leč není tomu tak.PHP problem

Dospělý a rozumný jazyk

Jazyk C# je tu už poměrně dlouhou dobu (od roku 2000), spadá do rodiny C-jazyků, tedy syntakticky vychází z C/C++. Co se týče OOP věcí navíc, nechal se inspirovat jazykem Java. Jeho syntaxe je tedy velmi čistá a srozumitelná, k tomu mu napomáhá hned několik věcí, ke kterým se ještě vyjádřím. Co ocení někteří vývojáři z jiných jazyků, je konzistence C#. Některé jazyky vznikaly jako pouliční směs jazyků jiných a na některých se to opravdu škaredým způsobem podepsalo. Ti nejhorší mutanti dokonce ani nedbají na nějakou selskou logiku.  Jako příklady na všechny tyto neduhy budu používat především PHP a JavaScript, né že by byly ve všem nejhorší, ale dobře se to na nich ukazuje, tak mě prosím předem omluvte.

 

"foo" == TRUE

"foo" == 0


ale

TRUE != 0

 

 

Strongly-typed jazyk, striktně omezená dynamika a zcela bezpečné implicitní konverze

Ač nejsem věřící, tak opravdu děkuji bohu, že C# není dynamický jazyk! Na rozdíl od některých jiných jazyků, jako je PHP a JavaScript, jsou všechny typy v C# předem určeny a jsou kontrolovány jakékoliv operace s nimi. Jakákoliv modifikace, přiřazení, porovnávání – to vše musí odpovídat daným typům a neprobíhá tam žádná magical implicitní konverze. Ptáte se proč je dynamika špatná? Nejdříve si probereme proč je dobrá. Ušetří to pár slov v kódu… Tak to by jsme měli probrané veškeré klady. Nyní ty zápory.

Na vysvětlení si vypůjčím oblíbený kód z PHP, na kterém se tento průšvih velmi lehce objasňuje:

V PHP existuje například funkce STRPOS(), která slouží k nalezení substringu ve stringu.

Funkce strpos() vrací číslo, pokud se v řetězci nachází jiný řetězec poslaný jako argument. Pokud se tedy hledaný řetězec nachází na pozici 0, vrátí funkce hodnotu 0. Myslíte si, že pokud se tam daný řetězec nenachází, vrátí tato funkce například –1, jako to dělají vesměs všechny ostatní jazyky? Ale co vás nemá. Pokud řetězec neobsahuje hledaný  řetězec, vrátí FALSE. Tedy bool hodnotu. Ponechme stranou, že už tato funkce je sama o sobě silně nekonzistentní a špatná, přidejme si k tomu “úžasnou” implicitní konverzi (0 ~= false) a máme na světě  mnohem vážnější problém:
 
 
strpos($haystack, $needle) == false -> true pokud je na offsetu 0
strpos($haystack, $needle) === false -> false pokud je na offsetu 0
strpos($haystack, $needle) == false -> true pokud tam není
strpos($haystack, $needle) === false –> true pokud tam není

 

 

Tady objev a odstranění takovéto chyby nemusí být zase tak složitý, ale zkuste návratovou hodnotu této podmínky vracet například z několika funkcí. Zábava na večer u debugu cizího kódu je zaručena.

Zde je vidět i další silný neduh některých jazyků, silná schizofrenie - jedná se o jazyk objektový, nebo funkcionální?  Jsou tam přeci třídy, objekty a přitom voláme funkci, jak v klasickém C.


Podívejme se ještě na jeden kód z oblíbeného jazyka JavaScript:
 
var myFunction = function () {
    return "set up, only called once";

    myFunction = function() {
        alert("no set up code");
    }
}
var a = myFunction(); alert( a );
var b = myFunction(); alert ( b );

 

 

Zde se jedná o redefinici funkce sebe sama, během prvního vykonání. Zatímco poprvé tedy funkce vrací řetězec, podruhé může vrátit úplně něco jiného, nebo vůbec nic...  Zdá se vám to hezké? Mně příliš ne a tomu, kdo by tuto moji funkci používal, to pěkné nepřijde už vůbec. Zde slýchávám velmi často jeden argument:

,,Prasit se dá v každém jazyku”

S tímto souhlasím, né každý jazyk je ale naprosto “zprasený” už v základu od autora, takže nabádá k udržování této kvality kódu.

V dynamicky “netypových” jazycích se lze setkat ještě s věcmi, které jsou kvůli dynamice nutné a jak by řekla jedna známá               osobnost - člověka pouze obtěžují. To je především rozdíl mezi “==” (které je vlastně polo k ničemu) a “===”. Kde se u druhého porovnává i shodnost “typů”.  U dynamických typů nás poté otravuje i další nutnost a sice kontrola, zda už byla daná properta “nasetována” (undefined) , nebo zda je pouze prázdná (null).

 

C# je co se týče implicitních konverzí ještě bezpečnější, než C++. Nedochází zde tedy například ani k implicitní konverzi z bool na integer a naopak.

pitfall

V .NETu a potažmo i ASP MVC existuje také dynamický typ , resp. keyword dynamic, který lze použít například u třídy ExpandóóóuObject. (ExpandoObject – byl to pouze pokus, jak ukázat, že je jazyk skutečně kouzelný Veselý obličej ) Na první pohled se může zdát, že C# je také dynamicky typovaný jazyk. Ve skutečnosti se jedná pouze o takový syntactic sugar. ExpandoObject, jednoduše řečeno, obsahuje Dictionary se seznamem všech propert. Pokud tedy použijete object.Age, ve skutečnosti se zavolá metoda .GetProperty(“Age”),  která najde na základě klíče hodnotu v Dictionary a tu vrátí (opět zjednodušeně řečeno). Já vás ale předem prosím, ať to pokud možno nepoužíváte. Je to zlo a přicházíte k .NET možná právě proto, aby jste se ZLA zbavili.

 

Takováto dynamika je spíše na škodu, než-li k pomoci. Výše uvedené jazyky si to už naštěstí uvědomily a tak nové verze už počítají s rozumnými změnami, například přechod z prototypové dědičnosti na normální třídní přístup, případně právě dynamicky typované proměnné.

Přeloženo – “bylo to strašně super, ale jen na papíře”, proto se kompletně změní ECMAscript 6 a PHP.

 

Threading model, paralelní, asynchronní programování

Tady u této kategorie musím předem říct, že se jedná o můj podpásový argument, když se mě někdo zeptá, proč nepoužívat PHP a JavaScript na serveru. Narozdíl od JavaScriptu  jsou si ale PHP programátoři naprosto děsivé (ne)implementace paralelního programování v PHP vědomi. V JavaScriptu si z nějakého pro mě nepochopitelného důvodu obhajují callback model a co hůře... i na serveru.  V JavaScriptu se tedy v tom horším případě použije callback hell:

doAsync1(function () {
  doAsync2(function () {
    doAsync3(function () {
      doAsync4(function () {
    })
  })
})

V lepším poté například nějaká promise knihovna a trošku to vylepší a obalí to sérií .then() na pokračování…

 

somethingAsync().then(function (n) {
  return somethingElseAsync(n);
})
.then(function (n) {
  return somethingElseAsync(n);
})
.then(function (result) {
  // ...
})

A v úplně nejlepším případě použijí nějaký návrhový vzor.  Co se týče PHP, jsem přesvědčený o tom, že PHP programátoři ví, o čem mluvím.

Funkční správa paměti a jiných zdrojů

Prostředí .NET používá automatickou správu paměti, to znamená, že není potřeba ručně alokovat paměť a ručně ji zase uvolňovat. Je ale důležité vědět alespoň základ, jak to funguje. Kolikrát mě šokuje, jak často si někteří programátoři myslí, že v okamžiku, kdy je tam Garbage collector, tak nelze vytvořit žádný memory leak. Garbage collector uvolní nepotřebnou paměť až v okamžiku, kdy objekt není skutečně potřeba. Jak to pozná? Vnitřně si udržuje reference na konkrétní objekty. Pokud na základě této a dalších informací zjistí, že už se nelze k objektu nikterak dostat, paměť uvolní. Kdy? Někdy. Především až se mu to bude hodit a pokud možno v době, kdy tato náročná operace nebude nikomu vadit a nebude brzdit program. Vysvětlení celé funkce Garbage collectoru, není rozhodně na jeden odstaveček a pokud chcete zjistit více, můžete se dočíst například zde:

Under the Hood of NET Management

Samozřejmě každý z jazyků, který se v současném světě používá, uvolní po skončení vykonávání programu / scriptu využitou paměť. Je ale třeba správně pochopit, co je memory leak – nejedná se pouze o paměť, která není uvolněna po skončení programu, ale i o paměť, kterou není nutné použít (nebo nadále používat) a přesto není navrácena zpět systému. 

Argument, že po skončení vykonávání scriptu PHP, který jede 15 minut a “zpapá” 2,5 GB paměti, vše zase uvolní, přesto že si ostatní vystačí s 80MB, je tedy zcela invalid.  Ano… i u PHP lze zapnout garbage collecting, který od verze 5.3 i občas funguje. Přesto u větších dat často padá, vytuhává, případně si pár minut počkáte. Proč to píši…?  Nesnažím se zde o žádný hate, ať si každý zhodnotí, jak je spokojený. Slibuji vám, že tyto problémy vás na .NETu trápit nebudou.

Samostatnost C#

C# není jazykem, který je přímo omezený na webové technologie. Bez větších problémů jste v něm schopni napsat s pár výjimkami cokoliv – konzolovou aplikaci, desktopovou aplikaci, mobilní aplikaci, webovou aplikaci, real-time server, ovládat s ním nějaký kus hardwaru, provádět složité výpočty, atd... Toto není u jazyků typu PHP, JavaScript  možné… Jsou velmi specificky určené a pokud budete potřebovat něco jiného, musíte si napsat nějaký MODUL do serveru. Tento modul rozhodně nebudete psát v JavaScriptu, ani v PHP, ale budete muset šáhnout po C/C++. Dalším častým omezením je jejich rychlost a paměťová náročnost.

 

Rychlost a paměťová náročnost

Je zde třeba brát v úvahu rozdíly mezi rychlostí dané technologie a propustností daného frameworku. Zatímco rychlost se uvádí většinou v době, kterou stráví CPU nad vykonáváním určitého úkolu, propustností rozumíme kolik operací (v našem případě většinou requestů), zvládne server zpracovat za jednotku času - většinou se tedy měří v REQs/Sec. .NET je na tom výborně co se týče rychlosti samotného výpočtu, co je ale v základu horší, je nějaká propustnost – tedy kolik je schopný obsloužit požadavků. Pro představu jak je to s rychlostí, přikládám následující tabulku – jedná se o časy CombSort algoritmu. Po rozkliknutí odkazu naleznete více informací:

CombSort porovnání

která je převzata z tohoto webu:

http://kokizzu.blogspot.be/2015/02/numeric-combsort-benchmark-updated.html

.NET C# by se v této tabulce nacházel někde přibližně mezi clang a javou, co se týče Runtime Duration. Po stránce paměťové poté využívá opravdové minimum.

Jak jsem ale řekl, můžete nalézt na internetu i hodně porovnání nějaké propustnosti, především pak například ASP MVC vs. Node.js, kde .NET né příliš překvapivě dostane nakládačku od JavaScriptu na serveru... Odpovědět na otázku proč tomu tak je, není příliš obtížné. Zatímco request->response lifecykle na NodeJS je poměrně dosti primitivní, na .NETu za vším stojí poměrně velká mašinérie. To že  jde v těchto testech o velmi primitivní operace, kde se téměř ihned jen vrací response také velmi zvýhodňuje threading model Node.js a znevýhodňuje threading model .NETu, využívající thread pool, jelikož práce s touto administrací vláken je už znatelná v porovnání s nic neděláním v samotném requestu. Zkuste si ale udělat jednoduchý server v konzolové aplikaci .NET za pomoci např. HTTPListeneru, omezit funkcionalitu na to, co dělá holý Node.js. Budete určitě mile překvapeni.

 

Generické programování, Aspektově orientované programování, Generování kódu – T4 šablony

V C# lze samozřejmě plně využít generického programování. Už v základu, bez nějakých přídavných modulů, precompilování nebo nějaké pseudo generiky za porušení několika OOP principů. To vám ušetří ohromné množství práce a především zlepší kvalitu kódu. Zbavíte se tak neustálého kopírování jedné třídy, ve které upravujete pouze pár řádek.

C# rovněž podporuje Aspektově orientované programování. Co to znamená? Označíte třídu, metodu, propertu nějakým “aspektem” a tím ji vybavíte novou funkcionalitou kterou by jste jinak museli připisovat všude ručně.

 

info

Aspekty s sebou nepřinášejí vždy pouze pozitiva. Existuje ale několik typů, co se týče jejich implementace a způsobu použití. Jednotlivé typy a jejich použití si v dalších dílech seriálu ukážeme.

 

 

Generování kódu. Jedna z nejsilnějších zbraní .NETu a Visual Studia. Tímto nemyslím pouze to, že můžete vygenerovat .NET kód, ale například na základě .NET kódu vygenerovat například frontendovou část, databázi atp. K tomu se nám budou hodit již zmíněné aspekty. Mezi věci, které si ukážeme hned v prvních dílech, je generování validace, na základě aspektu na propertách.  Dále si ukážeme v našem seriálu generování TypeScriptových souborů na základě našich .NET souborů. Taká si necháme vygenerovat celou AngularJS servisu pro komunikaci se serverem, na základě našeho WebAPI a našich Data objektů. Nenapíšeme tedy ani řádek TypeScriptu a budeme mít vygenerovanou strongly-typed komunikaci se serverem, kde budeme pracovat s konkrétními typy a to opět díky TypeScriptu.

Debugování, profiling - var_dump(), echo(), xdebug, debugger; enjoy.

Přestože se už naštěstí debug nástroje pro některé jazyky vyvinuly, pořád je to taková polo katastrofa, která vám ve většině případů umožní nějaký step by step debugging a variable watch. Složitější debuggingu, či profilling pro vás znamená většinou otevřít si nějakou konzoli a ve stylu GDB / valgrind zjistit, co se vlastně děje. Pokud vám toto vadí, mám pro vás dobré zprávy. Ve Visual Studio a .NET VM můžete debugovat, jak se vám zlíbí.

 

Shrnutí – jack of all trades? (Master of none?)

Jak jste si jistě už všimli, je tu hodně chvály na .NET a naopak dostatek kritiky na ostatní “webové” jazyky. Tento díl tedy může vyznít pro mnohé z vás, jako že jsem Microsoftem placený, případně nějaký MS #fanboy. Stojím si zde ale za svým a sice, že pravda je někde jinde. Zkoušel jsem hodně jiných jazyků, neustále zkouším, zkoumám, praktikuji – snažím se neusnout na vavřínech. Přesto všechno jsem prozatím ale nenašel nic, co by mi mohlo alespoň z části nahradit komfort, použitelnost a výkon, co mi poskytuje právě .NET ASP MVC.  Potřebuji messaging – .NET mi stačí, potřebuji nějaké složité výpočty – s .NETem si vystačím, prostě si napíši systémovou službu Windows - s tou mohu komunikovat například přes WCF, Message Queue, WebAPI. Toto mi žádná jiná platforma (částečně Java) neposkytne, vždy budu něčím omezený a budu muset zkombinovat několik technologií.

Nijak vám tedy nenutím moje názory na ostatní platformy, udělejte si vlastní názor a nejlépe vyzkoušejte vše, co budete moci. Tak jak se o to pokouším i já sám.

Z výše zmíněných důvodů se může zdát, že nevidím na .NETu problémy, překážky. Není tomu tak. Na problémy určitě i vy narazíte a pokud jste povahy stejné jako já, budou i lítat třísky a tvrdší slova. Právě proto, že každá technologie má své pro i proti, z mé tabulky  vítězně vzešel právě .NET. Přál bych si, aby tomu bylo i u vás.

Přesto, že jsme neprobrali všechny věci, co vám udělají při vývoji radost – například jsme zcela vynechali velmi pěkný scaffolding (který můžete znát z RoR), už zanecháme nějakého porovnávání a dáme se do práce – instalace toho, co budeme potřebovat.

Hodně programátorských úspěchů,

MB

 

hodnocení článku

-1 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

 

 

Nový příspěvek

 

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

Další díl

Už jsem nedočkavý následujícího dílu.

Konečně (další) profesionál, který se rozhodl podělit se o své načerpané znalosti.

Kdy tedy bude další díl?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

děkuji za přízeň. Jak jsem odpověděl na komentář pod vámi, mám rozepsané dva díly. Jeden je před korekturou, druhý je z 50% hotový.

MB

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Další díl?

Dobrý den, jak to vypadá s dalším dílem? Už se nemůžu dočkat...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

další díl mám dopsaný a chystám se mu už pouze udělat jazykovou korekturu, jelikož se ale věnuje vývojovému stacku a toolingu, konkrétně:

Visual Studio 2013 with Update 5

WebEssentials

Visual Studio Online

ReSharper

PostSharp

StyleCop

GhostDoc

TypeScript

NUGET

a nabízí tedy spíše jen popis MVC a solutionu, chtěl jsem vydat dva díly současně, kde druhý se věnuje View a záležitostem ve spojení s ním...

Především z toho důvodu, že nechci aby to vypadalo, že se budu věnovat pouze teorii. Tedy další díl mám už dopsaný a ten následující po něm (View, Helpery, Scaffolding,..) mám zhruba z 50%.

Rád bych tedy vyčkal na dopsání i toho dalšího dílu a vydal rovnou dva najednou.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Styl článku

Z odborného hlediska to přelouskám, ale nedala by se tomu článku udělat alespoň základní jazyková korektura? Je to fakt síla.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Dobrý den,

můžete uvézt příklady prosím? Asi tuším co máte na mysli a na korekturu se chystám, ale pro jistotu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jejda, kde jen začít?

"si konečně připravíme vývojový stack" nekorektní mezery

"potřeby, které jsou ve spojení s vývojem webových aplikací" - chybná stylistika

"ASP MVC zde bude ale použito jakožto hlavní platformy" - chybné skloňování

"Já tu nehodlám rozsekávat, co je pravda a co ne, jelikož podle mého názoru, je jediná správná odpověď ta, kterou řekl Tomáš Herceg na konci druhého odkazu" - chybně čárky

"tedy Drag&Dropnete nějakou komponentu do stránky " - czenglish

"Vezměme si příklad.. budu vyvíjet ve WebForms" - interpunkce

" že to sám nezvládne.. " - nadbytečná tečka

[fakt to nebudu číst celé]

"Jak jste si jistě už všimnuli" - všimli

"prostě si napíši windows servicu" - systémovou službu Windows / Windows Service

"Todle mi žádná jiná platforma (snad vyjma Javy) neposkytne" - nespisovné

začněte asi odstraněním nadbytečných mezer, pak byste mohl všude psát .NET místo .net, pak čárky v souvětích, atd. atd.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Aha rozumím, tedy se vám opravdu jedná o to, aby byl článek zcela spisovný a stylisticky v pořádku. Úpravy odpoledne provedu.

Máte nějaké poznámky k samotnému obsahu?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

K obsahu? Píšete rozvláčně, což mi osobně vyhovuje. Já jsem v ASP.NET MVC udělal kdysi jediný projekt, jinak se specializuji spíš na desktop, čili rád se něco naučím. Co osobně vidím jako největší výhodu ASP.NET oproti například PHP je fakt, že můžu generovat cokoliv na výstupu z aplikace - jako je třeba Excelová tabulka nebo dokument v PDF. U PHP ten Excel jde složitě a PDF se smysluplným formátováním vlastně vůbec.

Takhle v APS.NET použiju - já nevím - třeba ActiverReports a úplně stejné reporty budu mít jak z desktopu, tak z webu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Opravil jsem, co bylo v mých silách a hlavně, co jsem byl schopný opravit z posledních zásob energie pro dnešek.

Snad vám tedy už stylistika tolik nebude kazit čtení.

S pozdravem,

MB

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Osobne si myslím, že Petra si netreba všímať, je to predsa napísané tak, ako sa dnes programátori bežne vyjadrujú, keď spolu komunikujú. V takýchto článkoch nemá význam zaoberať sa do detailov tým, či je to po všetkých stránkach správna čeština, pokiaľ tam nie sú vyslovene oči-trhajúce chyby - a to nie sú. Energiu radšej venujte písaniu ďalších pokračovaní.

Vďaka za zaujímavý seriál.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý večer,

osobně se nacházím někde "mezi" vaším názorem a názorem Petra. V prvním znění se nacházely chyby, které trhaly i mě za oči, jako například "všimnuli" a chyby ve skloňování. Takovéto chyby jsem tedy i rád opravil a děkuji za upozornění.

Pak jsou ale věci, které mi opravdu braly energii a sice věci jako mezera za větou a hlavně pouze 1 mezera za slovem. Může za to především program Live Writer, který je zde použit a který mi bohužel každé 2 minuty vytuhne, případně nemilosrdně spadne. Navíc jsem nepřišel na to, jak do něj narvat nedělitelnou mezeru mezi předložkou a slovem a tak jsem si tam právě vypomáhal více mezerami, aby mi to hodilo celé na další řádek.

Děkuji vám za podporu a už pracuji na dalším dílu, který se bude věnovat instalaci vývojového prostředí + toolingu a už se koukneme na samotné MVC.

MB

nahlásit spamnahlásit spam 0 odpovědětodpovědět

"protože jste zřejmě schopni vše efektivně samy dělat"

Ale jinak moc pekny clanek ;) Doufam, ze priste uz to bude jenom o MVC a spise technicke

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,

opraveno. Děkuji za upozornění. Mám rozepsané další 2 díly. Předpokládám, že je tento víkend dokončím a vydám.

Díl třetí bude o vývojovém stacku (VS, WebEssentials, Visual Studio Online, Resharper, PostSharp, StyleCop, GhostDoc, TypeScript, Nuget) a o tom z čeho se skládá solution.

Díl čtrvtý už se poté podrobně věnuje view, základum routování, controllerů a podrobněji jak předávat do view data. Dále HTML helperum, psaní vlastních helperu atd.

Děkuji za zachování přízně.

MB.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Za mě OK

Hezký den,

mě tento styl psaní sedí i přes drobné chyby. Co se týče obsahu, tak mi nedal nic, co už jsem nevěděl. No, už se tím nějaký ten pátek živím. Ale věřím, že pro PHPčkaře a spol. je dobrou motivací přejít (nebo alespoň vyzkoušet).

PS: Jedna jediná chybka mi zůstala v paměti a to, že někde píšete "přesto že", píše se dohromady "přestože". Možná už je opraveno.

R.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback