No tak se musím přiznat, že z toho až tak úplně nejsem moudrý nejsem.

Asi jsem dneska nějaký natvrdlý, ale není mi úplně jasné, jak přepsat
do Visitor patternu následující jednoduchý příkládek:

Mějme příklad "if podle typu parametru":

interface Data {
}
class A implements Data {
   String name;
}

class B extends A {
  int size;
}

class ServiceA {
  void run() {
    A a = ((Servisa)ctx.lookup("servisa")).callFunc(new A());
    System.out.println(a);
   }
}

class ServiceB {
  void run() {
    B b = (B) ((Servisa)ctx.lookup("servisa")).callFunc(new B());
    System.out.println(b);
   }
}

interface Servisa {
   A callFunc(A result);
}

class ServisaImpl implements Servisa {
  public A callFunc(A result) {
    return new DalsiServisa().doSomething(result);
  }
}

class DalsiServisa {
  A doSomething(A result) {
           //....
           if (result instanceof B) { return new DelejFuncB().akce(result);}
           else { return new DelejFuncA().akce(result);}
           //.....
  }
}

interface Delej {
   A akce(A result);
}

class DelejFuncA implements Delej{
   public A akce(A result)  {ResultSet rs =
con.createStatement("select name from tabulka"); rs.next();
result.name = rs.getString("name"); return result;}
}

class DelejFuncB implements Delej {
  public A akce(A AResult) { B result = (B)aResult; ResultSet rs =
con.createStatement("select name,size from tabulka"); rs.next();
result.name = rs.getString("name"); result.size = rs.getInt("size");
return result;}
}

****************
A teď k tomu přepisu - co je visitorem? DelejFuncA a DelejFuncB? A
Data má potom implementovat accept(Delej)? Servisa má pak mít dvě
metody a v každé vytvořit instanci Delej podle toho, co kdo má co
dělat? A to ještě máme jednoduchý příklad, kdy jako vstup jde Data. Co
když chci ona Data vytvořit?

A v čem mi to potom pomůže kromě toho, že if neřeším programově v
kódu, kde by to bylo IMHO logické, ale nechávám to na Javě, přičemž
musím všechny mezivýpočty delegovat do parametrů více metod, kdy musím
mít jednu každou pro každý hook)? Tady nejde o tom, aby se jeden
visitor vypořádal z různými daty, ale aby jeden generátor na základě
znalostí akceptora vygeneroval pro různé akceptory různě odekorovaná
typově tatáž data.

Dík za vysvětlení,

Dne 19. července 2010 14:55 Karel Tejnora <ka...@tejnora.cz> napsal(a):
> Visitor pattern.
>
> Evidentně budete zasahovat do kódu, takže místo přidávání and cp a boolean
> to udělat trochu jinak.
>
> (Tady se da udelat i extends ale to se provaze s implementaci)
>
> Extrahovat interface (IfaceA) ze současné struktury (StructA) - a přidat
> druhou strukturu (StructB) která  implementuje tento interface také (může i
> rožšiřovat StructA).
>
> Interface bude mít navíc metodu jako "setResults(ServiceInterface
> serviceA)".
>
> A service bude mít selectResult(IfaceA obj) která zavolá
> Iface.setResults(this)
>
> StructA.setResults(ServiceInterface service)
> {
>     service.selectResults(this); // v tomhle pripade uz "this" je plne znamy
> typ
> }
>
> StructB.setResults(ServiceInterface service)
> {
>     service.selectResults(this); // v tomhle pripade uz "this" je plne znamy
> typ
> }
>
> no a konecne v ServiceInterface bude mit
>
> ServiceInterface.selectResult(Struct A) a
> ServiceInterface.selectResult(Struct B)
>
> Takhle nebudete mit zadny if else if else if a v budoucnu pokud pridate
> StructC D E F G H
> zasahnete kod ServiceInterface. Ono dokonce lze zdetit i ServiceInterface na
> ServiceIterfaceCDEF
>
> a v StructCDEF bude mit ServiceIterfaceCDEF - protoze Implementace zna sebe
> diky "this" tak to bude dal fungovat.
>
> Testovani: pokud se zavede boolean (N=2) nebo int (N) a to k tomu kazda
> dalsi stuktura (M) melo by se napsat NxM testu. Takhle 2xM. Tohle ma spis
> ukazat tu vyhodnost.
>
>
> Karel
>
> A je to refactoring safe. Coz v pripade booleanu nebo intu neni
>
> Naopak OOP bylo vymysleno tak aby se kod funkcni a odzkouseny pouzival znova
> a znova a znova.
>
>
>> d) pro omezení zbytečného výpočtu statistik v c) přidat do volání API
>> boolean (nebo raději int pro více možných stavů) parametr udávající,
>> zda výpočty volat či nikoli (rozhodování může to být řešeno dědičností
>> konkrétní datové struktury, ale to je pořád onen boolean či int a s
>> ním někde svázaný switch či kupa ifů).
>
>



-- 
Oto 'tapik' Buchta, ta...@buchtovi.cz, http://tapikuv.blogspot.com

Odpovedet emailem