2009-10-01

Should I put that logic in my Grails domain class, service class, or a controller?

I don't honestly know. I do have a feel for when this is appropriate and when it isn't. For example I think Anemic Domain Model is a valid anti-point. It completely jibes with how I feel the benefit of an Object Oriented Programming (OOP) system should work... in that I don't think domain classes should be just a representation of data.

The whole point of OOP is to encapsulate data and methods in a modular way keeping logic bundled together with the data it operates on. Let's work on a concrete example... assume this is a domain class in a Grails project.


class Person {
String firstName
String lastName
Date birthDate
}


So far so good. So if I want to figure out a person's age... where do I put that? The class seems like a good place...


class Person {
String firstName
String lastName
Date birthDate

def getAge() {
def now = new Date()
now[Calendar.YEAR] - birthDate[Calendar.YEAR]
}
}


... in fact anything that operates on the domain data in the object seems like it fits well here. If we run generate-all on this class we get a UI that looks like this...


Marking non-persistent services as transient keeps them from getting sent to the database should we need them... for example if I had a "fooService" then I would get this injected in my domain class like so...

class Person {
transient fooService

// ... snip ...
... but I'll not bother with an example just now.

So when does the logic belong in a service or a controller? Well, when it stops being directly driven by the domain model. For example things could get messy if we start injecting security checks into the domain model. I would find that a bit messy to maintain.

Similarly if there was a Person to Person relationship that required some logic that checked states of both objects...


class Person {
Person spouse
//... snip ...
void marry(Person other) {
if(!other.spouse || other.spouse.id == this.id ) {
other.spouse = person
}
else {
throw new Exception("These two cannot wed")
}
}


... while this works it feels a tad clunky because I have to do this bit ...


if(!other.spouse || other.spouse.id == this.id )

... and since we have to somehow modify the other class too and it feels odd to have the this person object modify the other person object.

... but if there was a minister service I could write this...


class MinisterService {
//... snip ...
void marry(Person left, Person right) {
if(!left.spouse && !right.spouse) {
left.spouse = right
right.spouse = left
}
else {
throw new Exception("These two cannot wed")
}
}
// ... snip ...
}


... and this feels a tad better since the Person class no longer needs to carry around the knowledge of all the possible marriage rules that a lawyer might enact. This also models real life better since people visit ministers, justices, or captains to get married in real life... and we cleanly avoid the issue of people modifying each other.

There's other rules that I could probably explain if I was more articulate. Has anyone else thought about this? What tweaks would you put on these ideas? How would you express this rule?

Note: this is a quick reply to this tweet.

2009-09-08

A Programmer's Isogloss

One of my coworkers has a degree in linguistics and this idea comes from talking with her about language and isolation. Call it my you should really go to that conference rant if you like. The topic of conversation give me a stark realization that I think anyone that is responsible for the care an feeding of programmers should be cautious of.

Naturally, computer programmers use programming languages and the more complex the language and free form it is the more likely it is to have dialect, idiom, and isogloss just like natural languages.

In particular if a speaker or group of speakers live in isolation long enough they will develop their own little quirky habits. These quirks start off as innocent inside jokes which include conventions that we recognize in API. Given time the isolated group can start to invent new idioms which approach an unintelligible complexity to an outsider. The divisions between various frameworks that share Java as a base language and their definitions of terms is a good example.

So how do you break this cycle of main languages fragmenting and breaking up into new languages? You go out and regularly talk to others about your code, your architecture, and you get a feel for how others say words or convey meanings. You make your community of language larger. Every company needs to get its programmers out there and talking to other developers. One of the best ways is through conferences.

The benefits will be that your corporate architecture will stay closer to the wider world's interpretation of the language and idioms you use (think: style, practice, and API). Your developer's will be more creative and valuable as they benefit from the exchange of ideas. And you will know that you have a pool of similarly talented consultants and developers to seek out when you need them.

Other good ways to let your programmers get out there and learn more is to encourage the use of social networking in responsible and applicable ways. I used this recently to help think about const versus final in our code base.

Another idea I've been toying with is to have at least one small company backed Open Source project that your people are encouraged to contribute to that you can also use for getting outside feedback and perhaps to recruit new people into your company from. This is a novel idea but I think with some sensible boundaries it can pay off even for closed source companies.

Those are just some of my thoughts on the topic. But essentially you want to avoid putting your programmers in the position that all they ever do is "talk" (via programming) to the computer and themselves. You need to talk with other people whether in code or English to keep your skills sharp and to avoid drifting off into your own strange dialect. The dangers to both the company and the employee of drifting off into your own little world are profound. It can mean obsolescence for both parties and that doesn't help anyone ... except maybe your competitors.

2009-09-05

Configuration Best Practice

So rattling around in my head is this idea of configuration. When should you configure? What should you configure? How much should you configure?

As a rule of thumb I need to perform a software task in three relevant contexts to spot the important patterns for the system. That is to say I need three unique implementations of a system to spot how to generically implement a framework around the problem domain. The same is true for configuration.

Until I see three distinct scenarios where a system will be used I usually can't rightly discern what is going to need to be configurable and what isn't. I can usually make a good guess as to what will be needed by the time I'm working on two implementations ... but it really takes the third one for things to gel.

So if I were to number from best to worst case for configurations... I would put them in this order:

  1. configuration by convention (as we see in Grails)

  2. dynamic configuration by environment

  3. explicit configuration by administrator



Once you figure out that part of a system is going to actually need to flex then you should refactor for just enough modularity to reach the changes you need see. When doing this work the best thing to do is to make your system self configure by convention. This way we provide the necessary configuration without increasing the load on the end developer or administrator.

Next best we can do configuration by picking up things from our environment and working out the values we might otherwise need configured. This allows the administrator of our application to merely move the application code base to the correct place in the "cloud" or the correct server.

The last thing we want is for the administrator to have to open a dialog and enter data about the environment for your system to use at run-time. This can be an error prone process and it is possible that the environmental factors will change forcing the administrator to always be conscious of additional variables in the system.

In the perfect world our software systems would have enough intelligence to ask the environment for what they need and the environment would be intelligent enough to compute those dependencies as they occurred.

Of course the real world is a long way from perfect.

2009-09-02

Working on a new Audit plugin release

I'm working on a new release for the Grails Audit Logging Plugin that deals with issues some people were having with transactional databases.

I'd like to test this on multiple databases and with multiple configurations. So I'm putting the word out that I'd like some help with testing this. I don't have more than four databases to test on so I'd like some help.

If you can help out let me know. Contact me through this blog, twitter, or carrier pigeon. Thanks.

2009-08-21

Groovy Automatic type casting tricks...

I've been working on a Domain Specific Language. We wanted to hide the fact that you were passing string parameters to methods... so you could say things like:


something 'foo'
something foo


...and they would be equivalent. As the project progressed I needed to make calls like these...

something 'foo.bar'
something foo.bar

... again we want the two calls to be equivalent. But then I needed to reference the implicit tree of properties created by calling 'foo.bar' and 'foo.bar.baz' when I was interpreting these statements. So I needed to start tracking the symbols.

So my text-book meta-programming trick ...

def propertyMissing(String name) {
return name
}

... stopped working since foo.bar would result in a property missing on the String object. I could do some meta-programming on the String object but I also wanted to preserve the tree relationship for other work later. So with that in mind I wrote a class to wrap the symbols.

But there's a problem with that. If I introduce this new class... there are many places I just want the symbol like 'foo.bar.baz' and not the complex relationship. And by this point in the project I've written a lot of code to deal with things as strings.

Wouldn't it be great if I could ignore the complex nature of the object most of the time... but pick out the complex bits when I wanted them? To that end I created this class ComplexSymbol to do that work. I empowered it to know how to turn itself into a string silently in all sorts of situations.

So I wrote some tests to express what I wanted to see...

assert symbol == "foo"
assert symbol.bar == "foo.bar"
assert symbol.baz.bing == "foo.baz.bing"
assert symbol.baz.blat == "foo.baz.blat"
assert symbol.bar.blat == "foo.bar.blat"

... and I wanted to see the class of Symbol silently swap in for String whenever the method that was being called was expecting a string and not a complex symbol.

Take a look at the class I came up with to do this job...

public class ComplexSymbol {
ComplexSymbol parent
String symbol
Map symbols = [:]
ComplexSymbol(String str) { symbol = new String(str) }
ComplexSymbol(String str, ComplexSymbol other) {
symbol = new String(str);
parent = other
}
String toString() {
if(parent) {
return parent.toString() + "." + this.symbol
}
return symbol
}
def propertyMissing(String sym) {
if(symbols.containsKey(sym)) {
return symbols[sym]
}
def obj = new ComplexSymbol(sym,this)
symbols[sym] = obj
return obj
}
def asType(Class clazz) {
Object obj = null
switch(clazz) {
case java.lang.String:
obj = this.toString()
break
}
return obj
}

boolean equals(Object other) {
this.toString().equals(other.toString())
}

}


I've got lots of explicit typing in places to document the use of the class since I expect this class to show up in Java and Groovy code. The typing is really for documentation as it should be.

In the class where I want ComplexSymbol to stand in for naked strings I now do this:

def propertyMissing(String name) {
return new ComplexSymbol(name)
}

... which sets things up nicely so that the following works ...

someMethod foo.bar.baz

... and someMethod should get called with a string "foo.bar.baz" but before we get to that point I need to sanity check things.

Now to test the class with some methods... I just dumped the text for the above class into a file called symbols.groovy and stuck these methods at the end of the script so I could call them.


boolean stringify(String str) {
return str != null
}


This one should just see if it gets a string and I'll pass my ComplexSymbol to it and see if it gets the string.


boolean stringify(ComplexSymbol sym) {
return stringify(sym as String)
}


This method explicitly takes the complex symbol and uses the asType explict cast on it. This should show that the cast works.


boolean implicitlyCast(String sym) {
return sym != null
}


The implicit cast is my holy grail. If I can get the type system to see String whenever it asks for a String or the full ComplexSymbol type when it can handle that then I've got the whole enchilada.



/** Here's the tests again **/

def symbol = new ComplexSymbol("foo")
assert symbol == "foo"
assert symbol.bar == "foo.bar"
assert symbol.baz.bing == "foo.baz.bing"
assert symbol.baz.blat == "foo.baz.blat"
assert symbol.bar.blat == "foo.bar.blat"
assert stringify(symbol)

println "-" * 40
println symbol
println "-" * 40
println symbol as String
println "-" * 40
println symbol.toString()
println "-" * 40

assert implicitlyCast(symbol)


... command line output of this ...


$ groovy symbol.groovy
----------------------------------------
foo
----------------------------------------
foo
----------------------------------------
foo
----------------------------------------
Caught: groovy.lang.MissingMethodException: No signature of method: symbol.implicitlyCast() is applicable for argument types: (ComplexSymbol) values: [foo]
at symbol.run(symbol.groovy:71)


Notice that the last assert (my holy grail) fails. What I have is a very nice taco if not the whole enchilada.

Methods like print and println are going to implicitly handle the ComplexSymbol properly since they'll call the toString() on the object. And for methods that don't call ".toString()" we can either call it for them or explicitly cast to a String just before calling them.

All and all, it's a nice compromise with static and dynamic typing that allows me to use this class in plain Java code or in Groovy code very easily.

If someone has some thoughts on how I can get assert implicitlyCast(symbol) to work I'd love to hear them. With out it though, it's simple enough to spot the problem in a test case and put "as String" in the call like so...


assert implicitlyCast(symbol as String)


... and as I have incorporated this class into my work I've found points where I don't want the implicit cast to work all the time! I actually want to go into ComplexSymbol and ask for the symbol property directly. It turns out I actually need to hold the leaf nodes by their leaf node value sometimes and having them automatically resolve to their whole name would cause problems.

So in the end I'm glad the implicitlyCast test doesn't work the way I imagined.

2009-08-05

Grails in a J2EE world - RMI @ GroovyMag

In this month's GroovyMag I talk about using Grails code from a J2EE application using RMI. It's some practical work with the remoting plugin. Thanks again to Craig Wickesser for editing.

This is my last installment in the Grails in a J2EE world series. I had specifically been inspired to write these articles by several developers I had met over the last year that are interested in introducing Grails but who are also maintaining infrastructures that are built on EJB2. Yes, that's right... EJB2. I did not have time or space to cover every aspect that I wanted to, but, I hope that those of you that are in that particular boat and are interested in Grails can use these articles as a starting point for bringing Grails into your organizations.

Please head over to GroovyMag and check out the article. Feel free to give me some feedback below about the article. Together we can help cover this topic area better.

Thanks.

2009-06-04

Grails in a J2EE world - The Database @ GroovyMag

In this month's GroovyMag I talk about sharing a database between a J2EE application and a Grails application that is using GORM. If you haven't spent anytime working with concurrency in database applications you will really want to check this out. If you have a Container Managed Persistence (CMP) application that you are working with and you have a green-light on using Grails you might consider moving directly from EJB2 to GORM in a phased manner sharing parts of the database on the way.

Thanks again to Craig Wickesser for editing.

Please head over to GroovyMag and check out the article and give me some feedback.

EDIT
I'll also be giving out 5 free PDF copies of GroovyMag to the first five people who can Direct Message me on Twitter the answer to this riddle: What do you call an organized body of related information?

EDIT
That went fast! Congrats to @vintagedance, @evanbooth, @paulk_asert, @iansari, and @unixfudotnet

@unixfudotnet has offered his coupon up to the first person who wants it. Congrats to @dferrand.

Our answer? A database