Groovy-meta-object-programming

提供:Dev Guides
移動先:案内検索

Groovy-メタオブジェクトプログラミング

メタオブジェクトプログラミングまたはMOPを使用すると、メソッドを動的に呼び出したり、クラスやメソッドをその場で作成したりできます。

だからこれはどういう意味ですか? Studentと呼ばれるクラスを考えてみましょう。これは、メンバー変数やメソッドのない空のクラスです。 このクラスで次のステートメントを呼び出す必要があるとします。

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

メタオブジェクトプログラミングでは、クラスにメンバ変数NameまたはメソッドDisplay()がなくても、上記のコードは引き続き機能します。

これはどのように機能しますか? これを解決するには、Groovyの実行プロセスにフックするGroovyInterceptableインターフェースを実装する必要があります。 このインターフェイスで使用できるメソッドは次のとおりです。

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

したがって、上記のインターフェースの説明で、invokeMethod()を実装する必要がある場合、存在するか存在しないすべてのメソッドに対して呼び出されると仮定します。

プロパティがありません

では、欠落しているプロパティに対してメタオブジェクトプログラミングを実装する方法の例を見てみましょう。 次のコードについて、次の重要事項に注意する必要があります。

  • クラスStudentには、NameまたはIDという名前のメンバー変数が定義されていません。
  • Studentクラスは、GroovyInterceptableインターフェイスを実装します。
  • その場で作成されるメンバー変数の値を保持するために使用されるdynamicPropsというパラメーターがあります。
  • メソッドgetpropertyおよびsetpropertyは、実行時にクラスのプロパティの値を取得および設定するために実装されています。
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]
   }
}

次のコードの出力は次のようになります-

Joe
1

欠落しているメソッド

では、欠落しているプロパティに対してメタオブジェクトプログラミングを実装する方法の例を見てみましょう。 次のキーについては、次のコードについて注意する必要があります-

  • クラスStudentは、メソッドが存在するかどうかに関係なく呼び出されるinvokeMethodメソッドを実装します。
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"
   }
}

次のコードの出力は次のようになります。 メソッドDisplayが存在しない場合でも、メソッド例外が見つからないというエラーはありません。

Joe
1

メタクラス

この機能は、MetaClassの実装に関連しています。 デフォルトの実装では、ゲッターとセッターを呼び出さずにフィールドにアクセスできます。 次の例は、metaClass関数を使用して、クラス内のプライベート変数の値を変更する方法を示しています。

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

次のコードの出力は次のようになります-

Joe
Mark

メソッドがありません

GroovyはmethodMissingの概念をサポートしています。 このメソッドは、指定された名前または引数、あるいはその両方のメソッドが見つからない場合、メソッドのディスパッチが失敗した場合にのみ呼び出されるという点で、invokeMethodとは異なります。 次の例は、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"
   }
}

次のコードの出力は次のようになります-

Joe
1
Missing method