Visualizzazione post con etichetta design oo. Mostra tutti i post
Visualizzazione post con etichetta design oo. Mostra tutti i post

lunedì 9 aprile 2012

Riflettiamo con la Java Reflection

L'idea di questo post nasce da un test preselezione che ho fatto per un'azienda inglese. Dato un pezzo di codice veniva chiesto quale caratteristica del linguaggio Java era utilizzata. Si trattava della reflection.

La reflection è quella caratteristica del linguaggio Java che permette ad un programma  in esecuzione di accedere a proprietà interne del programma stesso. Tutto ciò ovviamente in contro tendenza con il paradigma orientato agli oggetti. Ad esempio con questa caratteristica è possibile per un classe Java ottenere e accedere al nome di tutti i suoi metodi e attributi ed eventualmente mostrarli.

Perché la reflection?

La violazione del principio di incapsulamento dei linguaggi object oriented può essere pericoloso ma se trattato con le giuste accortezze diventa uno strumento potentissimo. In particolare può essere utile nei framework e in casi in cui si necessità di un forte riutilizzo di codice. Consideriamo ora un esempio di codice Java (fonte sito ufficiale della Oracle):


   import java.lang.reflect.*;
 
   public class DumpMethods {
      public static void main(String args[])
      {
         try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
            System.out.println(m[i].toString());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


Per usare la reflection occore effettuare l'import del package java.lang.reflect.Ora richiamando la classe DumpMethods e passando come input la stringa "java.util.Stack" l'output che otteniamo è il seguente:


 public java.lang.Object java.util.Stack.push(
    java.lang.Object)
   public synchronized 
     java.lang.Object java.util.Stack.pop()
   public synchronized
      java.lang.Object java.util.Stack.peek()
   public boolean java.util.Stack.empty()
   public synchronized 
     int java.util.Stack.search(java.lang.Object)



otteniamo quindi l'elenco dei metodi della classe Stack compreso di parametri e il tipo restituito da ogni metodo.

Un ottimo esempio di come sia utile la reflection è nella conversioni di documenti XML in oggetti Java (più facilmente manipolabili all'interno di un applicazione scritta in linguaggio Java). Trovate un ottimo esempio di codice qui.

Infine per una illustrazione completa dei diversi usi della reflection date anche un'occhiata qui.

giovedì 26 gennaio 2012

Perché le interfacce?

Molti si saranno chiesti a cosa servono e se sono realmente utili le interfacce software. Cercheremo di spiegarlo brevemente in questo post.

Un'interfaccia altro non è che una porzione di software che permette di interagire con le risorse hardware (memoria, CPU e cosi via) che si trovano ai livelli sottostanti. L'accesso a queste risorse se lasciato libero e indiscriminato può portare a diversi incovenienti. Per questo si può permettere l'accesso a tali risorse solo attraverso precisi entry point, ad esempio le interfacce.

Ma cosa è un'interfaccia nel campo della programmazione ad oggetti? Altro non è che una classe che non contiene dati, quindi di tipo astratto, e può contenere quindi solo metodi d'istanza astratti ( non può contenere né costruttori, né variabili di istanza, né metodi statici ecc.). Tuttavia una classe può implementare più interfacce. Una volta che una classe implementa un'interfaccia, il compilatore sà che un'istanza della classe conterrà lo specifico insieme di metodi. Per spiegare meglio cosa sia un'interfaccia usiamo un'analogia: un interfaccia seriale su un computer definisce un insieme di pin assegnati e il controlo dei segnali che saranno usati; il dispositivo può essere usato per differenti task: mouse, modem, ecc. e questi saranno tutti controllati attraverso lo stesso meccanismo di istruzioni digitali. Per cosa può essere utile un'interfaccia? Se una classe ha bisogno di due differenti insiemi di metodi cosi che il suo comportamente sia  quello di due cose differenti, può ereditare un insieme dalla classe A e usare un'interfaccia B per specificare l'altro!

mercoledì 16 novembre 2011

Interview question: SOLID

Questo è il primo di una lunga serie di post dove parleremo di possibili domande a cui un informatico potrebbe andare incontro.

  • Cos'è SOLID?
SOLID sta per Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion. Il termine è stato introdotto per la prima volta da Robert C. Martin agli inizi dell'anno 2000 per indicare un nuovo principio di programmazione e design object-oriented. Quando è applicato il principio permette di avere un sistema facile da manutenere e da estendere col tempo. Andiamo ad analizzare ogni singolo concetto di questo nuovo principio.

  • Single responsibility principle (SRP)
Ogni oggetto dovrebbe avere un sola singola responsabilità. In pratica ogni classe dovrebbe concentrarsi sul fare una sola cosa.

  • Open/closed principle (OCP)
Le entità software dovrebbero essere aperte per l'estensioni ma chiuse per le modifiche. Supponiamo di avere la classe OrderValidation con il metodo Validate (Order order) che contiene tutte le regole per validare un'ordine. Se tali regole cambiano siamo costretti a modificare la classe violando il principio OCP. Se avessimo invece l'oggetto IValidationRule contenente tutte le regole, allora potremmo basare il metodo Validate su questo oggetto e nel caso di cambio di regole basterà creare un nuovo IValidationRule e passarlo all'istanza di OrderValidation al run time.

  • Liskov substitution principle (LSP)
Gli oggetti in un programma dovrebbe essere rimpiazzati con instanze del loro sottotipo senza alterare la correttezza del programma. In pratica le sottoclassi dovrebbero comportarsi correttamente quando usate al posto delle loro classi base.


  • Interface segregation principle (ISP)
Diverse interfacce client specifiche sono meglio di una interfaccia con scopo generale. In pratica mantenere le interfacce piccole e coese.



  • Dependency inversion principle (DIP)
Dipendere dall'astrazione, non dipendere dalle concrezioni. Il metodo di Dependency injection è un modo per seguire questo principio. Tale metodo è un design pattern per la programmazione orientata agli oggetti per cui una classe o un sistema non è responsabile circa l'inizializzazione delle proprie dipendenze. Per maggiore informazioni dare un'occhiata su questo blog.



Per maggiori approfondimenti consultare il seguente link.