SlideShare ist ein Scribd-Unternehmen logo
1 von 86
{ clean code }
twitter.com/jirkapenzes
Co je to čistý kód?
• Definic je tolik, kolik je vývojářů.
• Čistý kód píše pečlivý člověk.
• „Čistý kód je jednoduchý a přímočarý. Čistý kód
  se čte jako dobře napsaná próza. Čistý kód
  nikdy nezatemňuje záměr návrháře, ale je plný
  břitkých abstrakcí a přímých toků řízení„
  (Grady Booch).
Proč čistý kód?
Proč psát čistý kód?
•   Chceme na svůj kód být hrdí.
•   Přehlednost, znovu použitelnost.
•   Kód se lépe udržuje.
•   Produktivita, méně stresu.
•   Zbavit se „wtf“ momentů.
•   Budete mít ze své práce radost a lepší pocit.
•   Dokumentace.

• Neděláme to jen pro sebe,
    – občas po nás kód někdo čte.
Jak na čistý kód?
Volit správné názvy
Volit správné názvy
•   Správná jména metod.
•   Správná jména tříd.
•   Správná jména proměnných.
•   Správná jména výčtových typů.

• SPRÁVNÁ JMÉNA.

• Největší problém v dějinách programování!
public List<int[]> GetThem()
    {
            List<int[]> list1 = new List<int[]>();
            foreach(int[] x in theList)
                if (x[0] == 4)
                    list1.Add(x)

             return list1;
    }



•       Jaký druh položek obsahuje theList?
•       Jaký je význam nultého indexu položky v theList?
•       Jaký je význam hodnoty 4?
•       Jak bych mohl využít vráceného seznamu?
•       Co ta metoda vůbec dělá??
public List<int[]> GetFlaggedCells()
{
        List<int[]> list1 = new List<int[]>();
        foreach(int[] x in theList)
            if (x[0] == 4)
                list1.Add(x)

        return list1;
}
public List<int[]> GetFlaggedCells()
{
        List<int[]> flaggedCells = new List<int[]>();
        foreach(int[] x in theList)
            if (x[0] == 4)
               flaggedCells.Add(x)

        return flaggedCells;
}
public List<int[]> GetFlaggedCells()
{
        List<int[]> flaggedCells = new List<int[]>();
        foreach(int[] cell in gameBoard)
            if (cell[0] == 4)
               flaggedCells.Add(cell)

        return flaggedCells;
}
public List<int[]> GetFlaggedCells()
{
        List<int[]> flaggedCells = new List<int[]>();
        foreach(int[] cell in gameBoard)
            if (cell[STATUS_VALUE] == FLAGGED)
               flaggedCells.Add(cell)

        return flaggedCells;
}
public List<int[]> GetFlaggedCells()
{
        List<int[]> flaggedCells = new List<int[]>();
        foreach(int[] cell in gameBoard)
            if (cell[STATUS_VALUE] == FLAGGED)
               flaggedCells.Add(cell)

        return flaggedCells;
}
public List<Cell> getFlaggedCells()
{
        List<Cell> flaggedCells = new List<Cell>();
        foreach(Cell cell in gameBoard)
            if (cell.IsFlagged)
               flaggedCells.Add(cell)

        return flaggedCells;
}
Nezkracujte názvy
int d = 2; // total days
int d = 2; // diameter
int d = 2; // distance

int s = 0;
for (int i = 0; i < 10; i++)
    s += i;

String m = "message";
Nezkracujte názvy
int totalDays = 2;
int diamater = 2;
int distance = 2;

int suma = 0;
for (int index = 0; index < 10; index++)
    suma += index;

String message = "message";



if (a >   b && a > c && a > d && a > e)
    max   = a ;
else if   (b > a && b > c && b > d && b > e)
    max   = b ;
Neprotahovat názvy
UniqueNamesTableUtils.putPortletRequestIntoResourceRecordLazyLoad
AdminTableModelInSession(portletrequest);
Smysluplně se vyjadřovat
int days;



int daysSinceCreation;

int daysSinceLastModification;

int daysSinceLastLogin;

int daysSinceLastPasswordChange;

int durationInDays;
Zřetelnost a výslovnost
List<Car> carsList;

List<Car> cars;
List<Car> newCars;


public class DtaRcrd
{
    private DateTime _geneDtDDMMYYYYhhss;
    private DateTime _modiDtDDMMYYYYhhss;
}

public class DataRecord
{
    private DateTime _generationDate;
    private DateTime _modificationDate;
}
Jak volit správné názvy
•   Jména musí vysvětlovat význam.
•   Srozumitelné.
•   Vyhnout se dezinformacím.
•   Názvy by neměli být redundantní.
    – Nezahrnovat do názvu datový typ.
•   Vyslovitelná jména (DtaRcr).
•   Dodržování konvencí (?)
•   Nenutit nikoho přemýšlet.
•   Názvy z reálného světa.
Jak volit správné názvy
• Jména tříd:
  – Podstatná jména.


• Jména metod:
  – Přístupové metody dle své hodnoty (get, set, is).
  – Slovesa.


• Jedno slovo = jeden pojem.
Datetime tomorrow = GetTomorrow();



public DateTime GetTomorrow() {
   Thread.Sleep(1000*60*60*24);
   return DateTime.Now;
}
OOP
Třídy
Single responsibility principle
public class Employee
{
    public int Id { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }

    public Money CalculatePay() { ... }
    public String ReportHours() { ... } ;
    public Report Save() { ... }
}
public class Employee
{
    public int Id { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
}


public class PayCalculator
{
    public Money CalculatePay(Employee employee) { … }
}

public class EmployeeReporter
{
    public Report ReportHours(Employee employee) { … }
}

public class EmployeeRepository
{
    public void Save() { … }
}
100 řádků v jedné třídě
 15 – 30 řádků metody
  15 tříd v namespace
Datové třídy
 Dědictví
Dědictví a datové třídy
• Dědíme jen to, co potřebujeme.

• Datová třída je pouze nositelem dat.
   – Entity, kontejnery*
• Slouží pro přenos dat (DTO).
• Aktivní záznam – save, find, ... (?!)
public void EmailDemo()
{
    var email = new Email();
    email.From = "jirkapenzes@hotmail.com";
    email.To = "jirkapenzes@gmail.com";
    email.Subject = "Spam";
    email.Body = "Posílám tu URL - tinyurl.com/6s6s63p ";

    email.Send();
}




var email = new Email();
email.From = "jirkapenzes@hotmail.com";
email.To = "jirkapenzes@gmail.com";
email.Subject = "Spam";
email.Body = "Posílám tu URL - tinyurl.com/6s6s63p";

var emailSender = new EmailSender();
emailSender.Send(email);
Jak na metody a funkce
Pravidla
•   1. Metoda musí být malá.
•   2. Metoda musí být ještě menší.
•   3. Metoda by měla dělat pouze jednu věc.
•   4. Volit správný název!
•   5. Minimum zanoření (jedno).
Argumenty funkce
Pravidla
•   Žádný == super.
•   Jeden == ok.
•   Dva == dejme tomu.
•   Tři == raději se tomu vyhnout.
•   Více == důkladně zdůvodnit, zda je to nutné.

• Předávejte objekty.
Vyhnout se příkazu switch
  Nepoužívat blok ‚else‘
public Record ExecuteCommand(Command command)
{
       switch(command.Type)
       {
           case Standard:
               return ExecuteStandardCommand(command);
           case Complex:
               return ExecuteComplexCommand(command);
           default:
               throw new InvalidExecuteType();
       }
   }
public abstract class Command {
    public abstract Record Execute();
}
public abstract class Command {
    public abstract Record Execute();
}

public interface ICommandFactory {
    public Command MakeCommand(CommandRecord commandRecord);
}
public abstract class Command {
    public abstract Record Execute();
}

public interface ICommandFactory {
     Command MakeCommand(CommandRecord commandRecord);
}

public class CommandFactory : ICommandFactory {

    public Command MakeCommand(CommandRecord commandRecord) {
       switch (commandRecord.Type) {
            case Standard:
                return new StandardCommand(commandRecord);
            case Complex:
                return new ComplexCommand(commandRecord);
            default:
                throw new InvalidExecuteRecordType();
        }
    }
}
Command command = commandFactory.MakeCommand(record);
Result result = command.Execute();
Command command = commandFactory.MakeCommand(record);
Result result = command.Execute();
Neopakovat se
Zpracování chyb
Zásady dobrého zpracování chyb
•   Používat výjimky!
•   Nepoužívat návratové kódy.
•   Nepředávat a nevracet hodnotu null.
•   Pište defenzivně.
•   Předávat informace o chybě.
•   Kontrolované výjimky (Java).
public void Add(Car car) {
    if (car != null) {
        CarGarage garage = context.FindCarGarage();
        if (garage != null) {
            garage.Add(car);
        }
    }
}




public void Add(Car car) {
    CarGarage garage = context. FindCarGarage();
    garage.Add(car);
}
List<Car> cars = GetCars();
if (cars != null)
   for(Car car : cars) {
       Repair(car);
   }




List<Car> cars = GetCars();
for(Car car : cars) {
    Repair(car);
}
Komentáře
(self documentation)
Práce s daty
Objekty a struktury
Práce s daty
• Při práci s daty se snažit o nezávislost.
• Odstínění datového zdroje.

• Repository pattern, DAO.
const string query
= "select name, isbn from book where year = @year";

using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    var sqlCommand = new SqlCommand(query, connection);
    sqlCommand.Parameters.AddWithValue("@year", year);
    var reader = sqlCommand.ExecuteReader();

    while (reader.Read())
    {
        var book = new Book
        {
            Name = reader["name"],
            Isbn = reader["isbn"]
        };
        Display(book);
    }
}
const string query
= MakeSqlQuery(BookQuery.FindBooksByYear);

using (var connection = new SqlConnection(connectionString))
{
    connection.Open();
    var sqlCommand = new SqlCommand(query, connection);
    sqlCommand.Parameters.AddWithValue("@year", year);
    var reader = sqlCommand.ExecuteReader();

    while (reader.Read())
    {
        var book = new User
        {
            Name = reader["name"],
            Isbn = reader["isbn"]
        };
        Display(book);
    }
}
var books = bookRepository.FindByYear(2002);

foreach (var book in books)
    Display(book);

public interface IBookRepository
{
    Book FindById(long id);
    IEnumerable<Book> FindAll();
    IEnumerable<Book> FindByCategory(Category category);
    IEnumerable<Book> FindByAuthor(Author author);
    IEnumerable<Book> FindByTag(string tag);
}




var books = bookDao.Fetch(new BookByYearQuery(2002));

foreach (var book in books)
    Display(book);
Refactoring
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   return _quantity * _itemPrice -
        Math.Max(0, _quantity - 500) * _itemPrice * 0.05 +
        Math.Min(_quantity * _itemPrice * 0.1, 100.0);
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;

    return _quantity * _itemPrice -
         Math.Max(0, _quantity - 500) * _itemPrice * 0.05 +
         Math.Min(_quantity * _itemPrice * 0.1, 100.0);
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;

    return basePrice -
         Math.Max(0, _quantity - 500) * _itemPrice * 0.05 +
         Math.Min(_quantity * _itemPrice * 0.1, 100.0);
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;

    return basePrice -
         Math.Max(0, _quantity - 500) * _itemPrice * 0.05 +
         Math.Min(basePrice * 0.1, 100.0);
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;
   double quantityDiscount =
              Math.Max(0, _quantity - 500) * _itemPrice * 0.05;

    return basePrice - quantityDiscount +
         Math.Min(basePrice * 0.1, 100.0);
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;
   double quantityDiscount =
              Math.Max(0, _quantity - 500) * _itemPrice * 0.05;
   double shipping = Math.Min(basePrice * 0.1, 100.0);

    return basePrice - quantityDiscount + shipping;
}
double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   double basePrice = _quantity * _itemPrice;
   double quantityDiscount =
              Math.Max(0, _quantity - 500) * _itemPrice * 0.05;
   double shipping = Math.Min(basePrice * 0.1, 100.0);

    return basePrice - quantityDiscount + shipping;
}
double CalculatePrice()
{
   return basePrice() - quantityDiscount() + shipping();
}

private double quantityDiscount() {
    return Math.Max(0, _quantity - 500) * _itemPrice * 0.05;
}

private double shipping() {
    return Math.Min(basePrice() * 0.1, 100.0);
}

private double basePrice() {
    return _quantity * _itemPrice;
}
double CalculatePrice()
{
   return basePrice() - quantityDiscount() + shipping();
}



double CalculatePrice()
{
   // price is base price - quantity discount + shipping
   return _quantity * _itemPrice -
        Math.Max(0, _quantity - 500) * _itemPrice * 0.05 +
        Math.Min(_quantity * _itemPrice * 0.1, 100.0);
}
Refactoring
•   Neměnit logiku aplikace.
•   Rozházet kód do tříd a metod.
•   Provádět iterativně.
•   Pozor na názvy.
    – Zloději, loupežníci, banditi, zločinci, rafani, …
Formátování a konvence
Formátování a konvence
• 1. Formátovat.
• 2. Dodržovat jazykové konvence.

• Konvence pro přístupové metody.
• Velikost písmen.
• Týmové konvence.
Další zdroje?
Shrnutí
•   Déle přemýšlet nad názvy.
•   Zkusit kód častěji formátovat.
•   Držet se konvencí.
•   Testování.

• Nestačí, aby to jen fungovalo …
Q&A
jirkapenzes@hotmail.com
  twitter.com/jirkapenzes

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (9)

Vývoj aplikací pro iOS
Vývoj aplikací pro iOSVývoj aplikací pro iOS
Vývoj aplikací pro iOS
 
Kdyby/Events
Kdyby/EventsKdyby/Events
Kdyby/Events
 
Dependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 praktickyDependency injection v Nette 2.1 prakticky
Dependency injection v Nette 2.1 prakticky
 
Kdyby/Redis
Kdyby/RedisKdyby/Redis
Kdyby/Redis
 
PZ2021
PZ2021PZ2021
PZ2021
 
Gwt frameworky GXT + UJORM
Gwt frameworky GXT + UJORMGwt frameworky GXT + UJORM
Gwt frameworky GXT + UJORM
 
CQRS v rohlik.cz
CQRS v rohlik.czCQRS v rohlik.cz
CQRS v rohlik.cz
 
Drupal Front-end
Drupal Front-endDrupal Front-end
Drupal Front-end
 
Django
DjangoDjango
Django
 

Andere mochten auch

Polské potraviny zpráva z výzkumu v2 (2)
Polské potraviny zpráva z výzkumu v2 (2)Polské potraviny zpráva z výzkumu v2 (2)
Polské potraviny zpráva z výzkumu v2 (2)MarketingSalesMedia
 
щасливі разом
щасливі разомщасливі разом
щасливі разомMasha11
 
ACAMS Today Article
ACAMS Today ArticleACAMS Today Article
ACAMS Today ArticleEdson Briggs
 
Psacn estudos sociais_2005
Psacn estudos sociais_2005Psacn estudos sociais_2005
Psacn estudos sociais_2005cavip
 
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learnt
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learntTCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learnt
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learntTCI Network
 
Psa cn 2011 pot_est soc_ ciências_ amarela
Psa cn 2011 pot_est soc_ ciências_ amarelaPsa cn 2011 pot_est soc_ ciências_ amarela
Psa cn 2011 pot_est soc_ ciências_ amarelacavip
 
Recitim Eminescu
Recitim EminescuRecitim Eminescu
Recitim EminescuElena Rosca
 
Letersia nen Diktature
Letersia nen DiktatureLetersia nen Diktature
Letersia nen DiktatureOrnela Keçi
 
Análise corinthians paulista 2017 - final
Análise corinthians   paulista 2017 - finalAnálise corinthians   paulista 2017 - final
Análise corinthians paulista 2017 - finalYatan Cenciales
 
Catalog Noaptea alba a creatorilor si designerilor de produs 2015
Catalog Noaptea alba a creatorilor si designerilor de produs 2015 Catalog Noaptea alba a creatorilor si designerilor de produs 2015
Catalog Noaptea alba a creatorilor si designerilor de produs 2015 Revista Atelierul
 
Igraem igrite na polsha
Igraem igrite na polshaIgraem igrite na polsha
Igraem igrite na polshamegikatq
 
La industria de innovación en España: oportunidades y amenazas
La industria de innovación en España: oportunidades y amenazasLa industria de innovación en España: oportunidades y amenazas
La industria de innovación en España: oportunidades y amenazasIgnacio Riesgo
 

Andere mochten auch (20)

Add dev productivity
Add dev productivityAdd dev productivity
Add dev productivity
 
Polské potraviny zpráva z výzkumu v2 (2)
Polské potraviny zpráva z výzkumu v2 (2)Polské potraviny zpráva z výzkumu v2 (2)
Polské potraviny zpráva z výzkumu v2 (2)
 
Code Retreat
Code RetreatCode Retreat
Code Retreat
 
Transducers
TransducersTransducers
Transducers
 
Sexy infrastruktura
Sexy infrastrukturaSexy infrastruktura
Sexy infrastruktura
 
щасливі разом
щасливі разомщасливі разом
щасливі разом
 
ACAMS Today Article
ACAMS Today ArticleACAMS Today Article
ACAMS Today Article
 
Psacn estudos sociais_2005
Psacn estudos sociais_2005Psacn estudos sociais_2005
Psacn estudos sociais_2005
 
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learnt
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learntTCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learnt
TCI 2013 North Atlantic Ocean Cluster Alliance (NAOCA) – Value – Lesson learnt
 
Psa cn 2011 pot_est soc_ ciências_ amarela
Psa cn 2011 pot_est soc_ ciências_ amarelaPsa cn 2011 pot_est soc_ ciências_ amarela
Psa cn 2011 pot_est soc_ ciências_ amarela
 
Webinar
WebinarWebinar
Webinar
 
Recitim Eminescu
Recitim EminescuRecitim Eminescu
Recitim Eminescu
 
Letersia nen Diktature
Letersia nen DiktatureLetersia nen Diktature
Letersia nen Diktature
 
Análise corinthians paulista 2017 - final
Análise corinthians   paulista 2017 - finalAnálise corinthians   paulista 2017 - final
Análise corinthians paulista 2017 - final
 
School of Activist Learning to be a Leader
School of Activist   Learning to be a LeaderSchool of Activist   Learning to be a Leader
School of Activist Learning to be a Leader
 
Catalog Noaptea alba a creatorilor si designerilor de produs 2015
Catalog Noaptea alba a creatorilor si designerilor de produs 2015 Catalog Noaptea alba a creatorilor si designerilor de produs 2015
Catalog Noaptea alba a creatorilor si designerilor de produs 2015
 
Igraem igrite na polsha
Igraem igrite na polshaIgraem igrite na polsha
Igraem igrite na polsha
 
La industria de innovación en España: oportunidades y amenazas
La industria de innovación en España: oportunidades y amenazasLa industria de innovación en España: oportunidades y amenazas
La industria de innovación en España: oportunidades y amenazas
 
Tipss ujian
Tipss ujianTipss ujian
Tipss ujian
 
Laporan pboii 2yosa
Laporan pboii 2yosaLaporan pboii 2yosa
Laporan pboii 2yosa
 

Ähnlich wie Clean code

MoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache WicketMoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache WicketTomáš Páral
 
ClojureScript
ClojureScriptClojureScript
ClojureScriptjakubkoci
 
React premature performance optimization
React premature performance optimizationReact premature performance optimization
React premature performance optimizationMartinKritof1
 
Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?Bohdan Ganický
 
Kruskalův algoritmus - implementace
Kruskalův algoritmus - implementaceKruskalův algoritmus - implementace
Kruskalův algoritmus - implementaceIvo Kostecký
 
Pokročilé techniky programování .NET a C#
Pokročilé techniky programování .NET a C#Pokročilé techniky programování .NET a C#
Pokročilé techniky programování .NET a C#Jan Hřídel
 
Petr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testyPetr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testyAnna Kovárová
 
Google Tag Manager pro mírně pokročilé
Google Tag Manager pro mírně pokročiléGoogle Tag Manager pro mírně pokročilé
Google Tag Manager pro mírně pokročiléMichal Blažek
 
Michal Blažek - Google Tag Manager pro mírně pokročilé
Michal Blažek - Google Tag Manager pro mírně pokročiléMichal Blažek - Google Tag Manager pro mírně pokročilé
Michal Blažek - Google Tag Manager pro mírně pokročiléeshopvikend
 
KST/ICSHP - 1. přednáška
KST/ICSHP - 1. přednáškaKST/ICSHP - 1. přednáška
KST/ICSHP - 1. přednáškaJan Hřídel
 
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)Martin Zeman
 
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)Péhápkaři
 
Péhápkaři - Píšeme čitelný kód #3 by Driveto
Péhápkaři - Píšeme čitelný kód #3 by DrivetoPéhápkaři - Píšeme čitelný kód #3 by Driveto
Péhápkaři - Píšeme čitelný kód #3 by DrivetoPetr Bechyně
 
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015angular-cz
 
Slovak Sun Training Day 2010 - DTrace
Slovak Sun Training Day 2010 - DTraceSlovak Sun Training Day 2010 - DTrace
Slovak Sun Training Day 2010 - DTraceMartin Cerveny
 
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?Develcz
 
Czech Oracle Solaris Administrators Day 2011 - DTrace
Czech Oracle Solaris Administrators Day 2011 - DTrace Czech Oracle Solaris Administrators Day 2011 - DTrace
Czech Oracle Solaris Administrators Day 2011 - DTrace Martin Cerveny
 
Scala - jazyk budoucnosti
Scala - jazyk budoucnostiScala - jazyk budoucnosti
Scala - jazyk budoucnostiZdeněk Farana
 
Develconf coffeescript
Develconf coffeescriptDevelconf coffeescript
Develconf coffeescriptMartin Maly
 
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQuery
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQueryData Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQuery
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQueryTaste
 

Ähnlich wie Clean code (20)

MoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache WicketMoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache Wicket
 
ClojureScript
ClojureScriptClojureScript
ClojureScript
 
React premature performance optimization
React premature performance optimizationReact premature performance optimization
React premature performance optimization
 
Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?
 
Kruskalův algoritmus - implementace
Kruskalův algoritmus - implementaceKruskalův algoritmus - implementace
Kruskalův algoritmus - implementace
 
Pokročilé techniky programování .NET a C#
Pokročilé techniky programování .NET a C#Pokročilé techniky programování .NET a C#
Pokročilé techniky programování .NET a C#
 
Petr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testyPetr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testy
 
Google Tag Manager pro mírně pokročilé
Google Tag Manager pro mírně pokročiléGoogle Tag Manager pro mírně pokročilé
Google Tag Manager pro mírně pokročilé
 
Michal Blažek - Google Tag Manager pro mírně pokročilé
Michal Blažek - Google Tag Manager pro mírně pokročiléMichal Blažek - Google Tag Manager pro mírně pokročilé
Michal Blažek - Google Tag Manager pro mírně pokročilé
 
KST/ICSHP - 1. přednáška
KST/ICSHP - 1. přednáškaKST/ICSHP - 1. přednáška
KST/ICSHP - 1. přednáška
 
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
 
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
 
Péhápkaři - Píšeme čitelný kód #3 by Driveto
Péhápkaři - Píšeme čitelný kód #3 by DrivetoPéhápkaři - Píšeme čitelný kód #3 by Driveto
Péhápkaři - Píšeme čitelný kód #3 by Driveto
 
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
 
Slovak Sun Training Day 2010 - DTrace
Slovak Sun Training Day 2010 - DTraceSlovak Sun Training Day 2010 - DTrace
Slovak Sun Training Day 2010 - DTrace
 
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
 
Czech Oracle Solaris Administrators Day 2011 - DTrace
Czech Oracle Solaris Administrators Day 2011 - DTrace Czech Oracle Solaris Administrators Day 2011 - DTrace
Czech Oracle Solaris Administrators Day 2011 - DTrace
 
Scala - jazyk budoucnosti
Scala - jazyk budoucnostiScala - jazyk budoucnosti
Scala - jazyk budoucnosti
 
Develconf coffeescript
Develconf coffeescriptDevelconf coffeescript
Develconf coffeescript
 
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQuery
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQueryData Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQuery
Data Restart 2023: Václav Ráš - 10 tipů, jak pracovat s BigQuery
 

Clean code

  • 1. { clean code } twitter.com/jirkapenzes
  • 2.
  • 3. Co je to čistý kód? • Definic je tolik, kolik je vývojářů. • Čistý kód píše pečlivý člověk. • „Čistý kód je jednoduchý a přímočarý. Čistý kód se čte jako dobře napsaná próza. Čistý kód nikdy nezatemňuje záměr návrháře, ale je plný břitkých abstrakcí a přímých toků řízení„ (Grady Booch).
  • 4.
  • 6.
  • 7.
  • 8. Proč psát čistý kód? • Chceme na svůj kód být hrdí. • Přehlednost, znovu použitelnost. • Kód se lépe udržuje. • Produktivita, méně stresu. • Zbavit se „wtf“ momentů. • Budete mít ze své práce radost a lepší pocit. • Dokumentace. • Neděláme to jen pro sebe, – občas po nás kód někdo čte.
  • 10.
  • 12. Volit správné názvy • Správná jména metod. • Správná jména tříd. • Správná jména proměnných. • Správná jména výčtových typů. • SPRÁVNÁ JMÉNA. • Největší problém v dějinách programování!
  • 13. public List<int[]> GetThem() { List<int[]> list1 = new List<int[]>(); foreach(int[] x in theList) if (x[0] == 4) list1.Add(x) return list1; } • Jaký druh položek obsahuje theList? • Jaký je význam nultého indexu položky v theList? • Jaký je význam hodnoty 4? • Jak bych mohl využít vráceného seznamu? • Co ta metoda vůbec dělá??
  • 14. public List<int[]> GetFlaggedCells() { List<int[]> list1 = new List<int[]>(); foreach(int[] x in theList) if (x[0] == 4) list1.Add(x) return list1; }
  • 15. public List<int[]> GetFlaggedCells() { List<int[]> flaggedCells = new List<int[]>(); foreach(int[] x in theList) if (x[0] == 4) flaggedCells.Add(x) return flaggedCells; }
  • 16. public List<int[]> GetFlaggedCells() { List<int[]> flaggedCells = new List<int[]>(); foreach(int[] cell in gameBoard) if (cell[0] == 4) flaggedCells.Add(cell) return flaggedCells; }
  • 17. public List<int[]> GetFlaggedCells() { List<int[]> flaggedCells = new List<int[]>(); foreach(int[] cell in gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.Add(cell) return flaggedCells; }
  • 18. public List<int[]> GetFlaggedCells() { List<int[]> flaggedCells = new List<int[]>(); foreach(int[] cell in gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.Add(cell) return flaggedCells; }
  • 19. public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new List<Cell>(); foreach(Cell cell in gameBoard) if (cell.IsFlagged) flaggedCells.Add(cell) return flaggedCells; }
  • 20. Nezkracujte názvy int d = 2; // total days int d = 2; // diameter int d = 2; // distance int s = 0; for (int i = 0; i < 10; i++) s += i; String m = "message";
  • 21. Nezkracujte názvy int totalDays = 2; int diamater = 2; int distance = 2; int suma = 0; for (int index = 0; index < 10; index++) suma += index; String message = "message"; if (a > b && a > c && a > d && a > e) max = a ; else if (b > a && b > c && b > d && b > e) max = b ;
  • 23. Smysluplně se vyjadřovat int days; int daysSinceCreation; int daysSinceLastModification; int daysSinceLastLogin; int daysSinceLastPasswordChange; int durationInDays;
  • 24. Zřetelnost a výslovnost List<Car> carsList; List<Car> cars; List<Car> newCars; public class DtaRcrd { private DateTime _geneDtDDMMYYYYhhss; private DateTime _modiDtDDMMYYYYhhss; } public class DataRecord { private DateTime _generationDate; private DateTime _modificationDate; }
  • 25.
  • 26. Jak volit správné názvy • Jména musí vysvětlovat význam. • Srozumitelné. • Vyhnout se dezinformacím. • Názvy by neměli být redundantní. – Nezahrnovat do názvu datový typ. • Vyslovitelná jména (DtaRcr). • Dodržování konvencí (?) • Nenutit nikoho přemýšlet. • Názvy z reálného světa.
  • 27. Jak volit správné názvy • Jména tříd: – Podstatná jména. • Jména metod: – Přístupové metody dle své hodnoty (get, set, is). – Slovesa. • Jedno slovo = jeden pojem.
  • 28. Datetime tomorrow = GetTomorrow(); public DateTime GetTomorrow() { Thread.Sleep(1000*60*60*24); return DateTime.Now; }
  • 29. OOP
  • 30.
  • 32.
  • 34. public class Employee { public int Id { get; set; } public String FirstName { get; set; } public String LastName { get; set; } public Money CalculatePay() { ... } public String ReportHours() { ... } ; public Report Save() { ... } }
  • 35. public class Employee { public int Id { get; set; } public String FirstName { get; set; } public String LastName { get; set; } } public class PayCalculator { public Money CalculatePay(Employee employee) { … } } public class EmployeeReporter { public Report ReportHours(Employee employee) { … } } public class EmployeeRepository { public void Save() { … } }
  • 36. 100 řádků v jedné třídě 15 – 30 řádků metody 15 tříd v namespace
  • 38. Dědictví a datové třídy • Dědíme jen to, co potřebujeme. • Datová třída je pouze nositelem dat. – Entity, kontejnery* • Slouží pro přenos dat (DTO). • Aktivní záznam – save, find, ... (?!)
  • 39. public void EmailDemo() { var email = new Email(); email.From = "jirkapenzes@hotmail.com"; email.To = "jirkapenzes@gmail.com"; email.Subject = "Spam"; email.Body = "Posílám tu URL - tinyurl.com/6s6s63p "; email.Send(); } var email = new Email(); email.From = "jirkapenzes@hotmail.com"; email.To = "jirkapenzes@gmail.com"; email.Subject = "Spam"; email.Body = "Posílám tu URL - tinyurl.com/6s6s63p"; var emailSender = new EmailSender(); emailSender.Send(email);
  • 40. Jak na metody a funkce
  • 41. Pravidla • 1. Metoda musí být malá. • 2. Metoda musí být ještě menší. • 3. Metoda by měla dělat pouze jednu věc. • 4. Volit správný název! • 5. Minimum zanoření (jedno).
  • 42.
  • 44. Pravidla • Žádný == super. • Jeden == ok. • Dva == dejme tomu. • Tři == raději se tomu vyhnout. • Více == důkladně zdůvodnit, zda je to nutné. • Předávejte objekty.
  • 45.
  • 46. Vyhnout se příkazu switch Nepoužívat blok ‚else‘
  • 47. public Record ExecuteCommand(Command command) { switch(command.Type) { case Standard: return ExecuteStandardCommand(command); case Complex: return ExecuteComplexCommand(command); default: throw new InvalidExecuteType(); } }
  • 48. public abstract class Command { public abstract Record Execute(); }
  • 49. public abstract class Command { public abstract Record Execute(); } public interface ICommandFactory { public Command MakeCommand(CommandRecord commandRecord); }
  • 50. public abstract class Command { public abstract Record Execute(); } public interface ICommandFactory { Command MakeCommand(CommandRecord commandRecord); } public class CommandFactory : ICommandFactory { public Command MakeCommand(CommandRecord commandRecord) { switch (commandRecord.Type) { case Standard: return new StandardCommand(commandRecord); case Complex: return new ComplexCommand(commandRecord); default: throw new InvalidExecuteRecordType(); } } }
  • 51. Command command = commandFactory.MakeCommand(record); Result result = command.Execute();
  • 52. Command command = commandFactory.MakeCommand(record); Result result = command.Execute();
  • 54.
  • 56. Zásady dobrého zpracování chyb • Používat výjimky! • Nepoužívat návratové kódy. • Nepředávat a nevracet hodnotu null. • Pište defenzivně. • Předávat informace o chybě. • Kontrolované výjimky (Java).
  • 57. public void Add(Car car) { if (car != null) { CarGarage garage = context.FindCarGarage(); if (garage != null) { garage.Add(car); } } } public void Add(Car car) { CarGarage garage = context. FindCarGarage(); garage.Add(car); }
  • 58. List<Car> cars = GetCars(); if (cars != null) for(Car car : cars) { Repair(car); } List<Car> cars = GetCars(); for(Car car : cars) { Repair(car); }
  • 59.
  • 61.
  • 62. Práce s daty Objekty a struktury
  • 63. Práce s daty • Při práci s daty se snažit o nezávislost. • Odstínění datového zdroje. • Repository pattern, DAO.
  • 64. const string query = "select name, isbn from book where year = @year"; using (var connection = new SqlConnection(connectionString)) { connection.Open(); var sqlCommand = new SqlCommand(query, connection); sqlCommand.Parameters.AddWithValue("@year", year); var reader = sqlCommand.ExecuteReader(); while (reader.Read()) { var book = new Book { Name = reader["name"], Isbn = reader["isbn"] }; Display(book); } }
  • 65. const string query = MakeSqlQuery(BookQuery.FindBooksByYear); using (var connection = new SqlConnection(connectionString)) { connection.Open(); var sqlCommand = new SqlCommand(query, connection); sqlCommand.Parameters.AddWithValue("@year", year); var reader = sqlCommand.ExecuteReader(); while (reader.Read()) { var book = new User { Name = reader["name"], Isbn = reader["isbn"] }; Display(book); } }
  • 66. var books = bookRepository.FindByYear(2002); foreach (var book in books) Display(book); public interface IBookRepository { Book FindById(long id); IEnumerable<Book> FindAll(); IEnumerable<Book> FindByCategory(Category category); IEnumerable<Book> FindByAuthor(Author author); IEnumerable<Book> FindByTag(string tag); } var books = bookDao.Fetch(new BookByYearQuery(2002)); foreach (var book in books) Display(book);
  • 68.
  • 69. double CalculatePrice() { // price is base price - quantity discount + shipping return _quantity * _itemPrice - Math.Max(0, _quantity - 500) * _itemPrice * 0.05 + Math.Min(_quantity * _itemPrice * 0.1, 100.0); }
  • 70. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; return _quantity * _itemPrice - Math.Max(0, _quantity - 500) * _itemPrice * 0.05 + Math.Min(_quantity * _itemPrice * 0.1, 100.0); }
  • 71. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; return basePrice - Math.Max(0, _quantity - 500) * _itemPrice * 0.05 + Math.Min(_quantity * _itemPrice * 0.1, 100.0); }
  • 72. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; return basePrice - Math.Max(0, _quantity - 500) * _itemPrice * 0.05 + Math.Min(basePrice * 0.1, 100.0); }
  • 73. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; double quantityDiscount = Math.Max(0, _quantity - 500) * _itemPrice * 0.05; return basePrice - quantityDiscount + Math.Min(basePrice * 0.1, 100.0); }
  • 74. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; double quantityDiscount = Math.Max(0, _quantity - 500) * _itemPrice * 0.05; double shipping = Math.Min(basePrice * 0.1, 100.0); return basePrice - quantityDiscount + shipping; }
  • 75. double CalculatePrice() { // price is base price - quantity discount + shipping double basePrice = _quantity * _itemPrice; double quantityDiscount = Math.Max(0, _quantity - 500) * _itemPrice * 0.05; double shipping = Math.Min(basePrice * 0.1, 100.0); return basePrice - quantityDiscount + shipping; }
  • 76. double CalculatePrice() { return basePrice() - quantityDiscount() + shipping(); } private double quantityDiscount() { return Math.Max(0, _quantity - 500) * _itemPrice * 0.05; } private double shipping() { return Math.Min(basePrice() * 0.1, 100.0); } private double basePrice() { return _quantity * _itemPrice; }
  • 77. double CalculatePrice() { return basePrice() - quantityDiscount() + shipping(); } double CalculatePrice() { // price is base price - quantity discount + shipping return _quantity * _itemPrice - Math.Max(0, _quantity - 500) * _itemPrice * 0.05 + Math.Min(_quantity * _itemPrice * 0.1, 100.0); }
  • 78. Refactoring • Neměnit logiku aplikace. • Rozházet kód do tříd a metod. • Provádět iterativně. • Pozor na názvy. – Zloději, loupežníci, banditi, zločinci, rafani, …
  • 80.
  • 81. Formátování a konvence • 1. Formátovat. • 2. Dodržovat jazykové konvence. • Konvence pro přístupové metody. • Velikost písmen. • Týmové konvence.
  • 83.
  • 84.
  • 85. Shrnutí • Déle přemýšlet nad názvy. • Zkusit kód častěji formátovat. • Držet se konvencí. • Testování. • Nestačí, aby to jen fungovalo …