Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encapsulating a service call within an domain object method

Is this a valid object design ? I have a domain object where i inject a service and call a verify method to update the state of the object and if all goes well send a confirmation message. The code looks like:

class Foo {
  String bar
  Service emailService


  public boolean verify() {
    bar = "foo"
        if(this.save()) {
            emailService.sendConfirmation()
        }
  }
}

Foo.get(1).verify()

Is it acceptable to call the emailService in such a away ? is there a design pattern that i can follow to use for such a situation.

Thank you - Ken

like image 418
ken Avatar asked Sep 01 '10 23:09

ken


1 Answers

There is nothing wrong with calling a service from an entity. There are, however, some problems concerning instantiating these services. If you follow this path, you have to somehow obtain an instance of a service during entity creation which is problematic.

Calling a constructor directly is obviously a bad idea (since it couples the entity to the service implementation).

Jimmy Bogard explained why injecting services into entities is a bad idea.

Instead of it, he suggested using 'double dispatch' (there were some debates if this name is appropriate) pattern to solve this problem. In this approach, a domain method callee provides a service implementation to the domain method. In your case it would look something like that:

class Foo {
  String bar    

  public boolean verify(Service emailService) {
    bar = "foo"
        if(this.save()) {
            emailService.sendConfirmation()
        }
  }
}

Foo.get(1).verify(new Service(...))

The last (but not least) option is to use Domain Events pattern. You can read about it on Udi Dahan's blog. In this approach entities are only responsible for publishing meaningful events which are subscribed by proper handlers. You can read full comparison of all these techniques on my blog.

Hope that helps

like image 75
Szymon Pobiega Avatar answered Oct 30 '22 23:10

Szymon Pobiega