Groovy - programação de metaobjetos
A programação de metaobjetos ou MOP pode ser usada para invocar métodos dinamicamente e também criar classes e métodos dinamicamente.
Então o que isso quer dizer? Vamos considerar uma classe chamada Student, que é uma classe vazia sem variáveis de membro ou métodos. Suponha que você tenha que invocar as seguintes instruções nesta classe.
Def myStudent = new Student()
myStudent.Name = ”Joe”;
myStudent.Display()
Agora, na programação de metaobjetos, mesmo que a classe não tenha a variável de membro Nome ou o método Display (), o código acima ainda funcionará.
Como isso pode funcionar? Bem, para que isso funcione, é necessário implementar a interface GroovyInterceptable para se conectar ao processo de execução do Groovy. A seguir estão os métodos disponíveis para esta interface.
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)
}
Portanto, na descrição da interface acima, suponha que se você tivesse que implementar invokeMethod (), ele seria chamado para cada método que existe ou não existe.
Propriedades ausentes
Então, vamos dar uma olhada em um exemplo de como podemos implementar a programação de metaobjetos para propriedades ausentes. As seguintes coisas chaves devem ser observadas sobre o código a seguir.
A classe Student não possui nenhuma variável de membro chamada Nome ou ID definida.
A classe Student implementa a interface GroovyInterceptable.
Existe um parâmetro chamado dynamicProps que será usado para manter o valor das variáveis de membro que são criadas instantaneamente.
Os métodos getproperty e setproperty foram implementados para obter e definir os valores das propriedades da classe em tempo de execução.
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]
}
}
A saída do código a seguir seria -
Joe
1
Métodos ausentes
Então, vamos dar uma olhada em um exemplo de como podemos implementar a programação de metaobjetos para propriedades ausentes. As seguintes coisas importantes devem ser observadas sobre o código a seguir -
A classe Student agora implementa o método invokeMethod, que é chamado independentemente de o método existir ou não.
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"
}
}
A saída do código a seguir deve ser mostrada abaixo. Observe que não há erro de exceção de método ausente, embora o método Display não exista.
Joe
1
Metaclasse
Esta funcionalidade está relacionada à implementação MetaClass. Na implementação padrão, você pode acessar campos sem invocar seus getters e setters. O exemplo a seguir mostra como, usando a função metaClass, podemos alterar o valor das variáveis privadas na 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;
}
}
A saída do código a seguir seria -
Joe
Mark
Método ausente
Groovy apóia o conceito de methodMissing. Este método difere de invokeMethod porque é invocado apenas no caso de falha no envio de um método, quando nenhum método pode ser encontrado para o nome e / ou os argumentos fornecidos. O exemplo a seguir mostra como o métodoMissing pode ser usado.
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"
}
}
A saída do código a seguir seria -
Joe
1
Missing method