Groovy - programowanie obiektów meta

Programowanie obiektów meta lub MOP może być używane do dynamicznego wywoływania metod, a także do tworzenia klas i metod w locie.

Więc co to oznacza? Rozważmy klasę o nazwie Student, która jest rodzajem pustej klasy bez zmiennych składowych ani metod. Załóżmy, że musiałbyś wywołać następujące instrukcje na tej klasie.

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

Teraz w programowaniu meta obiektowym, mimo że klasa nie ma zmiennej składowej Name ani metody Display (), powyższy kod będzie nadal działał.

Jak to działa? Cóż, aby to zadziałało, należy zaimplementować interfejs GroovyInterceptable, aby podłączyć się do procesu wykonywania Groovy. Poniżej przedstawiono metody dostępne dla tego interfejsu.

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

Więc w powyższym opisie interfejsu załóżmy, że gdybyś musiał zaimplementować metodę invokeMethod (), byłaby ona wywoływana dla każdej metody, która istnieje lub nie istnieje.

Brakujące właściwości

Spójrzmy więc na przykład, jak możemy zaimplementować programowanie meta obiektów dla brakujących właściwości. Następujące klucze należy zwrócić uwagę na poniższy kod.

  • Klasa Student nie ma zdefiniowanej zmiennej składowej o nazwie Nazwa lub ID.

  • Klasa Student implementuje interfejs GroovyInterceptable.

  • Istnieje parametr o nazwie dynamicProps, który będzie używany do przechowywania wartości zmiennych składowych tworzonych w locie.

  • Metody getproperty i setproperty zostały zaimplementowane w celu pobierania i ustawiania wartości właściwości klasy w czasie wykonywania.

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

Wynik następującego kodu byłby -

Joe 
1

Brakujące metody

Spójrzmy więc na przykład, jak możemy zaimplementować programowanie meta obiektów dla brakujących właściwości. Następujące klucze należy zwrócić uwagę na następujący kod -

  • Klasa Student implementuje teraz metodę invokeMethod, która jest wywoływana niezależnie od tego, czy metoda istnieje, czy nie.

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

Wynik poniższego kodu zostałby pokazany poniżej. Należy zauważyć, że nie ma błędu polegającego na braku wyjątku metody, mimo że metoda Display nie istnieje.

Joe 
1

Metaclass

Ta funkcja jest powiązana z implementacją MetaClass. W domyślnej implementacji można uzyskać dostęp do pól bez wywoływania ich metod pobierających i ustawiających. Poniższy przykład pokazuje, jak za pomocą funkcji metaClass możemy zmienić wartość prywatnych zmiennych w klasie.

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

Wynik następującego kodu byłby -

Joe 
Mark

Brak metody

Groovy wspiera koncepcję methodMissing. Ta metoda różni się od invokeMethod tym, że jest wywoływana tylko w przypadku nieudanego wysłania metody, gdy nie można znaleźć metody dla podanej nazwy i / lub podanych argumentów. Poniższy przykład pokazuje, jak można użyć 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"
   }  
}

Wynik następującego kodu byłby -

Joe 
1 
Missing method