Best practices

Jak zůstat pánem situace

Místo úvodu

  • Většina aplikací je vyvíjena pouze na základě hrubého návrhu nebo klíčové funkčnosti a je postupně dopracována do finální podoby.
  • Většina aplikací je složena z mnoha komponent, které vyvíjejí různí programátoři s rozdílnou kulturou psaní kódu.
  • Komponenty volají navzájem svoje služby a havárie jediné z nich může spustit dominový efekt a zhroucení celé aplikace nebo její uvedení do nepředvídatelného stavu. 

 

Cíl

  • Je třeba zajistit stabilní a předvídatelné chování aplikace.
  • Umožnit snadné nalezení vadného kódu.

 

Best practices

  • Best practices je doporučená sada technik nebo postupů umožňující vytvářet bezpečný a robustní kód, který je snadno čitelný a pochopitelný pro ostatní vývojáře v týmu.

 

Názvové konvence

  • Pascal – názvy tříd, názvy veřejných metod a vlastností.
  • Camel – názvy parametrů, názvy lokálních proměnných.
  • Nepoužívat maďarskou notaci.
  • Nepoužívat zkratky pro názvy proměnných.

 Podrobně viz: Design Guidelines for Developing Class Libraries / Capitalization Conventions

 Příklad:

Attribute VB_Name = "AgendaAkce"     'Název třídy Pascal
Function VyhodnotitPodminku(ByVal eval As Evaluator, ByVal data As Object) As Boolean   'Název funkce  Pascal, parametry Camel
    Dim xmlZaznamy As DOMDocument50    'Lokální proměnná Camel

Dim strKniha as String 'špatně maďarská notace
Dim K as Kniha         'špatně, nepoužívat zkratky

Poznámka: vzhledem k zavedeným zvyklostem můžeme používat konvenci Pascal pro parametry a lokální proměnné. Stejně tak lze používat zavedené zkratky pro proměnné (I as Integer, R as Recordset).

Pojmenování

  • Názvy tříd - podstatná jména (např. Agendy, Agenda, Kniha, Záznam)
  • Vlastnosti - podstatná a přídavná jména (Agenda, Rok, Rocni)
  • Metody - slovesa v infinitivu (Kopirovat, Ulozit)
  • Funkce - podstatná jména, slovesa (JeZapocataTransakce, DejStrom, FormatovatCisloTelefonu)
  • Nemíchat jazyky v jednom projektu

 

Poznámka: Lze používat anglické názvy, pokud je pojmenování dané zvyklostmi (např. kolekce Add, Remove, Contains). Vyvarovat se kombinacím (GetSoubor).
 

Indentation a Spacing

  • Používejte prázdnou řádku pro oddělení logických skupin kódu.

 Public Function AdHocDotaz(ByVal databaze As Database) As VarioLib.Data

    On Error GoTo Chyba           'Odsazení TAB (4 znaky)
    Dim pole() As Variant
    pole = Parametry
    If LBound(Parametry) <= UBound(Parametry) Then
        If IsArray(Parametry(0)) Then pole = Parametry(0)
    End If                        'Konec logiské skupiny
    
    Set AdHocDotaz = New VarioLib.Data
    AdHocDotazDB.InitInstance databaze , pole
   
    GoTo Konec
Chyba:                            'Návěští se neodsazují
    Chyby.GenerujVyjimku Err.Number, Err.Description, TypeName(Me) & "::AdHocDotaz"
Konec:
End Function

 

Programování

  • Krátké metody – max. 25 řádků.
  • Vypovídající názvy metod.
  • Metody plnící jeden cíl – single job methods.
  • Krátké třídy – max. 1000 řádků.

 

Hlídejte i neočekávané hodnoty:
 

If memberType = eMemberTypes.Registered Then

   // Registered user… do something…

ElseIf memberType = eMemberTypes.Guest Then

   // Guest user... do something…
Else
   // Un expected user type. Throw an exception
   Err.Raise vbObjectError, , “Un expected value “ + memberType.ToString() + “’.”

   // If we introduce a new user type in future, we can easily find
   // the problem here.
End If

 

Exit podmínky místo vnořených podmínek:

 

If Data Is Nothing Then

   // Není co řešit
   Goto Konec

ElseIf Data.Count = 0 Then

   // Není co řešit
   Goto Konec

ElseIf JetseSeMiNecoNelibiCoJinakNicemuNevadi Then

   // Není co řešit
   Goto Konec

End If

// Tady provedu bez obav, co je třeba
Vysledek = 1 / Data.Count

 

Používejte konstanty a enumy místo literálních konstant.

  • Používejte Lcase nebo Ucase pro porovnávání stringů.
  • Dávejte přednost parametrům před členskými proměnnými pro předávání hodnot mezi metodami.
  • Používejte privátní členské proměnné a zveřejňujte je pomocí vlastností.
  • Jako veřejné deklarujte pouze nejnutnější metody a vlastnosti, preferujte Friend (internal) modifikátor.
  • V obsluze události pouze převolávejte jinou samostatnou metodu.
  • Max. 5 parametrů ve volání metod.
  • Pokud funkce vrací kontejner (kolekci, pole …), vraťte prázdný kontejner místo Nothing, pokud nejsou data.
  • Uklízejte datové konexe a otevřené soubory samostatně a za všech okolností.

 

Programování - FileSystem

  • Používejte relativní cesty k souborům.
  • Napište self-check a volejte ho při startu aplikace.

 

Programování - Chyby

  • Nikdy nepište funkce s boolean návratovou hodnotou, která identifikuje zdárný průběh funkce – pokud je něco špatně, vygenerujte výjimku. Návratové hodnoty nikdo nekontroluje …
  • Nikdy nezahazujte výjimky.
  • VB, VBA: V každé funkci vytvořte chybový handler a předejte výjimku volající metodě ručně – umožníte tím snadnější trasování chyb.
  • Chybová hlášení musí obsahovat údaje:
    • co se nepovedlo (nebo co se stalo),
    • proč se to nepovedelo (stalo) a
    • co dělat, jak to opravit.
      Například: Nepodařilo se uložit soubor, protože složka C:\MojeSlozka\ neexistuje. Zadejte existující umístění.
  • Zobrazujte pouze krátká user-friendly hlášení, ale logujte chyby s co největším množstvím informací, aby se usnadnilo odhalení problému.
  • Za větou nepoužíejte vykřičníky! Tady sami vidíte jak je to nepříjemné.

 Viz též příkladové kódy v SDK.

 

Doporučení pro VBA

  • Hodnotu objektové proměnné předávanou parametrem vždy explicitně specifikujte, abyste určili zda se předá odkaz na objekt nebo hodnota výchozí vlastnosti.

X = NejakaFunkce(Me!Produkt.Value)  '// Správně, explicitně určená hodnota parametru
X = NejakaFunkce(Me!Produkt)  '// Špatně, není zřejmé zda se předá reference na prvek Produkt nebo jeho výchozí vlastnost Value


 

  • Explicitně určujte modifikátory parametrů ByVal nebo ByRef. Bezpečné je používat ByVal všude, kde nechceme předávat parametr odkazem. Na místech kde je vyžadováno předání odkazem je vhodné zdůraznit tuto skutečnost uvedením ByRef.

 

DAO

Vždy uzavírejte explicitně otevřené objekty typu

  • Database - po té co jste použili .OpenDatabase
  • Recordset - po té co jste použili .OpenRecordet
  • Querydef - jen pokud jste vytvořili temporary QueryDef voláním .CreateQueryDef("")

Známé problémy

Při volání funkcí

  • Vždy explicitně specifikujte parametr Compare (typ VbCompareMethod) u funkcí InStr, Split, Replace, StrComp
  • Vždy explicitně specifikujte parametr FirstWeekOfYear (typ VbFirstWeekOfYear) a FirstDayOfWeek (VbDayOfWeek) u funkcí DateDiff, DatePart, Weekday

Jinak hrozí neočekávané chování.
 

Ostatní

Vyvarujte se křížových referencí mezi instancemi.

 

 

Související dokument