Groovy - Programación de metaobjetos

La programación de metaobjetos o MOP se puede utilizar para invocar métodos dinámicamente y también crear clases y métodos sobre la marcha.

Entonces, ¿qué significa esto? Consideremos una clase llamada Student, que es una clase vacía sin variables o métodos miembros. Suponga que tuviera que invocar las siguientes declaraciones en esta clase.

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

Ahora, en la programación de metaobjetos, aunque la clase no tenga la variable miembro Name o el método Display (), el código anterior seguirá funcionando.

¿Cómo puede funcionar esto? Bueno, para que esto funcione, uno tiene que implementar la interfaz GroovyInterceptable para conectarse al proceso de ejecución de Groovy. A continuación se muestran los métodos disponibles para esta interfaz.

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) 
}

Entonces, en la descripción de la interfaz anterior, suponga que si tuviera que implementar invokeMethod (), se llamaría para cada método que exista o no.

Propiedades que faltan

Así que veamos un ejemplo de cómo podemos implementar la programación de metaobjetos para las propiedades que faltan. Las siguientes claves deben tenerse en cuenta sobre el siguiente código.

  • La clase Student no tiene definida ninguna variable de miembro denominada Nombre o ID.

  • La clase Student implementa la interfaz GroovyInterceptable.

  • Hay un parámetro llamado dynamicProps que se utilizará para mantener el valor de las variables miembro que se crean sobre la marcha.

  • Los métodos getproperty y setproperty se han implementado para obtener y establecer los valores de las propiedades de la clase en tiempo de ejecución.

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]
   } 
}

La salida del siguiente código sería:

Joe 
1

Métodos que faltan

Así que veamos un ejemplo de cómo podemos implementar la programación de metaobjetos para las propiedades que faltan. Las siguientes claves deben tenerse en cuenta sobre el siguiente código:

  • La clase Student ahora implementa el método invokeMethod que se llama independientemente de si el método existe o no.

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"
   }
}

La salida del siguiente código se mostraría a continuación. Tenga en cuenta que no hay ningún error por falta de excepción de método aunque el método Display no exista.

Joe 
1

Metaclase

Esta funcionalidad está relacionada con la implementación de MetaClass. En la implementación predeterminada, puede acceder a los campos sin invocar sus captadores y definidores. El siguiente ejemplo muestra cómo al usar la función metaClass podemos cambiar el valor de las variables privadas en la clase.

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;
   } 
}

La salida del siguiente código sería:

Joe 
Mark

Falta el método

Groovy apoya el concepto de MethodMissing. Este método difiere de invokeMethod en que solo se invoca en caso de un envío de método fallido, cuando no se puede encontrar ningún método para el nombre dado y / o los argumentos dados. El siguiente ejemplo muestra cómo se puede utilizar el métodoMissing.

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"
   }  
}

La salida del siguiente código sería:

Joe 
1 
Missing method