www.rozumim.cz

Code smell: výpočet parametru přímo ve volání metody

Jak už jsem psal, Code smell je konstrukce v kódu, ve které se skvěle daří chybám.

Dnešní ukázka je výpočet hodnoty parametru přímo ve volání metody.

Příklad

Stejný jako minule.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class EditaceDokumentu {
  
  private Set<Dokument> dokumenty;

  // další fieldy a metody
  // (...)
  
  public void ulozDokumenty() {
    
    ulozDokumenty(dokumenty, urciDruhUkladanyJakoPrvni());
    //                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- to mám na mysli!
    
    ulozDokumenty(dokumenty, urciDruhUkladanyJakoDruhy());
    
    // zde neznám již uložené druhy dokumentů! tenhle postup mě nutí 
    // v metodě ulozOstatniDokumenty() duplikovat logiku a hrozí chyba 
    ulozOstatniDokumenty(dokumenty);
  }
  
  private DokumentDruh urciDruhUkladanyJakoPrvni() {
    
    // rozhodne, jaký druh je ukládaný jako první
    // (...)
  }
  
  private DokumentDruh urciDruhUkladanyJakoDruhy() {
    
    // rozhodne, jaký druh je ukládaný jako druhý
    // (...)
  }
  
  private void ulozDokumenty(Set<Dokument> dokumenty, DokumentDruh druh) {

    // uloží všechny dokumenty z kolekce 'dokumenty', které jsou druhu 'druh'
    // (...)
  }
  
  private void ulozOstatniDokumenty(Set<Dokument> dokumenty) {
    
    // uloží všechny dokumenty z kolekce 'dokumenty', u kazdého nejdříve
    // zkontroluje zda není prvním nebo druhým již uloženým druhem a to
    // pomocí vlastní, duplicitní, logiky
    // (...)
  }
}

Protože se v ulozOstatniDokumenty() určují ukládané druhy dokumentů přímo ve volání metody ulozDokumenty(), nejsou potom k dispozici pro závěrečné uložení a výsledkem je zbytečné duplikování logiky pro jejich zjištění v ulozOstatniDokumenty().

Opravená vezre

Opět stejná jako minule.

Zjištěné druhy dokumentů si uložím a znovu použiji při ukládání ostatních dokumentů.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class EditaceDokumentu {
  
  private Set<Dokument> dokumenty;

  // další fieldy a metody
  // (...)
  
  public void ulozDokumenty() {
  
    DokumentDruh prvniDruh = urciDruhUkladanyJakoPrvni();
    ulozDokumenty(dokumenty, prvniDruh);
    
    DokumentDruh druhyDruh = urciDruhUkladanyJakoDruhy()
    ulozDokumenty(dokumenty, druhyDruh);
    
    ulozOstatniDokumenty(dokumenty, Sets.newHashSet(prvniDruh, druhyDruh));
  }
  
  private DokumentDruh urciDruhUkladanyJakoPrvni() {
    
    // stejné
    // (...)
  }
  
  private DokumentDruh urciDruhUkladanyJakoDruhy() {
    
    // stejné
    // (...)
  }
  
  private void ulozDokumenty(Set<Dokument> dokumenty, DokumentDruh druh) {

    // stejné
    // (...)
  }
  
  private void ulozOstatniDokumenty(Set<Dokument> dokumenty, 
                                    Set<DokumentDruh> kromeDruhu) {
    
    // uloží všechny dokumenty z kolekce 'dokumenty', vynechá ty, které mají
    // druh z kolekce 'kromeDruhu'
    // (...)
  }
}

Závěr

Je velmi pravděpodobné, že parametry volání metody budete později potřebovat. Zamyslete se, zda je opravdu chcete vypočítávát až (jen) ve chvíli volání metody. A rozhodně se nebojte pár řádek navíc.

16. 12. 2013, kategorie:
comments powered by Disqus