มีชื่อสำหรับรูปแบบนี้หรือไม่

ฉันเคยใช้รูปแบบนี้หลายครั้งในหลายๆ ที่ โดยปกติจะใช้ร่วมกับรูปแบบปลั๊กอิน

ตัวอย่างบางวิธีที่ฉันใช้กับระบบการรับส่งข้อความ เช่น การสร้างผู้สมัครรับข้อความประเภทต่างๆ ที่ไม่เกี่ยวข้อง ฉันยังใช้มันสำหรับเวิร์กโฟลว์การรวมทั่วไปที่แต่ละรายการต้องการออบเจ็กต์บริบทที่มีรูปแบบแตกต่างกัน

โดยพื้นฐานแล้วรูปแบบประกอบด้วยการกำหนดอินเทอร์เฟซเครื่องหมายว่างสำหรับข้อความหรือบริบท จากนั้นกำหนดอินเทอร์เฟซเวิร์กโฟลว์ระดับสูงที่ทำงานกับอินเทอร์เฟซข้อความ/บริบท จากนั้นคุณสามารถใช้โรงงานเพื่อรับตัวอย่างเวิร์กโฟลว์ที่เป็นรูปธรรม และหากจำเป็น เวิร์กโฟลว์ยังสามารถรับผิดชอบในการแยกวิเคราะห์ข้อความ / บริบทจากรูปแบบข้อมูลทั่วไป

ถัดไป คุณสร้างเวิร์กโฟลว์พื้นฐานทั่วไปเชิงนามธรรมซึ่งมีหน้าที่เพียงแมปการเรียกไปยังวิธีอินเทอร์เฟซ ซึ่งส่งผ่านอินเทอร์เฟซตัวทำเครื่องหมายที่ไม่มีประโยชน์ ไปเป็นการเรียกไปยังวิธีนามธรรมที่ใช้ข้อความ/บริบทเวอร์ชันที่เป็นรูปธรรม

หวังว่ามันจะสมเหตุสมผล ฉันจะให้ตัวอย่างรหัสด้านล่าง อยากทราบว่ารูปแบบนี้มีชื่อหรือเปล่า เพราะสังเกตว่าใช้ไปประมาณ 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));
    }
}

person Michael    schedule 15.02.2014    source แหล่งที่มา
comment
C# รองรับคุณสมบัติ   -  person Hans Passant    schedule 15.02.2014
comment
@HansPassant Java ก็เช่นกัน   -  person Cubic    schedule 15.02.2014
comment
ฉันจะเรียกรูปแบบกลิ่นการออกแบบที่แย่มากนี้ แทนที่จะทำ OOP ที่เหมาะสม คุณกำลังแฮ็กบางสิ่งด้วยข้อมูลทั่วไป   -  person Euphoric    schedule 15.02.2014
comment
@Euphoric คุณจะทำอย่างไรแตกต่างออกไป?   -  person Michael    schedule 15.02.2014
comment
@HansPassant หากข้อมูลเมตาจำเป็นต้องเปลี่ยนแปลงขณะรันไทม์ อินเทอร์เฟซก็ยอดเยี่ยม โดยเฉพาะอย่างยิ่งหากส่วนหนึ่งของข้อมูลเมตาจำเป็นต้องได้รับการแปล   -  person Gusdor    schedule 15.02.2014
comment
@HansPassant จริง ๆ แล้วฉันมักจะใช้สิ่งนี้กับรูปแบบปลั๊กอินโดยใช้คุณลักษณะในการใช้งานที่เป็นรูปธรรมซึ่งโรงงานใช้ ฉันได้แก้ไขเพื่อแสดงตัวอย่างคุณลักษณะและวิธีที่โรงงานจะนำไปใช้   -  person Michael    schedule 15.02.2014
comment
@Euphoric ทำไมมันแย่? ฉันพบว่ารูปแบบนี้มีประโยชน์ในบางกรณี และมันก็สมเหตุสมผลสำหรับฉันด้วย   -  person BlackBear    schedule 16.02.2014


คำตอบ (1)


ใช่ มันเหมือนกับที่คุณตั้งชื่อทุกประการ: อินเทอร์เฟซของมาร์กเกอร์

person Ufuk Hacıoğulları    schedule 15.02.2014
comment
คนอื่นเห็นด้วยกับเรื่องนี้หรือไม่? ก่อนที่ฉันจะยอมรับฉันต้องการให้แน่ใจว่า ฉันรู้ว่าอินเทอร์เฟซว่างที่ฉันใช้เป็นเกณฑ์สำหรับอาร์กิวเมนต์ทั่วไปคืออินเทอร์เฟซตัวทำเครื่องหมาย แต่ดูเหมือนว่าจะมีรูปแบบมากกว่านั้น เช่นเดียวกับการใช้ฐานทั่วไปเชิงนามธรรมเพื่อแมปอินเทอร์เฟซของมาร์กเกอร์ให้เป็นประเภทที่เป็นรูปธรรม และความสามารถในการสร้างการใช้งานที่เป็นรูปธรรมด้วยวิธีการที่ยอมรับพารามิเตอร์ประเภทต่างๆ แต่ยังคงสามารถเรียกผ่านอินเทอร์เฟซทั่วไปเพียงอินเทอร์เฟซเดียว - person Michael; 16.02.2014
comment
อีกประการหนึ่งคือบางครั้งมันไม่ใช่อินเทอร์เฟซของตัวทำเครื่องหมายด้วยซ้ำ บางครั้งคุณมีคลาส Message หรือ Context พื้นฐานที่มีฟิลด์ทั่วไป แต่รูปแบบที่เหลือยังคงเหมือนเดิม ในแง่ของการตั้งค่าอินเทอร์เฟซที่ไม่เชื่อเรื่องพระเจ้าประเภทหนึ่งและจากนั้นเป็นฐานทั่วไป ข้างใต้มัน - person Michael; 16.02.2014