Home > C# > Visitor on steroids

Visitor on steroids

I always worked “domain driven”. I like objects, that’s the truth. It’s like the game Lemmings where you told to that little ones with the green hair what to do. And I like the idea of low coupling, too. So, for me, persistence and domain model was always in different places. In other words, I don’t like my model knowing about persistence.  But I always concerned about the fact that sometimes we have some rules that will use our database (through a repository, dao, whatever) and they are related to an inheritance of our “entities”. It stop worrying me when I meet the visitor/double dispatch patterns, because they let the inheritance to chose what to do,  even when they don’t know what they are doing (?).

Some days ago, a friend of mine told me about his experiences with ActiveRecord an how wonderful it is. I won’t talk about it, I know the pattern but I didn’t use it. I don’t like the idea of the model knowing how to persist and having access to the entire repository BUT for polymorphic rules, it is just simple and I like that (a lot). So, we talked for hours about it, I read some blog posts and decided to try it in the near future (I hope I will post about it in the near future of that near future).

Two days after this long talk, I had to design a solution for a problem that sounds like this: Suppose you have to implement a rules system like outlook’s. I mean, you have rules to apply to every new email. These rules could be applied according the subject, the sender, etc. and they could do every possible transformation: move it to a folder, adding a priority, even changing the subject (the actual problem wasn’t about emails, but I won’t talk about the project I’m working on. Confidencial stuff, you know). And when a rule is created, it could be applied to every past email. So, I have a rule that, at least in the first approach, will be implemented using the database. So, my initial model was something like:

My first thought was “ok, I need a kind of IRuleVisitor…” and then I realized the rules could be… hundred. I mean, that was what the requirement says. So, goodbye Visitor (I won’t have an interface with 100 methods, coupled to every kind of rule. no, no, no!!!). And the ActiveRecord ghost started to whisper. “If I would use ActiveRecord, every db implementation will be on the rule class itself and it will be just fine. How do hay split them here?”. Since I hadn’t any idea of how to solve it, I went to play the guitar for a while. But my head continued working in background.

Next morning I had a pretty nice solution and I want to share it with you (“you”… since it’s my first actual post, I think there won’t be a lot of “you’s” for a long time):

My Rule class have an abstract method void ApplyUsing( IRuleExecutor ruleExecutor). This IRuleExecutor interface has one single method: void Execute<R>( R rule ) where R : Rule.

The magic here is that every rule implement this method in the same way: ruleExecutor.Execute( this ). This remaind me to the visitor pattern, in which every subclass implements the Accept method like visitor.Visit( this ).

The interesting part is the implementation of this IRuleExecutor. It needed a new interface, IRuleImplementation<R> where R : Rule and, in order to find the right implementation for each rule,  it has a reference to the application context (I called it “object factory”), so:

public void Execute<R>( R rule ) where R: Rule {
   objectFactory.Get<IRuleImplementation<R>>().Execute( rule );
}

So, I have one class by rule for persistence and one class by rule implementation. Each class has 2 or 3 lines of code and, since all is generic, it doesn’t need to cast (ok, I know the object factory is doing it a lot, but… it’s another story). I called it “Visitor on steroids”.

Disclaimer: I know it has nothing to do with ActiveRecord, I’m just making conversation (or something like that).

Categories: C# Tags: , ,
  1. Emiliano
    December 4, 2009 at 2:32 am

    Hi!
    Should I write in english too?

    well… first at all, congratulation for the site. I’m happy with this and I’m going to read all of your entries. Entries? Texts? Posts? I dont know…

    Why do you need a visitor?
    At the end… you have parallel inheritance hierarchies and maybe all you need is an aspect that “injects” the dependency

    Maybe you can use a base class for the persistency-layer rule class which uses generics and each implementation for each specific persistency-layer rule can specify which domain-class is related… saving all that stuff!

    Maybe some part of the problem is missing… Or I’m missing something…

  2. Rezlaj
    December 4, 2009 at 11:21 am

    Nice post Ivo! It was time you started a blog already!

    Now, how about using chain of responsibility in this case?

    Saludos!

  3. ivowiblo
    December 7, 2009 at 2:20 pm

    Emiliano:
    That’s ok, but the architecture of the project I’m working on doesn’t allow aspects on domain entities. In fact, there’s a kind of discussion about it, people that like it and people that don’t.

    Rezlaj:
    I don’t know, how about using it? 😛 Tell me more of your idea

  1. No trackbacks yet.

Leave a reply to Rezlaj Cancel reply