Groovy - Programmazione di meta oggetti

La programmazione di meta oggetti o MOP può essere utilizzata per invocare metodi dinamicamente e anche creare classi e metodi al volo.

Che cosa significa questo? Consideriamo una classe chiamata Student, che è una specie di classe vuota senza variabili o metodi membri. Supponi di dover invocare le seguenti istruzioni su questa classe.

Def myStudent = new Student() 
myStudent.Name = ”Joe”; 
myStudent.Display()

Ora nella programmazione dei meta oggetti, anche se la classe non ha la variabile membro Nome o il metodo Display (), il codice precedente funzionerà comunque.

Come può funzionare? Bene, perché questo funzioni, è necessario implementare l'interfaccia GroovyInterceptable per agganciarsi al processo di esecuzione di Groovy. Di seguito sono riportati i metodi disponibili per questa interfaccia.

Public interface GroovyInterceptable { 
   Public object invokeMethod(String methodName, Object args) 
   Public object getproperty(String propertyName) 
   Public object setProperty(String propertyName, Object newValue) 
   Public MetaClass getMetaClass() 
   Public void setMetaClass(MetaClass metaClass) 
}

Quindi, nella descrizione dell'interfaccia sopra, supponiamo che se dovessi implementare invokeMethod (), sarebbe chiamato per ogni metodo che esiste o non esiste.

Proprietà mancanti

Quindi diamo un'occhiata a un esempio di come possiamo implementare la programmazione di meta oggetti per le proprietà mancanti. Le seguenti cose chiave dovrebbero essere annotate sul codice seguente.

  • La classe Studente non ha una variabile membro denominata Nome o ID definito.

  • La classe Student implementa l'interfaccia GroovyInterceptable.

  • C'è un parametro chiamato dynamicProps che verrà usato per contenere il valore delle variabili membro che vengono create al volo.

  • I metodi getproperty e setproperty sono stati implementati per ottenere e impostare i valori delle proprietà della classe in fase di esecuzione.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
   }
}

class Student implements GroovyInterceptable { 
   protected dynamicProps=[:]
	
   void setProperty(String pName,val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   } 
}

L'output del codice seguente sarebbe:

Joe 
1

Metodi mancanti

Quindi diamo un'occhiata a un esempio di come possiamo implementare la programmazione di meta oggetti per le proprietà mancanti. Le seguenti cose chiave dovrebbero essere annotate sul seguente codice:

  • La classe Student ora implementa il metodo invokeMethod che viene chiamato indipendentemente dal fatto che il metodo esista o meno.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
}
 
class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   } 
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def invokeMethod(String name, Object args) {
      return "called invokeMethod $name $args"
   }
}

L'output del codice seguente dovrebbe essere mostrato di seguito. Si noti che non vi è alcun errore di eccezione del metodo mancante anche se il metodo Display non esiste.

Joe 
1

Metaclasse

Questa funzionalità è correlata all'implementazione di MetaClass. Nell'implementazione predefinita puoi accedere ai campi senza richiamare i loro getter e setter. L'esempio seguente mostra come utilizzando la funzione metaClass siamo in grado di modificare il valore delle variabili private nella classe.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      println mst.getName()
      mst.metaClass.setAttribute(mst, 'name', 'Mark')
      println mst.getName()
   } 
} 

class Student {
   private String name = "Joe";
	
   public String getName() {
      return this.name;
   } 
}

L'output del codice seguente sarebbe:

Joe 
Mark

Metodo mancante

Groovy supporta il concetto di methodMissing. Questo metodo differisce da invokeMethod in quanto viene richiamato solo in caso di invio di un metodo non riuscito, quando non è possibile trovare alcun metodo per il nome e / o gli argomenti forniti. L'esempio seguente mostra come utilizzare methodMissing.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
} 

class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def methodMissing(String name, def args) {         
      println "Missing method"
   }  
}

L'output del codice seguente sarebbe:

Joe 
1 
Missing method