Avoiding repetitive code for timestamping and updating status

This is some boilerplate I found myself writing on a new abstract class. It seems ripe for refactoring, but I'm not sure the best way to implement it more effectively. Is there a pattern for these sort of time-stamping/status-updating methods?

def create() {
tsCreated = new DateTime()
userCreated = springSecurityService.currentUser
status = RequestStatus.OPEN
}

def accept() {
tsAccepted = new DateTime()
userAccepted = springSecurityService.currentUser
status = RequestStatus.ACCEPTED
}

def send() {
tsSent = new DateTime()
userSent = springSecurityService.currentUser
status = RequestStatus.SENT
}

def complete() {
tsCompleted = new DateTime()
userCompleted = springSecurityService.currentUser
status = RequestStatus.COMPLETED
}

def cancel() {
tsCanceled = new DateTime()
userCanceled = springSecurityService.currentUser
status = RequestStatus.CANCELED
}


No idea about groovy, but it looks like a case for an EnumMap<RequestStatus, Data> with the map storing the (last) corresponding time and user. You need a single method

def action(RequestStatus status) {
map.put(status, new Data(new DateTime(), springSecurityService.currentUser))
this.status = status
}


If you really need 5 methods, you can define them trivially via action.

• Neat! This highlights the value of understanding what the language has already available. Speaking of which, what's the Data type you're using there? It's hard to google due to its common name. – Charles Wood Jun 11 '14 at 16:49
• @CharlesWood You need to write class Data. In the most straightforward way: 2 fields and one all args constructor. – maaartinus Jun 12 '14 at 8:50
• Ah! I think in Groovy this would be implemented with a plain old anonymous Map. E.g., map.put(status, [timestamp: new DateTime(), user: springSecurityService.currentUser]). Thanks! – Charles Wood Jun 12 '14 at 18:34
• @CharlesWood I guess so. As long as it stays in the class, it's OK, otherwise I'd avoid untyped data structures. – maaartinus Jun 13 '14 at 8:49
• Not that I disagree with you, but dynamic typing is pretty fundamental to Groovy. – Charles Wood Jun 13 '14 at 15:15