2009-05-07 8 views
5

मैं कुछ कोड देख रहा हूं कि मेरा एक सहयोगी कार्यक्रम तर्क को नियंत्रित करने के लिए 'मार्कर कक्षाओं' का उपयोग कर रहा है (नीचे उल्लिखित उदाहरण देखें)। यह अच्छी तरह से काम करने लगता है, और कोड वास्तव में अच्छी तरह से पढ़ता है, लेकिन वहाँ अभी इसके बारे में कुछ खुशबू आ रही है वह यह है कि ...तर्क प्रवाह को नियंत्रित करने के लिए मार्कर कक्षाओं का उपयोग

namespace ConsoleApplication4983 
{ 
    public class MyClass 
    { 
     static void Main() 
     { 
      var c = new MyClass(); 
      c.DoSomething(new Sequential()); 
      c.DoSomething(new Random()); 
     } 

     public void DoSomething(ProcessingMethod method) 
     { 
      if (method is Sequential) 
      { 
       // do something sequential 
      } 
      else if (method is Random) 
      { 
       // do something random 
      } 
     } 
    } 

    public class ProcessingMethod {} 
    public class Sequential : ProcessingMethod {} 
    public class Random : ProcessingMethod {} 
} 

क्या एक ही प्रभाव को प्राप्त करने का एक बेहतर तरीका हो सकता है? Enums? गुण?

उत्तर

8

मार्कर इंटरफेस बेहतर अभ्यास है क्योंकि वे अधिक लचीलापन प्रदान करते हैं।

हालांकि इस विशिष्ट मामले में मुझे लगता है कि आभासी प्रेषण एक बेहतर समाधान है।

using System; 

namespace ConsoleApplication4983 
{ 
    public class MyClass 
    { 
     static void Main() 
     { 
      var c = new MyClass(); 
      c.DoSomething(new Sequential()); 
      c.DoSomething(new Random()); 
     } 

     public void DoSomething(ProcessingMethod method) 
     { 
      method.Foo(); 
     } 
    } 

    public class ProcessingMethod 
    { 
     public virtual void Foo() { } 
    } 
    public class Sequential : ProcessingMethod 
    { 
     public override void Foo() { } 
    } 
    public class Random : ProcessingMethod 
    { 
     public override void Foo() { } 
    } 
} 
1

वह लगभग वहां था, लेकिन काफी नहीं, और शायद यही वह है जो आप देख रहे हैं। इस प्रकार का बयान खराब गंध है। ऐसा कुछ प्रसंस्करण मोडस बेस क्लास पर होना चाहिए था और प्रत्येक प्रकार जो विस्तारित करता है, उसका अपना संस्करण होना चाहिए।

public void DoSomething(ProcessingMethod method) { 
    method.DoSomething(); 
} 
0

विशिष्ट उपclass में प्रसंस्करण तर्क को प्रतिनिधि करने के बारे में कैसे? ProcessingMethod में कुछ सार विधि होगी जो प्रत्येक उप-वर्ग द्वारा कार्यान्वित की जाती है।

public void DoSomething(ProcessingMethod method) 
{ 
    method.Process(); 
} 

public abstract class ProcessingMethod 
{ 
    public abstract void Process(); 
} 

public class Sequental : ProcessingMethod 
{ 
    public override void Process() 
    { 
    // do something sequential 
    } 
} 

public class Random : ProcessingMethod 
{ 
    public override void Process() 
    { 
    // do something random 
    } 
} 
0

हाँ, यह बदबू आ रही है। यदि आप कुछ समानांतर करना चाहते हैं:

public class Parallel : ProcessingMethod{} 

तो आपको बहुत सारे कोड को बदलना होगा।

4

आप क्या करना चाहते हैं इसे strategy pattern के साथ बदलें। एक रणनीति परिभाषित करती है कि कुछ कैसे किया जाता है - यानी, एक एल्गोरिदम।

public interface IProcessingMethod 
{ 
    void Process(); 
} 

public class SequentialProcess : IProcessingMethod 
{ 
    public void Process(IProcessable obj) 
    { 
     do something sequentially with the obj 
    } 
} 

public class ParallelProcess : IProcessingMethod 
{ 
    public void Process(IProcessable obj) 
    { 
     do something in parallel with the obj 
    } 
} 

public interface IProcessable 
{ 
    void Process(IProcessingMethod method); 
} 

public class MyClass : IProcessable 
{ 
    public void Process(IProcessingMethod method) 
    { 
     method.Process(this); 
    } 
} 

... 

var obj = new MyClass(); 
obj.Process(new SequentialProcess()); 

अब अगर मैं ProcessingMethod के एक नए प्रकार है, मैं बस उस विधि के लिए वर्ग बना सकते हैं और कोड निर्धारित करता है कि क्या संसाधन विधि मेरी IProcessable वस्तु की प्रक्रिया विधि को इंजेक्ट किया जाता है बदलने की जरूरत है।

+0

+1 यह एक अच्छा तरीका है। –

0

फ्रेमवर्क डिज़ाइन दिशानिर्देश पुस्तक मार्कर इंटरफेस (और संभावित रूप से मार्कर कक्षाओं) का उपयोग करने के लिए अनुशंसा करती है, गुणों को पूर्णांक पसंद करते हैं। ऐसा कहकर, पुस्तक कहती है कि is (जैसा आपने किया है) का उपयोग करके एक विशेषता की जांच करने के लिए प्रतिबिंब का उपयोग करने से बहुत तेज है।

2

मुझे लगता है कि यह प्रश्न पुराना है, लेकिन मुझे लगता है कि सभी उत्तरों बिंदु से चूक गए।

यदि उदाहरण आवश्यक कार्यक्षमता की सीमा को पूरी तरह से दिखाता है, तो यहां उपयोग करने के लिए उपयुक्त निर्माण एनम प्रकार होगा। एनम प्रकार मूल्य प्रकार हैं; वे अनिवार्य रूप से नामित संख्यात्मक स्थिरांक की तरह काम करते हैं, महान आईडीई स्वत: पूर्ण समर्थन के साथ। एनम प्रकार का उपयोग करने के लिए यहां संशोधित उदाहरण दिया गया है:

namespace ConsoleApplication4983 
{ 
    public class MyClass 
    { 
     static void Main() 
     { 
      var c = new MyClass(); 
      c.DoSomething(ProcessingMethod.Sequential); 
      c.DoSomething(ProcessingMethod.Random); 
     } 

     public void DoSomething(ProcessingMethod method) 
     { 
      if (method == ProcessingMethod.Sequential) 
      { 
       // do something sequential 
      } 
      else if (method == ProcessingMethod.Random) 
      { 
       // do something random 
      } 
     } 
    } 

    public enum ProcessingMethod 
    { 
     Sequential, 
     Random 
    } 
} 

अन्य उत्तर अधिक विस्तृत पैटर्न के संदर्भ में हैं। मुझे लगता है कि वे "मार्कर क्लास" शब्द में बहुत अधिक पढ़ते हैं। कभी-कभी रणनीति पैटर्न, आभासी प्रेषण इत्यादि जाने का एक अच्छा तरीका है, लेकिन इस मामले में मुझे लगता है कि इस कोड में एक एनम सबसे सरल सुधार है।

संबंधित मुद्दे

 संबंधित मुद्दे