Esercizio su pattern

di il
6 risposte

Esercizio su pattern

Modificare la classe utilizzando il Command Pattern in modo tale da incapsulare l'azione associata ad un Bottone tramite il metodo esegui e renderla parametrizzata.

abstract class Bottone
	{
	abstract public void esegui();
	}

class Bottone1 extends Bottone
	{
	public void esegui() { System.out.println("ciao"); }
	}

class Bottone2 extends Bottone
{
	private int k, j;
	private String label;
	public Bottone2 (int k, int j) { this.k = k; this.j = j; }
	
	public void esegui() { label = ""+k/j; }
}

In pratica devo creare un'interfaccia:

interface Command{ void esegui() ;}
la quale verrà implementata da tanti comandi che effettuano operazioni diverse. Poi la classe che ne richiede l'esecuzione dovrà avere una forma del genere:

class Bottone{
	public void esegui(Command com){ com.esegui();}
}
oppure:

class Bottone{
	private Command com;
	public Bottone(Command com){this.com=com;}
	public void esegui(){ com.esegui();}
}
Ma come posso rispettare il pattern e soddisfare l'esegui() del Bottone2 che utilizza i suoi campi??

Ciao e buona giornata

6 Risposte

  • Re: Esercizio su pattern

    Paolovox ha scritto:


    Ma come posso rispettare il pattern e soddisfare l'esegui() del Bottone2 che utilizza i suoi campi??
    Esempio basilare: un certo "comando" deve prendere il testo da un textfield e copiarlo in un altro textfield. Esempio "stupido" (ma neanche tanto) giusto per capire.
    Da qualche parte verrà ricevuto il riferimento all'oggetto del comando, che viene visto chiaramente solo attraverso la interfaccia di "astrazione" e quindi senza sapere nient'altro (a parte il fatto di dover poi invocarci il esegui() ).
    Questo vuol dire una cosa molto semplice: tutte le informazioni utili per eseguire il comando dovranno pertanto essere nell'oggetto che implementa il Command!
    Con l'esempio sopra, una classe che implementa il Command es. CopiaTextfieldCommand dovrà avere i riferimenti o poter accedere ai due textfield.
  • Re: Esercizio su pattern

    Quindi per mettere a fattor comune il metodo esegui sia di Bottone1 che Bottone2, utilizzo comunque quest'interfaccia:
    
    public interface Command {
    
    	void execute();
    }
    
    === BOTTONE1 ===
    
    public class Bottone {
    	
    	public void esegui(Command com){
    		com.execute();
    	}
    }
    
    
    === BOTTONE2 ===
    
    public class Bottone2{
    
    	private String label;
    	private int k,j;
    	
    	public Bottone2(int k, int j){
    		this.k = k;
    		this.j = j;
    	}
    	
    	public int getK(){return k;}
    	public int getJ(){return j;}
    	public void setStr(String label){ this.label=label;}
    	
    	public void esegui(Command com){
    		com.execute();
    	}
    	
    	public String toString(){
    		return label;
    	}
    	
    	public static void main(String[] args) {
    		
    		Bottone2 b = new Bottone2(4,2);
    		b.esegui(()->{b.setStr(""+b.getK()/b.getJ());});
    		
    		System.out.println(b);
    	}
    
    }
    
    Può andare oppure non ci ho capito proprio nulla??
    Così è possibile offrirgli varie azioni in qualsiasi momento.
  • Re: Esercizio su pattern

    Paolovox ha scritto:


    Può andare oppure non ci ho capito proprio nulla??
    Così è possibile offrirgli varie azioni in qualsiasi momento.
    No .. non ha granché senso.
    Prova a vedere
    Se poi non dovesse essere ancora chiaro, potrei fare un esempio io.
  • Re: Esercizio su pattern

    Vediamo se ci sono adesso.
    Creo una classe che mi fornisce le varie azioni:
    
    public class Exec {
    
    	public void esegui(){
    		System.out.println("ciao");
    	}
    	
    	public String esegui(int k, int j){
    		return ""+k/j;
    	}
    	
    }
    
    Poi ho la mia interfaccia:
    
    public interface Command {
    
    	void execute();
    }
    
    Adesso le classi che richiedono l'esecuzione di un'azione in particolare, implementano l'interfaccia Command ed hanno al loro interno un campo come oggetto Exec, il quale viene inizializzato da costruttore.
    
    public class Bottone1 implements Command{
    	
    	private Exec ex;
    	
    	public Bottone(Exec ex){
    		this.ex = ex;
    	}
    
    	@Override
    	public void execute() {
    		ex.esegui();
    	}
    }
    
    public class Bottone2 implements Command{
    
    	private String label;
    	private int k,j;
    	private Exec ex;
    	
    	public Bottone2(Exec ex, int k, int j){
    		this.ex = ex;
    		this.k = k;
    		this.j = j;
    	}
    	
    	@Override
    	public void execute() {
    		label = ex.esegui(k, j);		
    	}
    }
    
    Somiglia quasi al Singleton ma da quanto ho capito il Command offre diverse implementazioni di azioni differenti, mentre il Singleton implementazioni differenti della stessa azione.

    Può andare adesso?
  • Re: Esercizio su pattern

    Paolovox ha scritto:


    Vediamo se ci sono adesso.
    Ehm ... più o meno ... sì, quasi.

    Paolovox ha scritto:


    mentre il Singleton implementazioni differenti della stessa azione.
    Il Singleton non c'entra niente con azioni o comandi. È semplicemente il principio di poter avere una sola istanza di una certa classe. Poi cosa rappresenti questa istanza ... dipende.
  • Re: Esercizio su pattern

    Si scusa, ho confuso lo Strategy con il Singleton. Mi serve almeno un'altra settimana per far maggior chiarezza sui design pattern. Poi quando avrò più tempo, una bella lettura della Bibbia dei Design Pattern (Design Patterns: Elements of Reusable Object-Oriented Software) non mi farà male.
    Adesso mi stanno sparaflashando in testa migliaglia di informazioni alla settimana, rischiando un overflow mentale.
Devi accedere o registrarti per scrivere nel forum
6 risposte