|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
[JAVA]pochi if-else,velocità, e leggibilità...e anche patterns
Apro questo thread con l'intentzione di racchiudere un pò di "trucchetti" per migliorare la qualità del nostro codice.
Per iniziare, un problema che mi si presenta spesso è quello di dover eseguire un metodo a seconda del valore che assume una determinata variabile. Ad esempio: Codice:
public void execute(int type){ switch(type){ case A: actionA();return; case B: actionB();return; ... } } Di solito risolvo creando una classe per ogni azione che devo compiere: Codice:
class A extends C{ ... public void execute(){ System.out.println("action A"); } } class B extends C{ ... public void execute(){ System.out.println("action B"); } } abstract class C{ ... public void execute(); } class Executor{ private C c; public Executor(int type){ c=valute(type); } private C valute(int type){ switch(type){ case A: return new A(); case B return new B(); } } public void execute(){ c.execute(); } } ... ... Executor e=new Executor(A); e.execute(); ... ... C'è modo per eliminare anche lo switch? Secondo voi è una buona soluzione? |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Spostare "new A()", "new B()" alla chiamata del costruttore di Executor?
Executor e = new Executor(new A()); e.execute();
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
io farei cosi'....
Codice:
class A implements C { ... public void execute() { System.out.println("action A"); } } class B implements C { ... public void execute() { System.out.println("action B"); } } public interface C { public void execute(); } class Executor{ private C myAction; public Executor(C myAction){ this.myAction = myAction; } public void execute(){ myAction.execute(); } } ... ... A a = new A(); Executor executor = new Executor(a); executor.execute();
__________________
![]() Ultima modifica di ^TiGeRShArK^ : 04-03-2009 alle 13:17. |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 4683
|
Quote:
__________________
Firma eliminata e avatar cambiato. Troppa gente giudica il monaco dall'abito. |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
yes..
m'ero perso un pezzo...
__________________
![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
mmmm...
rileggendo forse ho capito cosa intendeva fare... se ho capito bene basterebbe aggiungere al mio codice un array di action (o una mappa a seconda dei valori che deve assumere la variabile) e richiamare semplicemente map[variable].execute(); ho capito bene stavolta o ancora mi sfugge qualcosa? ![]()
__________________
![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
tradotto in codice:
Codice:
class A implements Action { ... public void execute() { System.out.println("action A"); } } class B implements Action { ... public void execute() { System.out.println("action B"); } } public interface Action { public void execute(); } class Executor{ private Action[] myActions; public Executor(Action[] myActions){ this.myActions = myActions; } public void execute(int val){ myActions[val].execute(); } } int val = ???; ... ... Action[] myActions = new Actions[2]; myActions[0] = new A(); myActions[1] = new B(); Executor executor = new Executor(myActions); executor.execute(val);
__________________
![]() |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Quote:
La domanda sorge spontanea ora, è meglio il "mio" metodo che fa usa di switch(o if) o quello proposta da te che istanzia oggetti senza avere la sicurezza che poi vengano effettivamente usati? Ho paura che a parte il fatto che non vengano usati if-else non porti altri vantaggi, perchè sicuramente non è più veloce visto che deve istanziare tanti oggetti quante sono le varie azioni che devo fare, ne di spazio per lo stesso motivo. Sono ovviamente mie supposizioni campate in aria, cosa ne pensi? Ultima modifica di MEMon : 04-03-2009 alle 17:37. |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Se banalmente devo eseguire del codice solo se vera una determinata condizione, esempio:
Codice:
... if(cond){ esegui(); } ... Inoltre sempre nel medisimo caso, è meglio come scritto sopra, o così: Codice:
... if(!cond) return; esegui(); ... |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
Quote:
Inoltre con l'array crei solo un'istanza di ogni action, invece con l'if crei una nuova istanza della action corrente per ogni esecuzione e questo peggiora sia la velocità di esecuzione che l'occupazione di memoria prima del passaggio del GC. comunque tutto questo in teoria... per vedere l'effettiva differenza prestazionale l'unica cosa è provare con un profiler il codice in modo da vedere velocità di esecuzione e occupazione di memoria.
__________________
![]() |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
Quote:
Nel caso di un oggetto qualsiasi si ha qualcosa del genere: Codice:
String cond = ???; .... Map<String, Action> map = new HashMap<String, Action>(); map.add("pippo", new Pippo()); map.add("pluto", new Pluto()); map.add("topolino", new Topolino()); map.get(cond).execute(); Codice:
if (!cond) return; execute(); if(cond) execute();
__________________
![]() |
|
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Jan 2002
Città: Napoli
Messaggi: 1726
|
Quote:
comunque partendo dal problema di partenza: Codice:
public void execute(int type){ non vedo perchè il codice che chiama execute, non dovrebbe chiamare direttamente il metodo che vuole eseguire, piuttosto che passare da questo "wrapper".
__________________
Se buttassimo in un cestino tutto ciò che in Italia non funziona cosa rimarrebbe? Il cestino. |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Quote:
Codice:
... A a=new A(); B b=new B(); if(type==INT_A){ a.eseguie(); } else if(type==INT_B){ b.esegui(); } ... |
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Quote:
|
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
si, array e mappe sono usati comunemente, insieme al polimorfismo e a qualche altro strumento, per eliminare gli if.
__________________
![]() |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
Quote:
__________________
![]() |
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ma nel tuo prima post non avevi capito quello che chiedevo, è ovvio che se so a priori di usare un metodo di A allora non serve l'esecutore, ma la situazione non è quella
![]() La situazione è che in base a una condizione o al valore di una variabile devo fare cose diverse. |
![]() |
![]() |
![]() |
#18 | |
Senior Member
Iscritto dal: Jan 2002
Città: Napoli
Messaggi: 1726
|
Quote:
ma cmq anche il polimorfismo deve una logica di base..... se hai super-classe Shape, estesa da Square, Circle chiamerai Codice:
square.computeArea() circle.computeArea()
__________________
Se buttassimo in un cestino tutto ciò che in Italia non funziona cosa rimarrebbe? Il cestino. |
|
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
|
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12103
|
Quote:
da cosa dipende?
__________________
![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:32.