Q: MOP, aspects, setter methods

View: New views
7 Messages — Rating Filter:   Alert me  

Q: MOP, aspects, setter methods

by grkuntzmd :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I am a Groovy-Newbie and this is a theoretical question

In a project I am working on, we have POJOs with setters of the following form:

// Java Code
public class Person {
  private String name;

  // Set the name value only if it changes, then mark the POJO dirty
  public void setName(String name) {
    if ((name == null) ? this.name != null : !name.equals(this.name)) {
      this.name= name;
      this.dirty = true;
    }
  }
}

Without arguing the philosophy of this approach, is it possible to use MOP in Groovy to automatically "inject" the equality checks and dirty flag setting (ala aspects)? As it stands, each of these setters needs unit testing because it contains "logic" code (as in Dierk König's interview on unit testing with Sven Haiges in the Grails podcast series). If the boilerplate setter code could be injected, these methods would not each need separate units tests.

G. Ralph Kuntz, MD

Re: Q: MOP, aspects, setter methods

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

grkuntzmd schrieb:

> I am a Groovy-Newbie and this is a theoretical question
>
> In a project I am working on, we have POJOs with setters of the
> following form:
>
> // Java Code
> public class Person {
>   private String name;
>
>   // Set the name value only if it changes, then mark the POJO dirty
>   public void setName(String name) {
>     if ((name == null) ? this.name != null : !name.equals(this.name)) {
>       this.name= name;
>       this.dirty = true;
>     }
>   }
> }
>
> Without arguing the philosophy of this approach, is it possible to use
> MOP in Groovy to automatically "inject" the equality checks and dirty
> flag setting (ala aspects)? As it stands, each of these setters needs
> unit testing because it contains "logic" code (as in Dierk König's
> interview on unit testing with Sven Haiges in the Grails podcast
> series). If the boilerplate setter code could be injected, these methods
> would not each need separate units tests.

If you add/change/replace a setter using MOP, then Java still won't see
that change. That means if Person#setName is called from Java, then it
will always be the old method... which implies that there has to be an
old method too,

Now if you write that class in Groovy, then there is the option to hook
into the compilation process. For example you could use our new AST
tranformations to annotate the properties to generate that code for you.
Of course such a setter is callable from Java too then.

But your motivation should not be to safe unit tests, it should be to
safe code duplication. Also the code above could be put in a helper:

> public class Person {
>   private String name;
>
>   // Set the name value only if it changes, then mark the POJO dirty
>   public void setName(String name) {
>     PropertyHelper.dirtySet("name",this,name)
>   }
> }
>
> class PropertyHelper {
>   static void dirtySet(String name, instance, value) {
>     if (value == instance.@"$name") return
>     instance.@"$name" = value
>     instance.@dirty = true
>   }
> }

Person can be Java or Groovy, PropertyHelper would be in Groovy and can
be tested on its own. (note: == is in Groovy different from Java)

bye blackdrag


--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Q: MOP, aspects, setter methods

by grkuntzmd :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks.

I was planning on calling these POGOs from Groovy.

I was NOT trying to save on writing unit tests. I simply feel that less code that needs to be tested is less code that tests can miss and less tests that need to be maintained if the code changes or the pattern changes.

The setters that we use are currently as described above, but if someone comes up with some new piece to the setter, then all of the tests will have to be updated. If this code can be injected, then only the injection process needs to be changed and its tests updated -- less chance of missing something.

I wholeheartly agree that avoiding code duplication is the real goal (DRY).
G. Ralph Kuntz, MD

Re: Q: MOP, aspects, setter methods

by grkuntzmd :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The Groovy compilation process inserts setter methods into GroovyBeans automatically if they have not been previously defined.

Is it possible to "intercept" this process and insert my modified code?
G. Ralph Kuntz, MD

Re: Q: MOP, aspects, setter methods

by Jochen Theodorou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

grkuntzmd schrieb:
> The Groovy compilation process inserts setter methods into GroovyBeans
> automatically if they have not been previously defined.
>
> Is it possible to "intercept" this process and insert my modified code?

just add/replace the methods on the classNode with MethodNode. I suggest
adding them, then the automatically generated getter and setter won't be
added unless you are in the wrong compilation phase.. Therefor I suggest
to use the most early phase possible... see my blog post for details
about the phases.

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Re: Q: MOP, aspects, setter methods

by grkuntzmd :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

My thoughts on this aren't very clear yet (there is a lot of fog between my ears :-)), but ...

I am wondering if I could an AOP system like Google-Guice to wrap the automatically created setters in code that checks for equality before the assignment and sets the dirty flags after, perhaps by creating a new setter and using Object.set() to intercept the call.

I don't know enough Groovy yet...

Must keep reading.

BTW, I am working on a fat-client application, not a webapp, so I don't think Spring is appropriate.
G. Ralph Kuntz, MD

Re: Q: MOP, aspects, setter methods

by grkuntzmd :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I just tried this and it worked:
class Parent {
  void setProperty(String name, value) {
    println "Setting $name to $value"
    this.@"$name" = value
  }
}

class Child extends Parent {
  def field
}

def c = new Child()
c.field = 4
assert c.field == 4
It printed "Setting field to 4". This might just solve my problem.
G. Ralph Kuntz, MD