Construction Kolektiv autorů

Podobné dokumenty
Construction. Jiří Toušek

Design and Construction

Čipové karty Lekařská informatika

Úvod do programovacích jazyků (Java)

Algoritmizace a programování

Abstraktní datové typy: zásobník

Neměnné objekty. Tomáš Pitner, upravil Marek Šabo

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

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

George J. Klir. State University of New York (SUNY) Binghamton, New York 13902, USA

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

JAVA. Další jazyky kompilovatelné do Java byte-code

Projekty pro výuku programování v jazyce Java

SonarQube - statická analýza kódu a její zapojení v CI. Babu Červenková Big Data developer - Java Fulltext - Robot tým

typová konverze typová inference

Michal Podzimek

Typický prvek kolekce pro české řazení

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

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

Lambda funkce Novinky v interfaces Streamy Optional - aneb zbavujeme se null. Java 8. Ondřej Hrstka

KIV/PIA 2013 Jan Tichava

Enterprise Java (BI-EJA) Technologie programování v jazyku Java (X36TJV)

Object-relational mapping (JPA, Hibernate)

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

Výčtový typ strana 67

Využití OOP v praxi -- Knihovna PHP -- Interval.cz

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

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

public static void main(string[] args) { System.out.println(new Main().getClass().getAnnotation(Greet.class).text());

Zápis programu v jazyce C#

Java Enum Java, zimní semestr ,2017 1

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

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);

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

Obsah přednášky. 12. Dokumentace zdrojového kódu Tvorba elektronické dokumentace UML. Co je diagram tříd. Ing. Ondřej Guth

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

PREPROCESOR POKRAČOVÁNÍ

Chyby a výjimky. Chyba. Odkud se chyby berou? Kdo chyby opravuje? Co můžete dělat jako programátor? Dvě hlavní metody práce s chybami.

KTE / ZPE Informační technologie

Platforma Java. Petr Krajča. Katedra informatiky Univerzita Palackého v Olomouci. Petr Krajča (UP) KMI/PJA: Seminář V. 27. říjen, / 15

Iterator & for cyklus

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

20. Projekt Domácí mediotéka

Testovací metoda. Testovací metoda. public class SimpleTest {

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

Stream API. Petr Krajča. Základy programovaní 4 (Java) Katedra informatiky Univerzita Palackého v Olomouci

Introduction to MS Dynamics NAV

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Java Výjimky Java, zimní semestr

První kapitola úvod do problematiky

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

RMI Remote Method Invocation

Seminář Java IV p.1/38

Generické typy. Podrobněji: The Java Language Specification ( Third Edition ) , 18

Generické programování

Java Řetězce Java, zimní semestr

návrhový vzor Singleton.

DPKOM_06 Dědičnost entit a zpětná volání posluchači

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

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

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.

10 Generické implementace

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

Databázové systémy II. KIV/DB2 LS 2007/2008. Zadání semestrální práce

Anotace a Hibernate. Aleš Nosek Ondřej Vadinský Daniel Krátký

UJO Framework. revoluční architektura beans. verze

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

Verzování a publikace dat na webu za pomoci PostgreSQL

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/

Doxygen. Jakub Břečka

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

NA CO SI DÁT POZOR V JAVASCRIPTU? Angular.cz

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

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

B0M33BDT Technologie pro velká data. Supercvičení SQL, Python, Linux

Jazyk C# (seminář 6)

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

Distribuované systémy a výpočty

1, Žáci dostanou 5 klíčových slov a snaží se na jejich základě odhadnout, o čem bude následující cvičení.

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

Java Cvičení 05. CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics

Compression of a Dictionary

JAVA V Assertions Java, zimní semestr

Programování v Javě I. Leden 2008

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

Enterprise Java (BI-EJA) Technologie programování v jazyku Java (X36TJV)

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

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

Úvod do programování v jazyce Java

Objektově orientované programování

Teoretické minimum z PJV

PG 9.5 novinky ve vývoji aplikací

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

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

Webové služby a XML. Obsah přednášky. Co jsou to webové služby. Co jsou to webové služby. Webové služby a XML

Jakub Čermák Microsoft Student Partner

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

Datové struktury. alg12 1

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Transkript:

Construction Kolektiv autorů 1.11.2018

Připomenutí Analýza Návrh Implementace Co Jak

Opakování

Příklad Vyhodnocení výrazu o 3 + ((5 + 9) * 2)

Příklad Vyhodnocení výrazu boolean isoperator = (operator!= null) && (leftchild!= null) && (rightchild!= null); int leftvalue = leftchild.evaluate(); int rightvalue = rightchild.evaluate(); switch (operation) { case PLUS: return leftvalue + rightvalue; case MINUS: return leftvalue - rightvalue; case TIMES: return leftvalue * rightvalue; case DIVIDE: return leftvalue / rightvalue; default: throw new IllegalStateException( "Unknown operator: " + operator); }

Příklad Vyhodnocení výrazu

Příklad Vyhodnocení výrazu

Příklad Vyhodnocení výrazu public class ValueNode implements Node { public int evaluate() { return value; } } public class OperationNode implements Node { public int evaluate() { return operation.evaluate( leftchild.evaluate(), rightchild.evaluate()); } } public enum DefaultOperations implements Operation { PLUS { public int evaluate(int a, int b) {return a + b;} }, MINUS { public int evaluate(int a, int b) {return a - b;} }, TIMES { public int evaluate(int a, int b) {return a * b;} }, DIVIDE { public int evaluate(int a, int b) {return a / b;} } }

Příklad - Cache public class CacheMap<K, V> extends LinkedHashMap<K, V> { private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void lockread() { lock.readlock().lock(); } public void unlockread() { lock.readlock().unlock(); } } public void lockwrite() { lock.writelock().lock(); } public void unlockwrite() { lock.writelock().unlock(); } try { cache.lockwrite(); cache.put("a", "B"); } finally { cache.unlockwrite(); } cache.putall(someothercache); cache.remove("a"); try { cache.lockread(); cache.put("a", "B"); } finally { cache.unlockread(); }

Příklad - Cache public class CacheMap<K, V> { private final CustomLinkedHashMap<K, V> map; private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public V get(final K key) { return withreadlock(() -> map.get(key)); } public void put(final K key, final V value) { withwritelock(() -> map.put(key, value)); } public void remove(final K key) { withwritelock( ); } } public int size() { return withreadlock(() -> map.size()); }

Pár úvah o kvalitním kódu

Na cestě ke kvalitnímu kódu o Každý to chce psát jednoduše

Na cestě ke kvalitnímu kódu o o Každý to chce psát jednoduše Každý to chce psát čistě

Na cestě ke kvalitnímu kódu o o o Každý to chce psát jednoduše Každý to chce psát čistě Každý to chce psát jinak

Na cestě ke znovupoužitelnosti o Developers love to reuse code!

Příklad Join řetězců o Jak implementovat spojení kolekce řetězců o [ A, B, C ] -> A, B, C

Příklad Join řetězců o Možná implementace public static String join(list<string> strings) { StringBuilder result = new StringBuilder(); for (String p : strings) { result.append(p).append(", "); } } return result.substring( 0, result.length() - ", ".length());

Příklad Join řetězců o Hotová řešení v Java světě: Apache commons-lang StringUtils.join Google Guava Joiner.on Java String.join

Co je to kvalitní kód?

Kvalitní kód je Bezchybný Rychlý / Efektivní Krátký? Rafinovaný? Srozumitelný Udržovatelný S unit testy

Proč psát srozumitelný kód Kód píšete jednou, číst ho (vy nebo někdo jiný) budete pravděpodobně vícekrát Pokud váš kód někdo nepochopí, snadno v jeho použití nebo úpravě udělá chybu Nesrozumitelný kód nikdo nebude chtít používat Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.

Kdy nepsat kvalitní kód?

Jak psát srozumitelný kód

Co bude uživatel vaší metody číst 1. Jméno metody 2. Deklarované typy parametrů a návratové hodnoty 3. Jména deklarovaných parametrů 4. Javadoc 5. Samotný kód metody Čím dříve se dozví vše, co potřeboval, tím dříve může přestat číst (a ušetřit čas)

Příklad: StringUtils (Commons Lang) /** join()

Příklad: StringUtils (Commons Lang) /** public static String join(object[], String, int, int)

Příklad: StringUtils (Commons Lang) /** public static String join(object[] array, String separator, int startindex, int endindex)

Příklad: StringUtils (Commons Lang) /** Joins the elements of the provided array into a single String containing the provided list of elements. No delimiter is added before or after the list. A null separator is the same as an empty String (""). Null objects or empty strings within the array are represented by empty strings. StringUtils.join(null, *) = null StringUtils.join([], *) = "" StringUtils.join([null], *) = "" StringUtils.join(["a", "b", "c"], "--") = "a--b--c" StringUtils.join(["a", "b", "c"], null) = "abc" StringUtils.join(["a", "b", "c"], "") = "abc" StringUtils.join([null, "", "a"], ',') = ",,a" Parameters: array the array of values to join together, may be null separator the separator character to use, null treated as "" startindex the first index to start joining from. It is an error to pass in a start index past the end of the array endindex the index to stop joining from (exclusive). It is an error to pass in an end index past the end of the array Returns: the joined String, null if null array input */ public static String join(object[] array, String separator, int startindex, int endindex)

Příklad: StringUtils (Commons Lang) /** Joins the elements of the provided array into a single String containing the provided list of elements. No delimiter is added before or after the list. A null separator is the same as an empty String (""). Null objects or empty strings within the array are represented by empty strings. StringUtils.join(null, *) = null StringUtils.join([], *) = "" StringUtils.join([null], *) = "" StringUtils.join(["a", "b", "c"], "--") = "a--b--c" StringUtils.join(["a", "b", "c"], null) = "abc" StringUtils.join(["a", "b", "c"], "") = "abc" StringUtils.join([null, "", "a"], ',') = ",,a" Parameters: array the array of values to join together, may be null separator the separator character to use, null treated as "" startindex the first index to start joining from. It is an error to pass in a start index past the end of the array endindex the index to stop joining from (exclusive). It is an error to pass in an end index past the end of the array Returns: the joined String, null if null array input */ public static String join(object[] array, String separator, int startindex, int endindex)

Příklad: StringUtils (Commons Lang) public static String join(object[] array, char separator, int startindex, int endindex) { if (array == null) { return null; } int bufsize = (endindex - startindex); if (bufsize <= 0) { return EMPTY; } bufsize *= ((array[startindex] == null? 16 : array[startindex].tostring().length()) + 1); StrBuilder buf = new StrBuilder(bufSize); } for (int i = startindex; i < endindex; i++) { if (i > startindex) { buf.append(separator); } if (array[i]!= null) { buf.append(array[i]); } } return buf.tostring();

Příklad: StringUtils (Commons Lang) private static final String[] ARRAY_LIST = {"foo", "bar", "baz"}; private static final String[] NULL_ARRAY_LIST = {null}; private static final String[] EMPTY_ARRAY_LIST = {}; private static final String[] MIXED_ARRAY_LIST = {null, "", "foo"}; private static final Object[] MIXED_TYPE_LIST = {"foo", Long.valueOf(2L)}; private static final String SEPARATOR = ","; private static final String TEXT_LIST_NOSEP = "foobarbaz"; private static final String TEXT_LIST = "foo,bar,baz"; @Test public void testjoin_arraystring() { assertnull(stringutils.join((object[]) null, null)); assertequals(text_list_nosep, StringUtils.join(ARRAY_LIST, null)); assertequals(text_list_nosep, StringUtils.join(ARRAY_LIST, "")); assertequals("", StringUtils.join(NULL_ARRAY_LIST, null)); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, null)); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, "")); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR)); assertequals(text_list, StringUtils.join(ARRAY_LIST, SEPARATOR)); assertequals(",,foo", StringUtils.join(MIXED_ARRAY_LIST, SEPARATOR)); assertequals("foo,2", StringUtils.join(MIXED_TYPE_LIST, SEPARATOR)); } assertequals("/", StringUtils.join(MIXED_ARRAY_LIST, "/", 0, MIXED_ARRAY_LIST.length - 1)); assertequals("", StringUtils.join(MIXED_ARRAY_LIST, "", 0, MIXED_ARRAY_LIST.length - 1)); assertequals("foo", StringUtils.join(MIXED_TYPE_LIST, "/", 0, 1)); assertequals("foo/2", StringUtils.join(MIXED_TYPE_LIST, "/", 0, 2)); assertequals("2", StringUtils.join(MIXED_TYPE_LIST, "/", 1, 2)); assertequals("", StringUtils.join(MIXED_TYPE_LIST, "/", 2, 1));

Název metody To první a často jediné, co z vaší metody bude většina lidí číst věnujte mu pozornost Měl by být stručný a přitom dostatečně popisovat, co metoda dělá Pokud se vám nedaří vhodný název vymyslet, může to být špatným návrhem metody Metoda dělá více různých věcí (měla by dělat vždy jen jeden svůj úkol) Nemáte vlastně jasno, co má metoda dělat Pokud jste při vymýšlení jména přišli na špatný návrh metody, ušetřili jste si dost času, který byste jinak strávili později přepisováním kódu Kvíz: co dělá tato metoda? dontstoredatatocache()

Název metody issavebasicdataandtemplateattributevaluesdeactivatedocumentreturnpossible()

Jedno slovo o One Word per Concept fetch retrieve get read find

Jména a typy parametrů Jméno by mělo popisovat, co daný objekt reprezentuje nejen sám o sobě, ale i v kontextu použití parametru: void merge(graph graph1, Graph graph2) vs. void merge(graph sourcegraph, Graph targetgraph) U typovaných jazyků využívejte datové typy Toto by měla být naprostá samozřejmost Speciálně v Javě se ale často setkávám zejména s ignorováním enums (místo enumu se často používají booleany nebo soustavy konstant) Zdá se, že velmi populární je místo strongly typed používat stringly typed přístup: Text: "abc" Číslo: "42" Objekt obsahující jednu textovou a dvě číselné položky: "abc_42_666" Přístup k první číselné položce objektu: myobjectstring.split("_")[1]

Co nepovažuji za užití datových typů Map<Vertex, Set<Boolean>> List<List<List<String>>> Map<List<Object>, HashSet<Pair<Integer, Integer>>>

Parametry Metoda s příliš velkým počtem parametrů je nepřehledná protected PdfPTable getprijemceplnenitable(float documentwidth, String nazevleasingovky, String cisloleasingovesmlouvy, String smluvniservis, String prijemcecislouctu, String prijemcejmeno, String prijemceulicecp, String prijemceobecpsc, boolean pojistenijindeexistuje, String pojistenijindenazev, Boolean dphanonenull, String zpusobuhradykey, String datum, boolean isdph, String stextpodpodpisem) Parametry typu boolean nejsou příliš vhodné Nutno v názvu parametru jasně deklarovat, co znamená true a co false Jméno parametru ale nemusí být vždy dostupné (např. v Javě, mám-li knihovnu bez javadoc a zkompilovanou bez jmen parametrů, vidím jen typ bez jména) Při volání metody není na první pohled význam boolean parametru obvykle zřejmý newtable(tablename, parentdatabase, true) newtable(tablename, parentdatabase, TableType.GLOBAL_TEMPORARY)

Primitive Obsession Parametry void bookticket(string name, String firstname, String film, int count, String cinema); bookticket(string arg0, String arg1, String arg2, int arg3, String arg4); void bookticket(name name, FirstName firstname, Film film, Count count, Cinema cinema); bookticket(name arg0, FirstName arg1, Film arg2, Count arg3, Cinema arg4);

Primitive Obsession - Parametry o Příklad Vyhledávání produktů podle cenového intervalu? searchbyprice (?);

Primitive Obsession - Parametry o Příklad Vyhledávání podle cenového intervalu Vector searchbyprice(double start, double end); List<Product> searchbypricerange(price start, Price end); List<Product> searchbypricerange(pricerange pricerange);

Primitive Obsession Třídy public class Customer { } private int id; private String firstname; private String lastname; public class Customer { } private CustomerId id; private FirstName firstname; private LastName lastname;

Javadoc Dohodněte se na jazyku a dodržujte ho V angličtině může být problém se vyjádřit (zejména odborné pojmy) Komentáře v češtině vyžadují neustále přepínat klávesnici a jazyk v hlavě Komentáře v cestine nevypadají dobře Dokumentujte chování vůči null (všude tam, kde to není očividné) U atributů objektu / třídy zda může někdy být null a co to znamená U parametrů metod zda může být null a co se v tom případě stane U návratových hodnot zda a v jaké situaci může metoda vrátit null U kolekcí a polí vnímejte rozdíl mezi prázdnou kolekcí a null Většinou dává lepší smysl prázdná kolekce ( seznam nalezených prvků je prázdný ) než null ( seznam nalezených prvků neexistuje ) Nenechte se vést leností nebo dojmem větší efektivity / úspory paměti při použití null (Java: Collections.emptyList())

Javadoc /** * Metoda cislo zaznamu milestone v cache nebo -1 * @param firstrow * @param lastrow * @param extrarecords * @return * @throws ExpiredDataException */ public CachedData gettimemilestonecacheddata(..)

Javadoc: StringUtils (Commons Lang) /** Joins the elements of the provided array into a single String containing the provided list of elements. No delimiter is added before or after the list. A null separator is the same as an empty String (""). Null objects or empty strings within the array are represented by empty strings. StringUtils.join(null, *) = null StringUtils.join([], *) = "" StringUtils.join([null], *) = "" StringUtils.join(["a", "b", "c"], "--") = "a--b--c" StringUtils.join(["a", "b", "c"], null) = "abc" StringUtils.join(["a", "b", "c"], "") = "abc" StringUtils.join([null, "", "a"], ',') = ",,a" Parameters: array the array of values to join together, may be null separator the separator character to use, null treated as "" startindex the first index to start joining from. It is an error to pass in a start index past the end of the array endindex the index to stop joining from (exclusive). It is an error to pass in an end index past the end of the array Returns: the joined String, null if null array input */ public static String join(object[] array, String separator, int startindex, int endindex)

Javadoc : StringUtils (Spring) o o Anotace pro popis okrajových podmínek javax.annotation.nullable javax.annotation.nonnull Není nutný popis v Javadocu /** * Check whether the given {@code String} is empty. * <p>this method accepts any Object as an argument, comparing it to * {@code null} and the empty String. As a consequence, this method * will never return {@code true} for a non-null non-string object. * <p>the Object signature is useful for general attribute handling code * that commonly deals with Strings but generally has to iterate over * Objects since attributes may e.g. be primitive value objects as well. * @param str the candidate String * @since 3.2.1 */ public static boolean isempty(@nullable Object str) { return (str == null "".equals(str)); }

Javadoc: ServerRequest (Spring) o o Optional monáda pro návratové hodnoty Optional.isEmpty() Optional.map(value -> ).orelse( ) Není nutný popis v Javadocu public interface ServerRequest { /** * Get the request URI. */ URI uri(); /** * Get the request attribute value if present. * @param name the attribute name * @return the attribute value */ Optional<Object> attribute(string name); } /** * Get a mutable map of request attributes. * @return the request attributes */ Map<String, Object> attributes();

Javadoc: Flux (Reactor) o Když slova nestačí Obrázky, diagramy /** * Transform the items emitted by this {@link Flux} by applying a synchronous function * to each item. * <p> * <img class="marble" src="..." alt=""> * <p> * @param mapper the synchronous transforming {@link Function} * @param <V> the transformed type * * @return a transformed {@link Flux} */ public final <V> Flux<V> map(function<? super T,? extends V> mapper) {

Javadoc : Flux (Reactor)

Javadoc - asciiart o Když nemáte obrázek, můžete vzít asciiart /** * Reads complete offer. * <pre> * * * Offer * * * * \/ * * Business Product <----------- Offered Product * * * * \/ \/ * * Business Feature <----------- Offered Feature * * </pre> */ Optional<FinancialProduct> getoffer(productid productid, OfferId offerid);

Kód Dodržujte konvence daného jazyka (jména, formátování, ) Orientace na čtenáře kód bude čten víckrát, píšete jej jednou Lenost zde není platným argumentem Jména proměnných (a všeho ostatního) volte dostatečně srozumitelná Příklad z jedné revize: v cele třídě mnoho nevhodných názvů proměnných bi, is, bos, asr, s, m, baos, dos a můj favorit, pole s názvem array Kvíz: co ošetřuje následující podmínka? if(lv >= 0 && df >= 0 && this.hasrows() && df < this.getrows().length) { } Všeho s mírou obecně čím větší rozsah platnosti, tím důležitější je jasné jméno Srozumitelnost!= délka např. význam proměnné i je obecně známý Nepoužívejte jednu proměnnou ke dvěma účelům Ternární operátor je efektní, ale leckdy poněkud nečitelný Kvíz: co vrátí následující výraz? (0 < 1)? 2 : 3 + 4

Programming by Coincidence

Programming by Coincidence if (typzadosti == ZALOZENI_SMLOUVY) { zalozsmlouvu(); } else { zrussmlouvu(); }

Programming by Coincidence if (typzadosti == ZALOZENI_SMLOUVY) { zalozsmlouvu(); } else if (typzadosti == ZRUSENI_SMLOUVY) { zrussmlouvu(); }

Programming by Coincidence if (typzadosti == ZALOZENI_SMLOUVY) { zalozsmlouvu(); } else if (typzadosti == ZRUSENI_SMLOUVY) { zrussmlouvu(); } else { } throw new IllegalArgumentException( Nepodporovany typ zadosti: + typzadosti);

Programming by Coincidence if (typzadosti == ZALOZENI_SMLOUVY) { zalozsmlouvu(); } else if (typzadosti == ZRUSENI_SMLOUVY) { zrussmlouvu(); } // else do nothing

Programming by Coincidence 2 int pocetcelychmesicudokoncekvartalu = 0; switch(mesicvroce%3) { case 0: pocetcelychmesicudokoncekvartalu = 0;break; case 1: pocetcelychmesicudokoncekvartalu = 2;break; case 2: pocetcelychmesicudokoncekvartalu = 1;break; }

Programming by Coincidence 2 int pocetcelychmesicudokoncekvartalu = 0; switch(mesicvroce%3) { case 0: pocetcelychmesicudokoncekvartalu = 0;break; case 1: pocetcelychmesicudokoncekvartalu = 2;break; case 2: pocetcelychmesicudokoncekvartalu = 1;break; default: throw new IllegalStateException( "Nastala situace, ke ktere nemuze dojit"); }

Je tento konstruktor prázdný záměrně? protected MyObject() { };

Je tento konstruktor prázdný záměrně? protected MyObject() { }; /* empty */

Dřív to fungovalo entity.id = new EntityId(this.allEntities.size());

Fail Fast o Kdo si pamatuje?

Fail Fast o o Je-li v programu chyba, měl by selhat co nejdříve Aktivně kontrolujte konzistenci a ošetřujte možné chyby o o Dead programs tell no lies Nejhorší je na chybu přijít až po databázovém commitu

Fail Fast - Kontrola parametrů public void setformatter(dateformatter dateformatter) { Assert.notNull(dateFormatter, "DateFormatter must not be null"); } this.dateformatter = dateformatter;

Fail Fast - Kontrola stavu objektu public Transaction createtransaction(string name, int timeout) throws NotSupportedException, SystemException { Assert.state(transactionManager!= null, "No JTA TransactionManager available"); }...

Unit testy

Unit testy o o Kdo píšete? Pravidla?

Unit testy o o o o o Psaní unit testů je absolutní samozřejmost. Kvalitní kód bez unit testů je nesmysl. Nejdůležitější je Psát hodně Psát průběžně Aktualizovat Pravidla (podle Uncle Boba): One assert per test Readable Fast Independent Repeatable One assert per test dodržuje málokdo.

Příklad: StringUtils (Commons Lang) private static final String[] ARRAY_LIST = {"foo", "bar", "baz"}; private static final String[] NULL_ARRAY_LIST = {null}; private static final String[] EMPTY_ARRAY_LIST = {}; private static final String[] MIXED_ARRAY_LIST = {null, "", "foo"}; private static final Object[] MIXED_TYPE_LIST = {"foo", Long.valueOf(2L)}; private static final String SEPARATOR = ","; private static final String TEXT_LIST_NOSEP = "foobarbaz"; private static final String TEXT_LIST = "foo,bar,baz"; @Test public void testjoin_arraystring() { assertnull(stringutils.join((object[]) null, null)); assertequals(text_list_nosep, StringUtils.join(ARRAY_LIST, null)); assertequals(text_list_nosep, StringUtils.join(ARRAY_LIST, "")); assertequals("", StringUtils.join(NULL_ARRAY_LIST, null)); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, null)); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, "")); assertequals("", StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR)); assertequals(text_list, StringUtils.join(ARRAY_LIST, SEPARATOR)); assertequals(",,foo", StringUtils.join(MIXED_ARRAY_LIST, SEPARATOR)); assertequals("foo,2", StringUtils.join(MIXED_TYPE_LIST, SEPARATOR)); } assertequals("/", StringUtils.join(MIXED_ARRAY_LIST, "/", 0, MIXED_ARRAY_LIST.length - 1)); assertequals("", StringUtils.join(MIXED_ARRAY_LIST, "", 0, MIXED_ARRAY_LIST.length - 1)); assertequals("foo", StringUtils.join(MIXED_TYPE_LIST, "/", 0, 1)); assertequals("foo/2", StringUtils.join(MIXED_TYPE_LIST, "/", 0, 2)); assertequals("2", StringUtils.join(MIXED_TYPE_LIST, "/", 1, 2)); assertequals("", StringUtils.join(MIXED_TYPE_LIST, "/", 2, 1));

Příklad JpaRepository (Spring Data JPA) public class JpaRepositoryTests { CrudRepository<WithIdClass, WithIdClassPK> idclassrepository; @Test // DATAJPA-50 public void executescrudoperationsforentitywithidclass() { PersistableWithIdClass entity = new PersistableWithIdClass(1L, 1L); idclassrepository.save(entity); assertthat(entity.getfirst(), is(notnullvalue())); assertthat(entity.getsecond(), is(notnullvalue())); PersistableWithIdClassPK id = new PersistableWithIdClassPK( entity.getfirst(), entity.getsecond()); } assertthat(idclassrepository.findbyid(id), is(optional.of(entity))); @Test // DATAJPA-266 public void testexistsfordomainobjectswithcompositekeys() {... } } @Test // DATAJPA-527 public void executesexistsforentitywithidclass() {... }

Unit testy Názvy metod o o o Špatné testfind testvalidate Dobré shouldfindbyidwhenexists shouldthrowexceptionwhenagelessthan18 should_throwexception_when_agelessthan18 executesexistsforentitywithidclass Doporučení Testujeme vlastnosti třídy, ne jednotlivé metody Pro jednu metodu typicky existuje několik testů

Nástroje

SonarQube o o o Nástroj pro analýzu kvality kódu Statická analýza Testy a coverage Podporuje Java C# JavaScript Doporučení Pouštět analýzu pravidelně Kontinuálně řešit nálezy Nenechat nahromadit technický dluh

SonarQube - Přehled

SonarQube Issues

SonarQube Code smell

Perličky

Kdy se zobrazí nabídka úvěrů? /** * Method returns true if credit lines should be shown. * * @return true if credit lines should be shown otherwise false */ public boolean isshowcreditlines() { return // Showing depends of dynamic property and if user is in pilot mode (show only in pilot to // users in pilot mode if constant is true, if false, show to all) ((ebankinguser.getpilot() == null) (!EbankingConstants.CREDIT_LINES_FUNCTIONS_PILOT) (Boolean.TRUE.equals(ebankingUser.getPilot()) && EbankingConstants.CREDIT_LINES_FUNCTIONS_PILOT)) // and (home tab is shown and there are no campaigns) && ((menubean.ishometab() &&!bcs.isshowcampaigns()) // or ((we are on loans tab (TAB_LOANS) on specific menu item (MNU_LST_CRE_MORA_GET) // or on eshop (TAB_ESHOP)) and client has no approved application) (((menubean.iswantedtab(menunames24.tab_loans.name()) // THU: tento kod je zakomentovan, protoze nefuguje nastavovani actualmenuitem spravne /*&& (menubean.getactualmenuitem()!= null) && menubean.getactualmenuitem().name().touppercase().equals( MenuNameS24.MNU_LST_CRE_MORA_GET.name())*/ ) menubean.iswantedtab(menunames24.tab_eshop.name())) && bcs.getapprovedapplicationid() == null)) // and there exist some credit lines &&!isitemlistempty(); }

Map není nikdy dost public interface IValidator { public void validate( Object[] objects, Map<Object, Object> globalparams, Map<Object, Object> localparams, Map<Object, Object> rowparams, Locale locale); }

DB procedura... ** Nazev ulozene procedury: esipo_s_prehl_rotv ** ** Funcionalita: Procedura slouzi ** ** Vstupni parametry:...

Trocha logiky public void setplatnostdoodvolani(boolean platnostdoodvolani) { if (platnostkontaktniadresy == null) { platnostkontaktniadresy = new IntervalOdDo(); } else { platnostkontaktniadresy = new IntervalOdDo( platnostkontaktniadresy.getzacatek(), null); } }

Čím se od sebe metody liší? /** * Directory interface poskytovany modulum skrze WebService webovou * aplikaci datovych schranek. */ public interface IDSDirectoryService { public ListResponse<Issuer> getissuer( IssuerSearchCriteria searchcriteria, String personid); } public ListResponse<Issuer> findissuer( IssuerSearchCriteria searchcriteria, String personid);

Handle stuff dataprocessor.processdata(elementsonpages);

Literatura o The Pragmatic Programmer: From Journeyman to Master Andrew Hunt, David Thomas o Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin

Dotazy? 85

Děkuji za pozornost Profinit, s.r.o. Tychonova 2, 160 00 Praha 6 Telefon + 420 224 316 016 Web www.profinit.eu LinkedIn linkedin.com/company/profinit Twitter twitter.com/profinit_eu