Is there a name for this template

I used this template many times in different places, usually next to the plugin.

In some examples, I used it for messaging systems, such as creating subscribers for various types of unrelated messages. I also used it for general integration workflows, each of which needs a context-sensitive form object.

Basically, a template consists of defining an empty token interface for a message or context. Next, define a high-level workflow interface that works with the message / context interface. You can then use the factory to get a specific instance of the workflow, and if necessary, the workflow can also be responsible for parsing its message / context from the general data format.

Then you create an abstract common base workflow, the responsibility of which is only to map the calls to the interface methods that go around the useless token interface, to the calls to abstract methods that accept a specific version of the message / context.

Hope this makes sense. I will give an example code below. I would like to know if this template has a name because I noticed that I used it about 4-5 times. Also, I am just explaining how to explain the pattern, so if anything about my explanation does not make sense, let me know.

The main thing is that you can have several classes with different method signatures that can still be called through a common interface:

Final result

public class ConcreteA : Base<MessageA>
{
    public void Process(MessageA message){...}
    public MessageA Parse(IDictionary data){...}
}

public class ConcreteB : Base<MessageB>
{
    public void Process(MessageB message){...}
    public MessageB Parse(IDictionary data){...}
}

//And both can by called by...
public void Main(){
    var data = GetDataFromIntegrationSource(someContext);
    IWorkflow impl = Factory.GetConcrete(someContext);

    //So in your classes you're able to work with strongly typed parameters,
    //But in the consuming code you still can use a common interface
    //Consuming code never even knows what the strong type is. 
    IMessage msg = impl.Parse(data);
    impl.Process(msg);
}

FULL EXAMPLE

High Level Interfaces

public interface IGenericeMarkerInterface
{
}

public interface IGenericWorkflow
{
    void Process(IGenericeMarkerInterface messageOrContext);

    IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}

An abstract base for mapping concrete methods

public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
    public void Process(IGenericeMarkerInterface messageOrContext)
    {
        Process((T)messageOrContext);      
    }

    public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
    {
        return DoParse(commonDataFormat);
    }

    public abstract void Process(T messageOrContext);
    public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}

Match Attributes

public class MappingAttributeUsedByFactoryAttribute : Attribute
{
    public WorkflowType SomePropertyForMapping { get; set; }
}

public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
    public int ID { get; set; }
    public string Data { get; set; }
}

[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
    public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
    {
        //TODO: process the strongly typed message
    }

    public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
    {
        //TODO: parse the common data into the strongly typed message            
    }
}

Factory

public static class WorkflowFactory
{
    public static IGenericWorkflow Get(WorkflowType workflow) 
    {
        //TODO: find the concrete workflow by inspecting attributes
    }
}

public static class Program
{
    public static void Main(string[] args)
    {
        //this could be driven by a UI or some contextual data
        var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
        var data = GetSomeDictionaryOfData();

        var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);

        workflow.Process(workflow.Parse(data));
    }
}
+3
1

, , :

+1

All Articles