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/