Estratto del documento

Java idioms

Item 1: Considerare gli static factory methods piuttosto che i costruttori

Static Factory Method sono detti anche costruttori statici, ovvero sono metodi statici che ritornano l'istanza di una classe. Possono / devono essere usati al posto o in aiuto dei costruttori normali di classe.

public Class Rectangle {
    public Rectangle() {...} // a constructor
    public static Rectangle getInstance() { // S.F.M
        Rectangle r;
        return r;
    }
}
// Client Code
Rectangle r1 = new Rectangle(); // creation through a standard constructor
Rectangle r2 = Rectangle.getInstance(); // creation through a static factory method

Ogni SFM può avere un diverso nome che ne può illustrare la sua specificità, mentre i costruttori standard sono limitati ad avere lo stesso nome della classe (es. .getInstance(), .getShape(), ecc.). Inoltre, con gli SFM si può controllare il modo in cui gli oggetti sono creati. È possibile ritornare un oggetto di un qualunque sottotipo del loro tipo di ritorno.

Limiti

  • Le classi senza costruttore pubblico o protetto non possono essere sottoclassate, no classi derivate.
  • SFM non possono rimpiazzare completamente i costruttori classici, a meno che non si decida che in quel momento non si ha bisogno di subclassare.
  • Essendo metodi statici, sono facilmente confondibili con altri metodi statici, per cui risulta necessario una convenzione per definirli: getInstance(), getType(), newInstance(), newType(), valueOf().
  • Le limitazioni sono risolvibili tramite Patterns Factory e Abstract Factory.

Item 2: Applicare la proprietà singleton con un costruttore privato

Singleton è una classe che è insaziabile solamente una volta. Abbiamo due esempi implementativi:

  1. Istanza creata da getInstance() alla prima invocazione, alla quale poi si mantiene un riferimento.
public Class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { ...... }
}
// Client Code
Elvis.INSTANCE.metodiVaridiElvis
  1. Singleton con uno Static Factory Method.
public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { ...... }
    public static Elvis getInstance() { return INSTANCE; }
}

Tutte le chiamate al metodo Elvis.getInstance() ritornano lo stesso riferimento all'oggetto. Ecco alcune varianti per la creazione di Singleton con SFM.

Creazione differita

public class Elvis {
    private static Elvis INSTANCE = null;
    private Elvis() {...}
    public static Elvis getInstance() {
        if (INSTANCE == null) INSTANCE = new Elvis();
        return INSTANCE;
    }
    public void leaveTheBuilding() {...}
}

Creazione differita con proprietà

public class Elvis {
    private static Elvis INSTANCE = null;
    private Object owner = null;
    private Elvis() {...}
    public static Elvis getInstance(Object owner) {
        if (INSTANCE == null) {
            INSTANCE = new Elvis();
            this.owner = owner;
        }
        return INSTANCE;
    }
    public void leaveTheBuilding() {...}
}

Item 3: Applicare la non-istanziabilità con un costruttore privato

Piccolo riassunto:

  • Item1: Usare SFM (prospettiva strutturale) permette di avere costruttori multipli con nomi “significanti” per la loro utilità, anche con la stessa signature. Inoltre permette il controllo della creazione delle istanze.
  • Item2: Controllare la creazione in modo tale da avere una singola istanza (prospettiva funzionale), può anche essere basato su SFM (prospettiva strutturale).
  • Item3: Consiste nel controllare la creazione in modo da non avere istanze (prospettiva funzionale).

Reminder:

  • Funzionale: il sistema è visto come una BlackBox investigabile solo in termini di relazioni tra l'input immesso e l'output restituito. Viene testato facendo riferimento alla specifica dei requisiti.
  • Strutturale: il sistema è visto come una WhiteBox, ovvero si ha accesso, invece che alle relazioni di Ingresso/Uscita, al codice sorgente.

Utilizzi dell'item3, data una classe fatta solo con metodi statici, non ci sarà alcun bisogno di creare un'istanza della classe, questo è un primo utilizzo. Esempio la java.lang.Math.

Ecco come si applica la non istanziabilità:

public class UtilityClass {
    // costruttore di default soppresso
    private UtilityClass() { ... } // non è invocabile
}

L'utilizzo di un costruttore privato implica il non subclassing. L'unico modo è rendere la classe astratta e sottoclassarla in modo tale da poter istanziare la sottoclasse. Se la rendiamo final non possiamo subclassare e istanziare.

Item 4: Evitare di creare oggetti duplicati

Anche questo item riguarda il controllo delle istanze al momento della creazione. Meglio riusare oggetti già esistenti ed istanziati anziché crearne di nuovi il cui stato non cambia dopo. Applicabile ad un qualsiasi oggetto immutabile (istanze che sono state inizializzate come per esempio String) utilizzare obj immutabili è l'item13.

NB: Se due oggetti sono immutabili e ad un certo istante sono uguali, allora è inutile distinguerli.

String s = new String("stringette"); // DON'T DO THIS! crea nuova istanza ogni volta
piuttosto:
String s = "stringette"; // DO THIS!

Esempio isBabyBoomer() è un metodo che controlla se il compleanno cade in un certo intervallo dato. Per questo scopo vengono create nuove istanze di Calendar, TimeZone e due di Date ogni volta che viene invocato isBabyBoomer();

public class Person {
    private final Date birthDate;
    public boolean isBabyBoomer() {
        // Unnecessary allocation of expensive object
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
        return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;
    }
}

Soluzione migliore tramite riutilizzo di una sola istanza: Attraverso invocazioni successive, facciamo in modo che i componenti riutilizzati siano condivisi al livello di classe.

  • Per ridurre l'impronta di memoria e il carico di lavoro del garbage collector e mostrare.
  •         class Person {
                private final Date birthDate;
                private static final Date BOOM_START;
                private static final Date BOOM_END;
                static {
                    Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                    gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
                    BOOM_START = gmtCal.getTime();
                    gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
                    BOOM_END = gmtCal.getTime();
                }
                public boolean isBabyBoomer() {
                    return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;
                }
            }
            

Item 5: Eliminare i riferimenti agli oggetti obsoleti

Memory leak rappresenta uno dei problemi di riferimenti in memoria. Ovvero perdita di memoria, perdita di riferimento ad oggetti in memoria ancora presenti e referenziati ma non utilizzabili (quindi non gestiti dal garbage collector).

Esempio di stack implementato sopra ad un array.

Anteprima
Vedrai una selezione di 4 pagine su 14
Appunti Ingegneria del software prof. Enrico Vicario Pag. 1 Appunti Ingegneria del software prof. Enrico Vicario Pag. 2
Anteprima di 4 pagg. su 14.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software prof. Enrico Vicario Pag. 6
Anteprima di 4 pagg. su 14.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software prof. Enrico Vicario Pag. 11
1 su 14
D/illustrazione/soddisfatti o rimborsati
Acquista con carta o PayPal
Scarica i documenti tutte le volte che vuoi
Dettagli
SSD
Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher tommasogiannoni di informazioni apprese con la frequenza delle lezioni di Ingegneria del software e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Firenze o del prof Vicario Enrico.
Appunti correlati Invia appunti e guadagna

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community