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