3

我在很多地方多次使用过这种模式,通常与插件模式一起使用。

我使用它的一些示例方法是用于消息传递系统,例如为各种类型的不相关消息创建订阅者。我还将它用于通用集成工作流程,每个工作流程都需要不同形状的上下文对象。

基本上,该模式包括为消息或上下文定义一个空白标记界面。然后定义一个与消息/上下文接口一起工作的高级工作流接口。然后,您可以使用工厂来获取工作流的具体实例,如果需要,工作流还可以负责从通用数据格式解析其消息/上下文。

接下来,您创建一个抽象的通用基本工作流,其职责是将调用映射到传递无用标记接口的接口方法,调用抽象方法来获取消息/上下文的具体版本。

希望这是有道理的。我将在下面提供一个代码示例。我很想知道这种模式是否有名字,因为我注意到我现在已经使用了大约 4-5 次。另外,我只是在充实如何解释这种模式,所以如果我的解释有什么不合理的地方,也请告诉我。

要点是您可以拥有多个具有不同方法签名的类,这些类仍然可以通过通用接口调用:

最终结果

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);
}

完整示例

高级接口

public interface IGenericeMarkerInterface
{
}

public interface IGenericWorkflow
{
    void Process(IGenericeMarkerInterface messageOrContext);

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

映射到具体方法的抽象基础

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);
}

映射属性

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            
    }
}

工厂

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));
    }
}
4

1 回答 1

1

是的,和你命名的完全一样:Marker interface

于 2014-02-15T16:17:29.423 回答