Re: getting things like loggers into the model

Rickard Öberg <[email protected]>
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <[email protected]>
On 2/14/14, 08:24 , Caleb Cushing wrote:
> So I asked this question on StackOverflow and the basic answer I've
> been getting comes down to using an anemic model (or at least that's
> my interpretation of people saying my entities should not have
> business logic)
>
> http://stackoverflow.com/questions/21743823/cdi-injecting-services-into-jpa-managed-entities/21749132
>
> My example uses a Setter, but that's really a side effect of me trying
> to use an exceptionally stupid example so that it's easily understood.
>
> my basic desire is to be able to have access to things like a logger
> in the model, largely for debugging purposes, or to fire events that
> can be then tracked by some external class.
>
> what I'm thinking right now is
>
> Repository {
> @Inject
> Logger
> @Inject
> Event
> ...
> AggregateRoot.wireServices( Logger, Event );
>
> and then passing it through the model
>
> However other idea's are welcome.

So, lately I've been playing with a slightly different pattern. In the 
codebase I'm working on (Neo4j, a database so it's not an app, but same 
idea applies) whenever I need a third party (i.e. not the object itself 
and not the caller) to know what's going on, I've used what I call a 
monitor interface.

Basically, the thing that wants to let others know what's happening 
(either exceptionally or for metrics reasons or whatever) defines an 
internal public interface which is always called Monitor. It has methods 
that take whatever parameters are needed (usually none, but sometimes an 
int or two, and an exception if something went wrong), and always 
returns void. Typed logging methods, you could say.

The constructor then takes a single instance of this, saves it, and uses 
it when needed.

During testing I can mock this, and make assertions on what should 
happen in various scenarios. This is easier than if the object had used 
an injected logger or somesuch. In production, however, the instance 
will pretty much always be a dynamic proxy which when invoked will 
delegate to others that listen to it. Any kind of coupling to logging 
will thus only be in those listeners (so I can easily support any number 
of logging frameworks, or none, if I want to). You get a single place to 
handle error messages (ResourceBundles become easy to use without 
requiring each individual object to know about that stuff). Some 
listeners will be metrics oriented, so have counters that I then expose 
through JMX and also through Graphite/CVS/etc.

Example:
https://github.com/neo4j/neo4j/blob/master/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/TxManager.java

Monitor proxy creator and listener manager:
https://github.com/neo4j/neo4j/blob/master/community/kernel/src/main/java/org/neo4j/kernel/monitoring/Monitors.java

/Rickard



------------------------------------

Yahoo Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/domaindrivendesign/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/domaindrivendesign/join
    (Yahoo! ID required)

<*> To change settings via email:
    [email protected] 
    [email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo Groups is subject to:
    http://info.yahoo.com/legal/us/yahoo/utos/terms/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.