Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Design pattern, or maybe antipattern? The whole idea is to NOT runtime-cast the IDispatch object. I have a method which should handle different IDispatch, but they must be privilege to the concrete type. I could put the functionality from Handle(...) directly in each Dispatch type, but that would violate SRP, not to mention that each Dispatch type should not even be aware of this functionalitys existence (encapsulation).

Of course, this could also be done by checking the type of IDispatch and casting to the concrete type. Even done 'pretty', for example by storing the methods in a Dictionary<Type, Action<IDispatch>> and then cast in each method this is not very beautiful. :p

What would you call this design pattern, and would you call it an antipattern? That is, is there some better solution to such a situation?

public interface IDispatch //or something
{
    void Dispatch(IDispatchee dispatchee);
}

public interface IDispatchee
{
    void Handle(ConcreteDispatch1 dispatch);
    void Handle(ConcreteDispatch2 dispatch);
    void Handle(.....);
}

public class OneTypeOfDispatchee
{
   void Handle(ConcreteDispatch1 dispatch)
   {
        //At this point, we have managed to make ConcreteDispatch1 statically typed
        //as opposed to typed to IDispatch.
   }

   void Handle(ConcreteDispatch2 dispatch)
   {
       //Same as above.
   }
}

UPDATE

I'll try to explain more about what I'm trying to achieve.

I need to know the concrete type of IDispatch in order to act upon it. This might seem like an antipattern in and of itself, but IDispatch mainly contains entity data, and each IDispatch type of course represents different "types" of data. What I am now trying to build is a peripheral component which IDispatch should not be aware of (if I put all such functionality in IDispatch, it would grow very large, very soon).

I still would like to avoid casting IDispatch to it's concrete type, or atleast I think it is worthwhile to atleast try to find a better solution.

For example, one OTHER solution than the proposed one above, but which uses casting, is this:

class Dispatchee
{
    private Dictionary<Type, Action<IDispatch>> dispatchActions = new Dictionary<Type, Action<IDispatch>() { {typeof(ConcreteDispatch1), DoFunctionalityType1 }  };



    public void DoFunctionality(Model model)
    {
        IDispatch disp = model.Dispatch; //fake names people!
        dispatchActions[disp.GetType()](disp);
    }

    private static void DoFunctionalityType1(IDispatch dispatch)
    {
        ConcreteDispatch1 concrete = (ConcreteDispatch1)dispatch; //would like to avoid this
    }
}
share|improve this question
I don't understand what your question is. Do you want a code review here? – Oded Dec 18 '11 at 10:37
@Oded I'm sorry, see my edit. Edited the question. :) The gist of the matter is: Is this a good, bad or stupid way to achieve this? – Max Dec 18 '11 at 10:39
Achieve what exactly? Please explain the problem that you are trying to solve (regardless of casting). – Oded Dec 18 '11 at 10:44
@Oded There, tried to update with some more info. – Max Dec 18 '11 at 10:55
What you basically want are strategy patterns for the dispatches instantiated by a factory. – Falcon Dec 18 '11 at 10:58
show 1 more comment

1 Answer

I'm not totally sure I understand what you're asking, but it looks like you're trying to achieve multiple dispatch. The classic OO approach is to use the visitor pattern, but there are a number of other options with various trade-offs (type checking as you've already mentioned, reflection, using the dynamic keyword if you're using C#4, etc).

Here's a rundown of the various techniques available together with some performance numbers against them.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.