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.
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.
,,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”.
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.
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.
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ý ) 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í:
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ě.
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