Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, s.r.o. haken@havit.cz, @RobertHaken. Perly code-review z praxe

Podobné dokumenty
[ASP].NET Worst Practices

[ASP].NET Worst Practices

Zápis programu v jazyce C#

1. Téma 12 - Textové soubory a výjimky

Čipové karty Lekařská informatika

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 3.4.

Jazyk C# - přístup k datům

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 19.2.

Code Contracts. Robert Haken [MVP ASP.NET, MCT] Software architect, Owner at HAVIT, s.r.o. knowledge-base.havit.cz

Příklad aplikace Klient/Server s Boss/Worker modelem (informativní)

Typický prvek kolekce pro české řazení

KTE / ZPE Informační technologie

Západočeská univerzita v Plzni Katedra informatiky a výpočetní techniky. 9. června krovacek@students.zcu.cz

Tabulková data. budeme pracovat s CSV soubory položky oddělené středníkem, např.

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

PREPROCESOR POKRAČOVÁNÍ

Distribuované systémy a výpočty

Generické programování

Jazyk C# (seminář 6)

Jazyk C# - přístup k datům

OOPR_05. Případové studie

Návrh softwarových systém. Návrh softwarových systémů

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 10.4.

IW5 - Programování v.net a C# 4 Pokročilé konstrukce C#

Přehled probírané látky

Jazyk C# - přístup k datům

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Kolekce, cyklus foreach

PŘETĚŽOVÁNÍ OPERÁTORŮ

Úvod do programovacích jazyků (Java)

5 Rekurze a zásobník. Rekurzivní volání metody

SOUBORY, VSTUPY A VÝSTUPY POKRAČOVÁNÍ

Jazyk C# (seminář 3)

Agenda. Docházka Návrat k minulému praktickému cvičení Zápočtové práce. Dokumentace. Dotazy, přání, stížnosti. Co, jak a proč dokumentovat

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Výčtový typ strana 67

Vláknové programování část V

20. Projekt Domácí mediotéka

Programování v jazyku C# II. 5.kapitola

Druhy souborů. textové. binární. nestrukturované txt strukturované - ini, xml, csv. veřejné bmp, jpg, wav proprietární docx, cdr, psd

Algoritmizace a programování

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

RMI Remote Method Invocation

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

typová konverze typová inference

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Indexové seznamy. známe už pole, kde ale musí být předem známa velikost indexové seznamy umí růst dynamicky

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Java a XML. 10/26/09 1/7 Java a XML

Abstraktní datové typy: zásobník

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

Regulární výrazy. Vzory

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Vytváření a použití knihoven tříd

UJO Framework. revoluční architektura beans. verze

Úvod do programování - Java. Cvičení č.4

17. Projekt Trojúhelníky

Java a Caché IV: Manipulace s objekty

PG 9.5 novinky ve vývoji aplikací

Simulace. Martin Pergel

Pro kontrolu správného formátu hodnoty N použijeme metodu try-catch.

Návrh a tvorba WWW stránek 1/14. PHP a databáze

Skripty základy VB, vestavěné objekty, příklady

ADT/ADS = abstraktní datové typy / struktury

KIV/PIA 2013 Jan Tichava

Java - řazení objektů

Tvorba informačních systémů

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Úvod do programování v jazyce Java

Osnova přednášky. Programové prostředky řízení Úvod do C# II. Přístup ke členům. Členy (Members)

Dědičnost (inheritance)

Programování v Javě I. Leden 2008

Jazyk C# a platforma.net

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Základní pojmy. Matice(řádky, sloupce) Matice(4,6) sloupce

ISZR Referenční agent.net

Distribuované systémy a výpočty

Jazyk C# (seminář 5)

První kapitola úvod do problematiky

KTE / ZPE Informační technologie

Fakulta elektrotechniky a informatiky Univerzita Pardubice 2014/2015. poslední přednáška a materiál k samostudiu

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

Programování v Javě I. Únor 2009

PL/SQL. Jazyk SQL je jazykem deklarativním, který neobsahuje procedurální příkazy jako jsou cykly, podmínky, procedury, funkce, atd.

Jazyk C# a platforma.net

Object-relational mapping (JPA, Hibernate)

Java Výjimky Java, zimní semestr

Textové soubory. alg9 1

SOUBORY, VSTUPY A VÝSTUPY POKRAČOVÁNÍ

Nové prvky v C# 3.0. David Keprt

Příkazy a řídicí struktury v Javě. Tomáš Pitner, upravil Marek Šabo

Výjimky. v C# a Javě

Teoretické minimum z PJV

Třídy a objekty. Třídy a objekty. Vytvoření instance třídy. Přístup k atributům a metodám objektu. $z = new Zlomek(3, 5);

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

HTTP. Webový server. generátor HTML stránek (CGI, Perl, PHP, Python, Ruby, Java, ASP.NET) zpracování požadavku/ odeslání odpovědi.

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Transkript:

Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, s.r.o. haken@havit.cz, @RobertHaken Perly code-review z praxe

Task: Přidej do sloupce Název info-baloon

Co je code-review? druhé vývojářské oči komunikace dvou (nebo více) rovnocennýchstran revize a návrhyna vylepšení zvoleného způsobu implementace srozumitelnosti kvality implementace obecně rychlá zpětná vazba nástroj zvyšování kvality produktu nástroj zlepšování týmu

Výsledek:

Výsledek:

Co není code-review? testování kontrola dodržování standardů kódování StyleCop, FxCop(CodeAnalysis) Formy code-review pre-commit review post-commit review příležitostné konzultace pair-programming

lock(new object()) // thread-safe...všude píšou, že stačí lockna newobject private object mylock = new object(); lock(mylock)...

Kategorie Provizornosti

/// <summary> /// Vrací seznam všech záznamů z tabulky LoginLog. /// </summary> /// <param name="datefrom">datum od pro dotazy</param> /// <param name="dateto">datum do pro dotazy</param> /// <returns>vrací kolekci objektů typu "LoginLog" s načtenými daty.</returns> public static IEnumerable<DateTime> GetListChartLoginLog( using (Context ctx = new Context()) return ctx.loginlogs DateTime datefrom, DateTime dateto).where(x => x.date >= datefrom && x.date <= dateto && x.login).select(x => x.date).orderby(x => x).tolist(); Pečlivá dokumentace. Copy-Paste?

public bool KontrolaParametru(out string message) message = string.empty; return true; // WTF? Jednotka dočasnosti = 1 FURT

SELECT Faktura.FakturaID FROM Faktura WHERE (1 = 1) AND (Deleted IS NULL) AND (SmerFaktury = @SmerFaktury) AND (Faktura.TypFakturyID IN (SELECT Value FROM @TypFakturyID))...aby mi to hezky zarovnávalo

public static Task RunDelayed(int milliseconds, Action action) return Task.Run(async delegate ); await Task.Delay(1000); action(); Tzv. tvrdý default?

Proč code-review? Vývojář -autor Dostávám zpětnou vazbu a učím se. Vím, že to po mě někdo uvidí. Snažím se, abych se za to nestyděl. Vývojář -reviewer Tým Inspiruji se prací jiných, učím se. Stojí o můj názor, realizuji se. Chci-li někomu něco vytýkat, sám to musím dělat správně. Zkracuje se doba na odhalení některých problémů -snažšíkorekce. Zrychluje se adaptace nových členů týmu. Posiluje se týmové pojetí projektu.

Kategorie Věřím si, netestuji

MySuperGrid.SortExpression = "Date.DayOfWeek"; DateTime.DayOfWeek Property Remarks The value of the constants in the DayOfWeek enumeration ranges from DayOfWeek.Sunday to DayOfWeek.Saturday. If cast to an integer, its value ranges from zero (which indicates DayOfWeek.Sunday) to six (which indicates DayOfWeek.Saturday). Prvním dnem je neděle. :-(

private void BindData() var procesy = Process.GetProcesses(); procesy.orderby(i => i.processname); MySuperGrid.DataSource = procesy;...ty systémový věci jsou nějaký divný. private void BindData() var procesy = Process.GetProcesses(); MySuperGrid.DataSource = procesy.orderby(i => i.starttime);

[Flags] public enum TreeNodeType Normal, Linked, Locked if (t.hasflag(treenodetype.normal)) // WTF? always true! [Flags] vždy s hodnotami, jinak je Normal= 0, Linked= 1, Locked= 2,... [Flags] public enum TreeNodeType Normal = 1, Linked = 2, Locked = 4 // 8, 16,...

Kategorie Proč to dělat jednoduše, když to jde složitě?

query.dateto = DateTime.Today.Date;...pro jistotu. // DateTime class public static DateTime Today get return Now.Date;

// Parsuje z formátu 19901231 public static DateTime? DateFromXmlString(string value) if (string.isnullorempty(value)) return null; return DateTime.Parse( string.format( "2.1.0", value.substring(0, 4), value.substring(4, 2), value.substring(6, 2)), CultureInfo.CreateSpecificCulture("cs-CZ"), DateTimeStyles.None); public static DateTime? DateFromXmlString(string value) DateTime date; if (DateTime.TryParseExact(value, "yyyymmdd", CultureInfo.CreateSpecificCulture("cs-CZ"), DateTimeStyles.None, out date)) return date; return null;

C# 6.0 -Declaration expressions public static DateTime? DateFromXmlString(string value) if (DateTime.TryParseExact(value, "yyyymmdd", CultureInfo.CreateSpecificCulture("cs-CZ"), DateTimeStyles.None, out var date)) return date; return null;

public int GetHashCode(DuplicitaOvereniKontrolniAkceStructure obj) if (!obj.overeniid.hasvalue) return string.empty.gethashcode(); return obj.overeniid.value.gethashcode(); public int GetHashCode(DuplicitaOvereniKontrolniAkceStructure obj) return obj.overeniid.gethashcode();

var posledniradekprojekt = Faktura.Items.Last(o => o.poradi == Faktura.Items.Max(v => v.poradi)).projekt; Poslední z posledních?.last(predicate) // odpovídá.where(predicate).last()

int fakturaid = result.faktura.id; Faktura faktura = (fakturaid == 0)? result.faktura : fakturarepository.getfakturabyid(fakturaid);...takhle už to nevypadá tak machrovsky: Faktura faktura = result.faktura;

DataSet dsresult = new DataSet(); SqlDataAdapter mydataadapter = new SqlDataAdapter( "SELECT COUNT(*) FROM Uzivatel", "**ConnString**"); mydataadapter.fill(dsresult); string count = dsresult.tables[0].rows[0][0].tostring(); dsresult = null; Není to náhodou ExecuteScalar? int count2 = (int)cmd.executescalar();

Task: Importuj jen druhy 2, 4 a 5 int[] nenacitanedruhy = new int[] 1, 3, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 50, 51, 52, 53, 54 ; if (!nenacitanedruhy.contains(druhzakazky)) // importuj Pozitivní přístup!

Kategorie Performance killers

private readonly Dictionary<string, string> localizedurls; private string GetUrl(string lang) if (localizedurls.containskey(lang)) return localizedurls[lang]; return "/"; private string GetUrl(string lang) if (localizedurls.trygetvalue(lang, out string url)) return url; return "/"; Proč hledat dvakrát?

private readonly Localization[] items; public string GetLocalization(string key, CultureInfo culture) return items. Where(x => x.equals(new Localization(key, culture))). Select(x => x.text). FirstOrDefault(); public bool Equals(Localization other) if (object.referenceequals(other, null)) return false; return (Key.Equals(other.Key) && LCID.Equals(other.LCID));...kterak potěšit GarbageCollector stovky řetězců per Page tisíce Localizations v items >200 000 volání constructoru per Page

private void Page_Load() // graf s počty přihlášení po dnech za dané období IEnumerable<DateTime> data = LoginLogService.GetListChartLoginLog( frompicker.selecteddate, topicker.selecteddate); DateTime dt = frompicker.selectedvalue; List<LoginStatistic> list = new List<LoginStatistic>(); while (dt <= DateTime.Today) list.add(new LoginStatistic Date = dt, Count = data.where(x => x.date == dt).count() ); dt = dt.adddays(1); MyChart.DataSource = list; MyChart.DataBind(); Výkonová optimalizace! Stačí, když to spočítám do dneška, v budoucnu žádná data přihlášení nejsou.

Kategorie Coding culture

// Kontrola vyplnění RČ a IČ dle právní formy if (akce.dotaceprijemcepravniformatyp == 1) chybaakce = "Pro typ '1' musí být zadáno RČ a nesmí být vyplněno IČ!"; if (akce.dotaceprijemcepravniformatyp == 2) chybaakce = "Pro typ '2' musí být alespoň jedna z položek RČ a IČ vyplněna!"; if (akce.dotaceprijemcepravniformatyp == 3) chybaakce = "Pro typ '3' musí být zadáno IČ a nesmí být vyplněno RČ!"; public enum PravniForma Nepodnikatel = 1, Zivnostnik = 2, PravnickaOsoba = 3 MagicNumbersNEEE! switch (akce.dotaceprijemcepravniformatyp) case PravniForma.Soukromnik: chybaakce = "..."; break; case PravniForma.Zivnostnik: chybaakce = "..."; break; case PravniForma.PravnickaOsoba: chybaakce = "..."; break;

#region SetButtonFakturovatVisibility public void SetButtonFakturovatVisibility(bool value) if (value) else #endregion FakturovatVybraneBT.Visible = true; FakturovatVybraneBT.Visible = false; Placen za počet řádek?

public DateTime? DateFrom get return this.datefrom; set DateTime min = SqlDateTime.MinValue.Value; DateTime max = SqlDateTime.MaxValue.Value; if ((value.hasvalue) && ((value.value <= min) (value.value >= max))) this.datefrom = null; else this.datefrom = value;...že by nová technika validace? DateFrom = input.value; IsValid = (DateFrom!= null); DateFrom = input.value?? DateTime.Today; XyLabel.Text = DateFrom.Value.ToString("g");//Ex: Nullable object must have...

row.cells["zbyvacol"].value = decimal.parse(row.cells["limitcol"].value.tostring().replace(".", ",")) - decimal.parse(row.cells["cerpanocol"].value.tostring().replace(".", ","));...asi ani nechci vědět, co tím autor myslel a jak se to chová v různých Culture.

public static Exception SendAlert(string subject, string body) Exception exceptionout = null; try MailMessage message = new MailMessage(); message.from = new MailAddress("sender@anon.net"]); message.to.add(new MailAddress("rcpt@anon.net")); message.subject = subject; message.body = body; (new SmtpClient(ConfigurationManager.AppSettings["SMTP"])).Send(message); catch (Exception exception) exceptionout = exception; return exceptionout; var ex = SendAlert(subject, body); if (ex!= null) //?? catch (ex) Log(ex); Pokud výjimku nezpracováváte, tak ji nezachycujte!

private void GetListForMonth(SqlConnection sqlconnection, list.clear(); //... while (sqldatareader.read()) //... int month, int year, Dictionary<string, bool> list) list.add(sqldatareader[0].tostring(), true); var list = GetListForMonth(conn, 10, 2014, var list = new List<string>(); GetListForMonth(conn, 10, 2014, list);

Kategorie Klasický bugy

protected Dictionary<string, string> _queryparams = new Dictionary<string, string>(); public void SetQueryParams(Dictionary<string, string> queryparams) _queryparams.clear(); _queryparams = queryparams; var myqueryparams = new Dictionary<string, string>() "ICO", "25612697", "NAZEV", "XY" ; resolver.setqueryparams(myqueryparams); // _queryparams = myqueryparams var result1 = resolver.execute(); myqueryparams.add("dic", "CZ25612697"); resolver.setqueryparams(myqueryparams); // myqueryparams.clear() var result2 = resolver.execute();...hledání s DIČ jimnefunguje!

Bug: Streamvrácený metodou GetMemoryStreamnení disposován Oprava:...doplněn using

http://knowledge-base.havit.cz Q & A