Come ottimizzereste questo codice? [POST LUNGO]

di il
4 risposte

Come ottimizzereste questo codice? [POST LUNGO]

Ciao.
continuo i miei studi in java, e mi sono inventato un programmino che simula un CUP, senza troppi controlli perché al momento non mi interessano.
Ero quasi soddisfatto del lavoro svolto, quando ho iniziato a scrivere la classe principale e mi sono accorto della quantità di codice ripetuto:
le classi basi sono (indipendentemente se concettualmente sono giuste o sbagliate)

public abstract class Persona {   //ASTRATTA
	private String nominativo;

	public Persona(String nominativo) {
		setNominativo(nominativo);
	}

	public String getNominativo() {
		return nominativo;
	}

	public void setNominativo(String nominativo) {
		this.nominativo = nominativo;
	}

	@Override
	public String toString() {
		return "Persona [" + getNominativo() + "]";
	}
}

//POI 

public class Medico extends Persona {
	private String qualifica;
	
	public Medico(String nominativo, String qualifica) {
		super(nominativo);
		setQualifica(qualifica);
	}

	public String getQualifica() {
		return qualifica;
	}

	public void setQualifica(String qualifica) {
		this.qualifica = qualifica;
	}

	@Override
	public String toString() {
		return "Medico [" + super.getNominativo() + ": " + getQualifica() + "]";
	}
	
}
 // E

public class Paziente extends Persona {
	private int codice;
	private Visita visita;
	
	public Paziente(String nominativo, int codice) {
		super(nominativo);
		setCodice(codice);
		this.visita=null;
	}

	public int getCodice() {
		return codice;
	}

	public void setCodice(int codice) {
		this.codice = codice;
	}

	public Visita getVisita() {
		return visita;
	}

	public void setVisita(Visita visita) {
		this.visita = visita;
	}

	@Override
	public String toString() {
		return "Paziente [" + super.getNominativo() + " - " + getCodice() + "]";
	}
}

// POI LA CLASSE VISITA
public class Visita {
	private String tipo;
	private Persona medico;
	
	public Visita() { }

	public Visita(String tipo, Persona medico) {
		setTipo(tipo);
		setMedico(medico);
	}

	public String getTipo() {
		return tipo;
	}

	public void setTipo(String tipo) {
		this.tipo = tipo;
	}

	public Persona getMedico() {
		return medico;
	}

	public void setMedico(Persona medico) {
		this.medico = medico;
	}

	@Override
	public String toString() {
		return "Visita [" + getTipo() + ", [" + getMedico() + "]]";
	}
}

// E INFINE PRENOTAZIONE
public class Prenotazione {
	private Persona paziente;
	private Visita visita;
	
	public Prenotazione(Persona paziente, Visita visita) {
		setPaziente(paziente);
		setVisita(visita);
	}

	public Persona getPaziente() {
		return paziente;
	}

	public void setPaziente(Persona paziente) {
		this.paziente = paziente;
	}

	public Visita getVisita() {
		return visita;
	}

	public void setVisita(Visita visita) {
		this.visita = visita;
	}

	@Override
	public String toString() {
		return "Prenotazione [" + getPaziente() + ", " + getVisita() + "]";
	}
}
la classe principale però, è piena di codice che per una sola istruzione o per un oggetto ha del codice molto simile tra metodo e metodo:

package CUP;

import java.util.*;

public class GestionePrenotazioni {
	private List<Prenotazione> prenotazioni = new ArrayList<>();
	private List<Persona> pazienti = new ArrayList<>();
	private List<Persona> medici = new ArrayList<>();

	private int cercaInPersone(List<Persona> lista, String nominativo) {
		int res = -1;
		for(int i=0; i< lista.size(); i++) {
			if (nominativo.equalsIgnoreCase(lista.get(i).getNominativo()))
				res = i;
		}
		return res;
	}

	public boolean addPaziente(String nominativo, int codice) {
		if (cercaInPersone(pazienti, nominativo)!=-1)
			return false;
		return pazienti.add(new Paziente(nominativo, codice));
	}

	public boolean addMedico(String nominativo, String qualifica) {
		if (cercaInPersone(medici, nominativo)!=-1)
			return false;
		return medici.add(new Medico(nominativo, qualifica));
	}

	public boolean associaVisita (String tipo, String paziente, String medico) {
		int idxMedico = cercaInPersone(medici, medico);
		if (idxMedico == -1) {
			System.out.println("Inserire prima il medico");
			return false;
		}

		int idxPaziente = cercaInPersone(pazienti, paziente);
		if (idxPaziente == -1) {
			System.out.println("Inserire prima il paziente");
			return false;
		}
		
		Visita v = new Visita(tipo, medici.get(idxMedico));
		Prenotazione p = new Prenotazione(pazienti.get(idxPaziente), v);
		return prenotazioni.add(p);
	}
	
	private Prenotazione cercaPrenotazione(String paziente) {
		for (int i=0; i< prenotazioni.size();i++) {
			if (prenotazioni.get(i).getPaziente().getNominativo().equalsIgnoreCase(paziente)) {
				return prenotazioni.get(i);
			}
		}
		return null;
	}
	
	public void stampaPrenotazione(String paziente) {
		Prenotazione p = cercaPrenotazione(paziente);
		if (p != null) {
			System.out.println(p);
		}else {
			System.out.println("Nessuna prenotazione trovata!");
		}
	};
}
mi piace aver racchiuso in un unico metodo ausiliario la ricerca del paziente e del medico, usando la classe Persona invece che le sottoclassi,
ma
AddMedico, addPaziente e associaVisita ha del codice ripetuto che vorrei ottimizzare ma non riesco......forse non si può.

Il programma funziona, ho omesso tutti i controlli per non dilungarmi troppo, infatti, nel tester ho scritto:

public class Tester {

	public static void main(String[] args) {
		GestionePrenotazioni gp = new GestionePrenotazioni();
		gp.addMedico("Medico UNO", "Oculista");
		gp.addMedico("Medico DUE", "Cardiologo");
		gp.addPaziente("Paziente UNO", 123);
		gp.addPaziente("Paziente DUE", 456);
		gp.associaVisita("Oculistica", "Paziente UNO" , "Medico UNO");
		gp.associaVisita("Cardiologica", "Paziente DUE" , "Medico DUE");
		gp.stampaPrenotazione("Paziente UNO");
		gp.stampaPrenotazione("Paziente DUE");
		gp.stampaPrenotazione("Paziente TRE");
		gp.addPaziente("Paziente TRE", 789);
		gp.associaVisita("Oculistica", "Paziente TRE" , "Medico DUE");
		gp.stampaPrenotazione("Paziente TRE");
	}
}

l'output:
Prenotazione [Paziente [Paziente UNO - 123], Visita [Oculistica, [Medico [Medico UNO: Oculista]]]]
Prenotazione [Paziente [Paziente DUE - 456], Visita [Cardiologica, [Medico [Medico DUE: Cardiologo]]]]
Nessuna prenotazione trovata!
Prenotazione [Paziente [Paziente TRE - 789], Visita [Oculistica, [Medico [Medico DUE: Cardiologo]]]]
ed ho asociato una visita oculistica ad un cardiologo, ma quello che mi premeva era capire se si poteva ottimizzare il codice ad esempio con interfacce funzionali o se in questi casi, meglio lasciare così perché in effetti si agisce su oggetti diversi , un arrayList di Pazienti e uno di Medici che hanno alcuni attributi diversi tra loro.

Grazie. ciao
Tagan

4 Risposte

  • Re: Come ottimizzereste questo codice? [POST LUNGO]

    tagan ha scritto:


    
    public class Paziente extends Persona {
    	private int codice;
    	private Visita visita;
    
    Uhm .... Paziente che ha una (1) Visita potrebbe forse essere "dubbio". E se un paziente facesse più visite??

    tagan ha scritto:


    
    public class Visita {
    	private String tipo;
    	private Persona medico;
    
    Attenzione ad una cosa: se ti aspetti un medico ma l'hai messo come Persona, qualcuno potrebbe passare lì un oggetto Paziente ... che non ha senso.

    Comunque è qui che avrebbe più senso mettere il paziente. E' la visita che "lega" paziente E medico.

    tagan ha scritto:


    public class GestionePrenotazioni {
    Su GestionePrenotazioni si potrebbero sollevare alcune questioni ma la guardo meglio appena ho più tempo.
  • Re: Come ottimizzereste questo codice? [POST LUNGO]

    andbin ha scritto:


    Uhm .... Paziente che ha una (1) Visita potrebbe forse essere "dubbio". E se un paziente facesse più visite??
    Certo, ma ho inteso che non possano esistere pazienti omonimi e ogni paziente ha una sola visita, se ne ha un'altra viene distrutat la prima e ricreata una seconda, metodi che non ho ancora fatto.

    andbin ha scritto:


    tagan ha scritto:


    
    public class Visita {
    	private String tipo;
    	private Persona medico;
    
    Attenzione ad una cosa: se ti aspetti un medico ma l'hai messo come Persona, qualcuno potrebbe passare lì un oggetto Paziente ... che non ha senso.
    ecco, questo è una bella ossevazione.
    per mantenere il vantaggio della ricerca sull ArrayList di tipo Persona, posso mettere nel setMedico un test di tipo
    if (... instanceof ...) ? e restituire un messaggio se la Persona è oggetto di Paziente?

    Grazie.
  • Re: Come ottimizzereste questo codice? [POST LUNGO]

    tagan ha scritto:


    Certo, ma ho inteso che non possano esistere pazienti omonimi e ogni paziente ha una sola visita, se ne ha un'altra viene distrutat la prima e ricreata una seconda, metodi che non ho ancora fatto.
    Qui è solo questione di come si vogliono trattare e usare gli oggetti ...

    tagan ha scritto:


    ecco, questo è una bella ossevazione.
    per mantenere il vantaggio della ricerca sull ArrayList di tipo Persona, posso mettere nel setMedico un test di tipo
    if (... instanceof ...) ? e restituire un messaggio se la Persona è oggetto di Paziente?
    No, non serve (e sarebbe pure "brutto"). Se cercaInPersone vuoi usarlo sia da addPaziente/addMedico/ecc.. è semplice:

    private List<Paziente> pazienti = new ArrayList<>();
    private List<Medico> medici = new ArrayList<>();

    e poi se ti basta ottenere solo l'indice:

    private int cercaInPersone(List<? extends Persona> lista, String nominativo) {

    e lo puoi usare sia con List<Paziente> che List<Medico>

    Se invece (per dire, come esempio) volessi ottenere l'oggetto trovato, allora fai diventare cercaInPersone un metodo "generico" (quello sopra con il extends NON è generico, nel senso che non dichiara una type variable).
  • Re: Come ottimizzereste questo codice? [POST LUNGO]

    andbin ha scritto:


    No, non serve (e sarebbe pure "brutto"). Se cercaInPersone vuoi usarlo sia da addPaziente/addMedico/ecc.. è semplice:

    private List<Paziente> pazienti = new ArrayList<>();
    private List<Medico> medici = new ArrayList<>();

    e poi se ti basta ottenere solo l'indice:

    private int cercaInPersone(List<? extends Persona> lista, String nominativo) {

    e lo puoi usare sia con List<Paziente> che List<Medico>

    Se invece (per dire, come esempio) volessi ottenere l'oggetto trovato, allora fai diventare cercaInPersone un metodo "generico" (quello sopra con il extends NON è generico, nel senso che non dichiara una type variable).
    giustissimo, quel "List<? extends Persona>" non l'avevo ricordato, o meglio non l'ho ancora appreso del tutto. devo farci degli esercizi sopra per capirlo per bene e farlo "mio".

    Per provare farò un altro metodo generico per esercitarmi e capire se davvero ho compreso la potenzialità delle classi e metodi generici.
    Grazie, sempre molto gentile
    Tagan
Devi accedere o registrarti per scrivere nel forum
4 risposte