Apakah Ada Nama untuk Pola ini

Saya telah menggunakan pola ini berkali-kali di berbagai tempat, biasanya di samping pola plugin.

Beberapa contoh cara saya menggunakannya adalah untuk sistem pesan, seperti membuat pelanggan untuk berbagai jenis pesan yang tidak terkait. Saya juga menggunakannya untuk alur kerja integrasi umum yang masing-masing memerlukan objek konteks dengan bentuk berbeda.

Pada dasarnya polanya terdiri dari pendefinisian antarmuka penanda kosong untuk suatu pesan atau konteks. Kemudian mendefinisikan antarmuka alur kerja tingkat tinggi yang berfungsi dengan antarmuka pesan/konteks. Anda kemudian dapat menggunakan pabrik untuk mendapatkan contoh nyata dari alur kerja, dan jika diperlukan, alur kerja juga dapat bertanggung jawab untuk menguraikan pesan/konteksnya dari format data umum.

Selanjutnya, Anda membuat alur kerja dasar generik abstrak yang tanggung jawabnya hanya memetakan panggilan ke metode antarmuka, yang meneruskan antarmuka penanda yang tidak berguna, menjadi panggilan ke metode abstrak yang mengambil versi nyata dari pesan/konteks.

Semoga itu masuk akal. Saya akan memberikan contoh kode di bawah ini. Saya ingin tahu apakah pola ini mempunyai nama karena saya perhatikan saya sudah menggunakannya sekitar 4-5 kali sekarang. Selain itu, saya baru saja menjelaskan cara menjelaskan polanya, jadi jika penjelasan saya ada yang tidak masuk akal, harap beri tahu saya juga.

Poin utamanya adalah Anda dapat memiliki beberapa kelas dengan tanda tangan metode berbeda yang masih dapat dipanggil melalui antarmuka umum:

Hasil Akhir

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

CONTOH LENGKAP

Antarmuka Tingkat Tinggi

public interface IGenericeMarkerInterface
{
}

public interface IGenericWorkflow
{
    void Process(IGenericeMarkerInterface messageOrContext);

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

Dasar Abstrak untuk Pemetaan ke Metode Beton

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

Memetakan Atribut

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

Implementasi Beton

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

Pabrik

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

Contoh Penggunaan

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 sumber
comment
C# mendukung atribut.   -  person Hans Passant    schedule 15.02.2014
comment
@HansPassant Begitu juga Java.   -  person Cubic    schedule 15.02.2014
comment
Saya menyebutnya pola bau desain yang buruk. Alih-alih melakukan OOP yang benar, Anda meretas sesuatu dengan obat generik.   -  person Euphoric    schedule 15.02.2014
comment
@Euphoric Apa yang akan Anda lakukan secara berbeda?   -  person Michael    schedule 15.02.2014
comment
@HansPassant jika metadata perlu diubah saat runtime, antarmukanya bagus. terutama jika sebagian metadata perlu dilokalkan   -  person Gusdor    schedule 15.02.2014
comment
@HansPassant Saya sebenarnya sering menggunakan ini dengan pola plugin menggunakan atribut pada implementasi konkret yang kemudian digunakan oleh pabrik. Saya telah mengedit untuk menunjukkan kepada Anda contoh atribut dan bagaimana pabrik dapat menggunakannya   -  person Michael    schedule 15.02.2014
comment
@Euforia kenapa jelek? Saya telah menemukan pola ini berguna dalam beberapa kasus dan itu masuk akal bagi saya   -  person BlackBear    schedule 16.02.2014


Jawaban (1)


Ya, sama persis dengan nama Anda: Antarmuka penanda

person Ufuk Hacıoğulları    schedule 15.02.2014
comment
Apakah semua orang setuju dengan hal ini? Sebelum saya menerima saya ingin memastikan. Saya tahu antarmuka kosong yang saya gunakan sebagai kriteria untuk argumen umum adalah antarmuka penanda, tetapi sepertinya ada lebih dari pola itu. Seperti penggunaan basis generik abstrak untuk memetakan antarmuka penanda ke dalam tipe konkrit dan kemudian kemampuan untuk membuat implementasi konkrit dengan metode yang menerima tipe parameter berbeda namun masih dapat dipanggil melalui satu antarmuka umum. - person Michael; 16.02.2014
comment
Hal lainnya adalah kadang-kadang bahkan bukan antarmuka penanda, kadang-kadang Anda memiliki kelas Pesan atau Konteks dasar dengan bidang umum, tetapi pola lainnya tetap sama, dalam hal menyiapkan antarmuka tipe-agnostik dan kemudian basis generik di bawahnya. - person Michael; 16.02.2014