ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग - एक चर के आधार पर थोड़ा भिन्न होने वाली प्रक्रियाओं में दोहराव से कैसे बचा जाए


64

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

हम उस उदाहरण का उपयोग करेंगे जो हमारे पास आमतौर पर है, जो हम जिस देश के साथ काम कर रहे हैं, उसके आधार पर कुछ अलग तरह से कर रहे हैं।

तो मेरे पास एक वर्ग है, चलो इसे कॉल करें Processor:

public class Processor
{
    public string Process(string country, string text)
    {
        text.Capitalise();

        text.RemovePunctuation();

        text.Replace("é", "e");

        var split = text.Split(",");

        string.Join("|", split);
    }
}

सिवाय इसके कि उन कुछ कार्यों के लिए कुछ देशों को ही होना चाहिए। उदाहरण के लिए, केवल 6 देशों को पूंजीकरण कदम की आवश्यकता है। देश के आधार पर विभाजन का चरित्र बदल सकता है। उच्चारण की जगह 'e'केवल देश के आधार पर आवश्यक हो सकती है।

जाहिर है आप इसे कुछ इस तरह से हल कर सकते हैं:

public string Process(string country, string text)
{
    if (country == "USA" || country == "GBR")
    {
        text.Capitalise();
    }

    if (country == "DEU")
    {
        text.RemovePunctuation();
    }

    if (country != "FRA")
    {
        text.Replace("é", "e");
    }

    var separator = DetermineSeparator(country);
    var split = text.Split(separator);

    string.Join("|", split);
}

लेकिन जब आप दुनिया के सभी संभावित देशों के साथ काम कर रहे होते हैं, तो यह बहुत बोझिल हो जाता है। और इसकी परवाह किए बिना, ifवक्तव्य तर्क को पढ़ने में कठिन बनाते हैं (कम से कम, यदि आप उदाहरण से अधिक जटिल विधि की कल्पना करते हैं), और चक्रीय जटिलता बहुत तेजी से रेंगना शुरू कर देती है।

इसलिए फिलहाल मैं कुछ ऐसा करने की कोशिश कर रहा हूं:

public class Processor
{
    CountrySpecificHandlerFactory handlerFactory;

    public Processor(CountrySpecificHandlerFactory handlerFactory)
    {
        this.handlerFactory = handlerFactory;
    }

    public string Process(string country, string text)
    {
        var handlers = this.handlerFactory.CreateHandlers(country);
        handlers.Capitalier.Capitalise(text);

        handlers.PunctuationHandler.RemovePunctuation(text);

        handlers.SpecialCharacterHandler.ReplaceSpecialCharacters(text);

        var separator = handlers.SeparatorHandler.DetermineSeparator();
        var split = text.Split(separator);

        string.Join("|", split);
    }
}

हैंडलर:

public class CountrySpecificHandlerFactory
{
    private static IDictionary<string, ICapitaliser> capitaliserDictionary
                                    = new Dictionary<string, ICapitaliser>
    {
        { "USA", new Capitaliser() },
        { "GBR", new Capitaliser() },
        { "FRA", new ThingThatDoesNotCapitaliseButImplementsICapitaliser() },
        { "DEU", new ThingThatDoesNotCapitaliseButImplementsICapitaliser() },
    };

    // Imagine the other dictionaries like this...

    public CreateHandlers(string country)
    {
        return new CountrySpecificHandlers
        {
            Capitaliser = capitaliserDictionary[country],
            PunctuationHanlder = punctuationDictionary[country],
            // etc...
        };
    }
}

public class CountrySpecificHandlers
{
    public ICapitaliser Capitaliser { get; private set; }
    public IPunctuationHanlder PunctuationHanlder { get; private set; }
    public ISpecialCharacterHandler SpecialCharacterHandler { get; private set; }
    public ISeparatorHandler SeparatorHandler { get; private set; }
}

जो समान रूप से मुझे यकीन नहीं है कि मुझे पसंद है। तर्क अभी भी कुछ हद तक कारखाने के निर्माण से अस्पष्ट है और आप मूल विधि को नहीं देख सकते हैं और उदाहरण के लिए "GBR" प्रक्रिया निष्पादित होने पर क्या होता है। आप शैली GbrPunctuationHandler, UsaPunctuationHandlerआदि में बहुत सारी कक्षाएं (इससे अधिक जटिल उदाहरणों में) बनाते हैं , आदि ... जिसका अर्थ है कि आपको विराम चिह्न के दौरान होने वाले सभी संभावित कार्यों का पता लगाने के लिए कई अलग-अलग वर्गों को देखना होगा। हैंडलिंग। स्पष्ट रूप से मैं एक विशाल वर्ग को एक बिलियन ifस्टेटमेंट के साथ नहीं चाहता , लेकिन समान रूप से 20 अलग-अलग तर्क वाले वर्ग भी क्लंकी महसूस करते हैं।

मूल रूप से मुझे लगता है कि मैं अपने आप को OOP गाँठ के कुछ प्रकार में ले आया हूँ और इसे अछूता करने का एक अच्छा तरीका नहीं जानता। मैं सोच रहा था कि क्या इस तरह की प्रक्रिया से मदद मिलेगी?


लगता है कि आपके पास एक PreProcessकार्यक्षमता है, जिसे कुछ देशों के आधार पर अलग-अलग लागू किया जा सकता है, DetermineSeparatorउन सभी के लिए हो सकता है, और ए PostProcess। उनमें से सभी protected virtual voidएक डिफ़ॉल्ट कार्यान्वयन के साथ हो सकते हैं , और फिर आप Processorsप्रति देश के लिए विशिष्ट हो सकते हैं
Icepickle

आपका काम दिए गए समय सीमा में कुछ करना है जो काम करता है, और भविष्य में या आपके या किसी और के द्वारा बनाए रखा जा सकता है। यदि कई विकल्प दोनों स्थितियों को पूरा कर सकते हैं तो आप अपनी पसंद के अनुसार उनमें से किसी को भी चुनने के लिए स्वतंत्र हैं।
डायलेक्टिकस

2
आपके लिए एक व्यवहार्य विकल्प एक कॉन्फ़िगरेशन है। इसलिए आपके कोड में आप विशिष्ट देश के लिए नहीं, बल्कि विशिष्ट कॉन्फ़िगरेशन विकल्प के लिए जाँच करते हैं। लेकिन प्रत्येक देश में उन कॉन्फ़िगरेशन विकल्पों का एक विशिष्ट सेट होगा। उदाहरण के लिए, if (country == "DEU")आप के बजाय जाँच करें if (config.ShouldRemovePunctuation)
डायलेक्टिकस

11
यदि देशों के पास विभिन्न विकल्प हैं, तो उन विकल्पों को मॉडल करने वाले वर्ग के उदाहरण के बजाय countryएक स्ट्रिंग क्यों है ?
डैमियन_इन_यूएनबेलिएवर

@Damien_The_Unbeliever - क्या आप इस पर थोड़ा विस्तार कर सकते हैं? क्या आप जो सुझाव दे रहे हैं, उसकी तर्ज पर रॉबर्ट ब्रूटिगम का जवाब नीचे दिया गया है। - आह अब आपका जवाब देख सकता है, धन्यवाद!
जॉन डारविल

जवाबों:


53

मैं सुझाव दूंगा कि सभी विकल्पों को एक कक्षा में रखा जाए:

public class ProcessOptions
{
  public bool Capitalise { get; set; }
  public bool RemovePunctuation { get; set; }
  public bool Replace { get; set; }
  public char ReplaceChar { get; set; }
  public char ReplacementChar { get; set; }
  public char JoinChar { get; set; }
  public char SplitChar { get; set; }
}

और इसे Processविधि में पास करें :

public string Process(ProcessOptions options, string text)
{
  if(options.Capitalise)
    text.Capitalise();

  if(options.RemovePunctuation)
    text.RemovePunctuation();

  if(options.Replace)
    text.Replace(options.ReplaceChar, options.ReplacementChar);

  var split = text.Split(options.SplitChar);

  string.Join(options.JoinChar, split);
}

4
निश्चित नहीं कि ऐसा कुछ करने की कोशिश क्यों नहीं की गई CountrySpecificHandlerFactory... o_0
मेटेन उल्हाक

जब तक कोई विशेष विकल्प नहीं हैं, मैं निश्चित रूप से इस तरह से जाऊंगा। यदि विकल्पों को टेक्स्ट-फाइल में क्रमबद्ध किया जाता है, तो यह गैर-प्रोग्रामर को नए वेरिएंट को परिभाषित करने / मौजूदा अपडेट को अपडेट करने की अनुमति देता है।
टॉम

4
यह public class ProcessOptionsवास्तव में सिर्फ होना चाहिए [Flags] enum class ProcessOptions : int { ... }...
नशे में कोड बंदर

और मुझे लगता है कि अगर उन्हें जरूरत है, तो वे देशों का एक नक्शा हो सकता है ProcessOptions। बहुत ही सुविधाजनक।
theonlygusti

24

जब .NET फ्रेमवर्क समस्याओं के इन प्रकारों को संभालने के लिए सेट होता है, तो यह सब कुछ मॉडल नहीं करता था string। तो आपके पास, उदाहरण के लिए, CultureInfoवर्ग :

एक विशिष्ट संस्कृति के बारे में जानकारी प्रदान करता है (मानव रहित कोड विकास के लिए एक स्थान कहा जाता है)। जानकारी में संस्कृति के लिए नाम, लेखन प्रणाली, इस्तेमाल किया जाने वाला कैलेंडर, तार का क्रम क्रम और तिथियों और संख्याओं के लिए प्रारूपण शामिल हैं।

अब, इस वर्ग में उन विशिष्ट विशेषताओं को शामिल नहीं किया जा सकता है जिनकी आपको आवश्यकता है, लेकिन आप स्पष्ट रूप से कुछ अनुरूप बना सकते हैं। और फिर आप अपनी Processविधि बदलते हैं :

public string Process(CountryInfo country, string text)

आपकी CountryInfoकक्षा के पास एक bool RequiresCapitalizationसंपत्ति आदि हो सकती है, जो आपके Processतरीके को उचित रूप से इसके प्रसंस्करण को निर्देशित करने में मदद करती है।


13

शायद आपके पास Processorप्रति देश एक हो सकता है ?

public class FrProcessor : Processor {
    protected override string Separator => ".";

    protected override string ProcessSpecific(string text) {
        return text.Replace("é", "e");
    }
}

public class UsaProcessor : Processor {
    protected override string Separator => ",";

    protected override string ProcessSpecific(string text) {
        return text.Capitalise().RemovePunctuation();
    }
}

और प्रसंस्करण के सामान्य भागों को संभालने के लिए एक आधार वर्ग:

public abstract class Processor {
    protected abstract string Separator { get; }

    protected virtual string ProcessSpecific(string text) { }

    private string ProcessCommon(string text) {
        var split = text.Split(Separator);
        return string.Join("|", split);
    }

    public string Process(string text) {
        var s = ProcessSpecific(text);
        return ProcessCommon(s);
    }
}

इसके अलावा, आपको अपने रिटर्न प्रकारों को फिर से तैयार करना चाहिए क्योंकि यह संकलन नहीं होगा जैसा कि आपने उन्हें लिखा है - कभी-कभी एक stringविधि कुछ भी वापस नहीं करती है।


मुझे लगता है कि मैं विरासत मंत्र पर रचना का पालन करने की कोशिश कर रहा था। लेकिन हाँ यह निश्चित रूप से एक विकल्प है, उत्तर के लिए धन्यवाद।
जॉन डारविले

काफी उचित। मुझे लगता है कि विरासत कुछ मामलों में उचित है, लेकिन यह वास्तव में इस बात पर निर्भर करता है कि आप अंत में अपने तरीकों और प्रसंस्करण को लोड / स्टोर / इनवॉइस करने / बदलने की योजना कैसे बनाते हैं।
कोरेंटिन पेन

3
कभी-कभी, विरासत नौकरी के लिए सही उपकरण है। यदि आपको एक ऐसी प्रक्रिया मिली है जो कई अलग-अलग स्थितियों में ज्यादातर उसी तरह से व्यवहार करने वाली है, लेकिन इसके कई हिस्से हैं जो अलग-अलग स्थितियों में अलग-अलग व्यवहार करेंगे, तो यह एक अच्छा संकेत है जिसे आपको विरासत का उपयोग करने पर विचार करना चाहिए।
टान्नर स्विट

5

आप एक Processविधि के साथ एक सामान्य इंटरफ़ेस बना सकते हैं ...

public interface IProcessor
{
    string Process(string text);
}

फिर आप इसे प्रत्येक देश के लिए लागू करते हैं ...

public class Processors
{
    public class GBR : IProcessor
    {
        public string Process(string text)
        {
            return $"{text} (processed with GBR rules)";
        }
    }

    public class FRA : IProcessor
    {
        public string Process(string text)
        {
            return $"{text} (processed with FRA rules)";
        }
    }
}

फिर आप प्रत्येक देश से संबंधित वर्ग को तत्काल तैयार करने और निष्पादित करने के लिए एक सामान्य विधि बना सकते हैं ...

// also place these in the Processors class above
public static IProcessor CreateProcessor(string country)
{
    var typeName = $"{typeof(Processors).FullName}+{country}";
    var processor = (IProcessor)Assembly.GetAssembly(typeof(Processors)).CreateInstance(typeName);
    return processor;
}

public static string Process(string country, string text)
{
    var processor = CreateProcessor(country);
    return processor?.Process(text);
}

फिर आपको बस प्रोसेसर बनाने और उसका उपयोग करने की आवश्यकता है ...

// create a processor object for multiple use, if needed...
var processorGbr = Processors.CreateProcessor("GBR");
Console.WriteLine(processorGbr.Process("This is some text."));

// create and use a processor for one-time use
Console.WriteLine(Processors.Process("FRA", "This is some more text."));

यहाँ एक काम कर रहे डॉटनेट का उदाहरण है ...

आप प्रत्येक देश वर्ग में सभी देश-विशिष्ट प्रसंस्करण रखते हैं। सभी वास्तविक व्यक्तिगत तरीकों के लिए एक सामान्य वर्ग (प्रसंस्करण वर्ग में) बनाएं, इसलिए प्रत्येक देश प्रोसेसर प्रत्येक देश वर्ग में कोड की बजाय अन्य सामान्य कॉल की एक सूची बन जाता है।

नोट: आपको जोड़ना होगा ...

using System.Assembly;

देश के वर्ग का एक उदाहरण बनाने के लिए स्थैतिक विधि के लिए।


क्या कोई प्रतिबिंबित कोड की तुलना में प्रतिबिंब उल्लेखनीय रूप से धीमा नहीं है? क्या यह इस मामले के लिए लायक है?
jlvaquero

@jlvaquero नहीं, प्रतिबिंब उल्लेखनीय रूप से धीमा नहीं है। बेशक, डिजाइन के समय में एक प्रकार को निर्दिष्ट करने के लिए एक प्रदर्शन हिट है, लेकिन यह वास्तव में एक नगण्य प्रदर्शन अंतर है और जब आप इसे उपयोग करते हैं तो केवल ध्यान देने योग्य होता है। मैंने जेनेरिक ऑब्जेक्ट हैंडलिंग के आसपास निर्मित बड़े संदेश प्रणालियों को लागू किया है और हमारे पास प्रदर्शन पर सवाल उठाने का कोई कारण नहीं है, और यह बड़ी मात्रा में थ्रूपुट के साथ है। प्रदर्शन में कोई उल्लेखनीय अंतर नहीं होने से, मैं हमेशा कोड को बनाए रखने के लिए सरल के साथ जाऊंगा, इस तरह।
मोनिका सेलियो

यदि आप प्रतिबिंबित कर रहे हैं, तो क्या आप देश के स्ट्रिंग को प्रत्येक कॉल से हटाना नहीं चाहेंगे Process, और इसके बजाय एक बार सही IProcessor प्राप्त करने के लिए इसका उपयोग करें? आप आमतौर पर एक ही देश के नियमों के अनुसार बहुत से पाठ संसाधित कर रहे होंगे।
डेविस्लोर

@Davislor यह कोड वास्तव में ऐसा ही करता है। जब आप कॉल करते हैं तो Process("GBR", "text");यह स्टैटिक विधि को कार्यान्वित करता है जो GBR प्रोसेसर का एक उदाहरण बनाता है और उस पर प्रोसेस विधि को निष्पादित करता है। यह केवल एक उदाहरण पर निष्पादित करता है, उस विशिष्ट देश प्रकार के लिए।
मोनिका सेलियो

@ आर्चर राइट, इसलिए उस विशिष्ट मामले में जहां आप एक ही देश के लिए नियमों के अनुसार कई स्ट्रिंग्स को संसाधित कर रहे हैं, यह एक बार उदाहरण बनाने के लिए अधिक कुशल होगा या हैश टेबल / शब्दकोश में एक निरंतर उदाहरण देखें और वापस लौटें उस के लिए एक संदर्भ। फिर आप उसी उदाहरण पर पाठ-परिवर्तन कह सकते हैं। हर कॉल के लिए एक नया उदाहरण बनाना और फिर उसे हर कॉल के लिए फिर से इस्तेमाल करने के बजाय उसे छोड़ना बेकार है।
डेविसलर

3

कुछ संस्करण पहले, पैटर्न मिलान के लिए C # swtich को पूरा समर्थन दिया गया था । ताकि "कई देशों का मिलान" मामला आसानी से हो जाए। हालांकि यह अभी भी क्षमता से कम नहीं है, एक इनपुट पैटर्न मिलान के साथ कई मामलों का मिलान कर सकता है। यह हो सकता है कि अगर एक बिट स्पष्ट स्पैम।

Npw एक स्विच आमतौर पर एक संग्रह के साथ बदला जा सकता है। आपको डेलिगेट्स और एक शब्दकोश का उपयोग करने की आवश्यकता है। प्रक्रिया के साथ बदला जा सकता है।

public delegate string ProcessDelegate(string text);

तब आप एक शब्दकोश बना सकते हैं:

var Processors = new Dictionary<string, ProcessDelegate>(){
  { "USA", EnglishProcessor },
  { "GBR", EnglishProcessor },
  { "DEU", GermanProcessor }
}

मैं फ़ंक्शन का उपयोग करता था प्रतिनिधि में हाथ करने के लिए। लेकिन आप संपूर्ण कोड प्रदान करने के लिए लैम्बडा सिंटैक्स का उपयोग कर सकते हैं। इस तरह आप किसी अन्य बड़े संग्रह की तरह उस पूरे संग्रह को छिपा सकते हैं। और कोड एक साधारण खोज बन जाता है:

ProcessDelegate currentProcessor = Processors[country];
string processedString = currentProcessor(country);

वे बहुत ज्यादा दो विकल्प हैं। आप मिलान के लिए तार के बजाय गणना के उपयोग पर विचार करना चाह सकते हैं, लेकिन यह एक छोटा विवरण है।


2

मैं शायद (आपके उपयोग-मामले के विवरण के आधार पर) Countryएक स्ट्रिंग के बजाय "वास्तविक" ऑब्जेक्ट होने के साथ जाऊंगा । कीवर्ड "बहुरूपता" है।

तो मूल रूप से यह इस तरह दिखेगा:

public interface Country {
   string Process(string text);
}

फिर आप उन देशों के लिए विशिष्ट देश बना सकते हैं जिनकी आपको आवश्यकता है। नोट: आपको Countryसभी देशों के लिए ऑब्जेक्ट बनाने की ज़रूरत नहीं है , आप कर सकते हैं LatinlikeCountry, या यहाँ तक कि GenericCountry। वहां आप जो कर सकते हैं, उसे इकट्ठा कर सकते हैं, यहां तक ​​कि दूसरों को फिर से इस्तेमाल करना, जैसे:

public class France {
   public string Process(string text) {
      return new GenericCountry().process(text)
         .replace('a', 'b');
   }
}

या इसी के समान। Countryवास्तव में हो सकता है Language, मैं उपयोग-मामले के बारे में निश्चित नहीं हूं, लेकिन मुझे आपकी बात समझ आ गई है।

साथ ही, पाठ्यक्रम का तरीका Process()यह नहीं होना चाहिए कि यह वह चीज होनी चाहिए जिसकी आपको वास्तव में जरूरत है। जैसे Words()या जो भी हो।


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

1

आप अपनी जिम्मेदारी के बारे में कुछ जानना चाहते हैं। इसलिए देश या कल्चरइन्फो टाइप का उपयोग करें या निर्माण करें, जैसा कि अन्य उत्तरों में ऊपर बताया गया है।

लेकिन सामान्य तौर पर और बुनियादी तौर पर आपकी समस्या यह है कि आप 'प्रोसेसर' जैसे प्रक्रियात्मक निर्माणों को ले रहे हैं और उन्हें ओओ पर लागू कर रहे हैं। OO सॉफ्टवेयर में किसी व्यवसाय या समस्या डोमेन से वास्तविक विश्व अवधारणाओं का प्रतिनिधित्व करने के बारे में है। प्रोसेसर सॉफ्टवेयर के अलावा वास्तविक दुनिया की किसी भी चीज़ में अनुवाद नहीं करता है। जब भी आपके पास प्रोसेसर या प्रबंधक या राज्यपाल जैसी कक्षाएं हों, तो खतरे की घंटी बजनी चाहिए।


0

मैं सोच रहा था कि क्या वहाँ एक पैटर्न था जो इस प्रकार की प्रक्रिया में मदद करेगा

पुनर्विचार की श्रृंखला एक ऐसी चीज है जिसे आप देख सकते हैं लेकिन OOP में कुछ बोझिल है ...

C # के साथ अधिक कार्यात्मक दृष्टिकोण के बारे में क्या?

using System;


namespace Kata {

  class Kata {


    static void Main() {

      var text = "     testing this thing for DEU          ";
      Console.WriteLine(Process.For("DEU")(text));

      text = "     testing this thing for USA          ";
      Console.WriteLine(Process.For("USA")(text));

      Console.ReadKey();
    }

    public static class Process {

      public static Func<string, string> For(string country) {

        Func<string, string> baseFnc = (string text) => text;

        var aggregatedFnc = ApplyToUpper(baseFnc, country);
        aggregatedFnc = ApplyTrim(aggregatedFnc, country);

        return aggregatedFnc;

      }

      private static Func<string, string> ApplyToUpper(Func<string, string> currentFnc, string country) {

        string toUpper(string text) => currentFnc(text).ToUpper();

        Func<string, string> fnc = null;

        switch (country) {
          case "USA":
          case "GBR":
          case "DEU":
            fnc = toUpper;
            break;
          default:
            fnc = currentFnc;
            break;
        }
        return fnc;
      }

      private static Func<string, string> ApplyTrim(Func<string, string> currentFnc, string country) {

        string trim(string text) => currentFnc(text).Trim();

        Func<string, string> fnc = null;

        switch (country) {
          case "DEU":
            fnc = trim;
            break;
          default:
            fnc = currentFnc;
            break;
        }
        return fnc;
      }
    }
  }
}

नोट: यह निश्चित रूप से सभी स्थिर होने की जरूरत नहीं है। यदि प्रोसेस क्लास को राज्य की आवश्यकता है तो आप एक इंस्टेंस्ड क्लास या आंशिक रूप से लागू फ़ंक्शन का उपयोग कर सकते हैं;)।

आप स्टार्टअप पर प्रत्येक देश के लिए प्रक्रिया का निर्माण कर सकते हैं, प्रत्येक को एक अनुक्रमित संग्रह में संग्रहीत कर सकते हैं और ओ (1) लागत के साथ आवश्यकता होने पर उन्हें पुनः प्राप्त कर सकते हैं।


0

मुझे खेद है कि मैंने बहुत पहले इस विषय के लिए "ऑब्जेक्ट" शब्द गढ़ा था क्योंकि यह बहुत से लोगों को कम विचार पर ध्यान केंद्रित करने के लिए मिलता है। बड़ा आइडिया है मैसेज करना

~ एलन के, मैसेजिंग पर

मैं बस दिनचर्या लागू करेगा Capitalise, RemovePunctuationsubprocesses है कि एक साथ संदेश भेजा जा सकता है के रूप में आदि textऔरcountry मानकों, और एक संसाधित पाठ लौट आते हैं।

एक विशिष्ट विशेषता (यदि आप सूचियों को प्राथमिकता देते हैं, तो यह केवल एक मामूली प्रदर्शन लागत के साथ काम करेगा) समूह देशों के शब्दकोशों का उपयोग करें। उदाहरण के लिए: CapitalisationApplicableCountriesऔर PunctuationRemovalApplicableCountries

/// Runs like a pipe: passing the text through several stages of subprocesses
public string Process(string country, string text)
{
    text = Capitalise(country, text);
    text = RemovePunctuation(country, text);
    // And so on and so forth...

    return text;
}

private string Capitalise(string country, string text)
{
    if ( ! CapitalisationApplicableCountries.ContainsKey(country) )
    {
        /* skip */
        return text;
    }

    /* do the capitalisation */
    return capitalisedText;
}

private string RemovePunctuation(string country, string text)
{
    if ( ! PunctuationRemovalApplicableCountries.ContainsKey(country) )
    {
        /* skip */
        return text;
    }

    /* do the punctuation removal */
    return punctuationFreeText;
}

private string Replace(string country, string text)
{
    // Implement it following the pattern demonstrated earlier.
}

0

मुझे लगता है कि देशों की जानकारी कोड में नहीं, डेटा में रखनी चाहिए। इसलिए एक CountryInfo वर्ग या CapitalisationApplicableCountries शब्दकोश के बजाय, आपके पास प्रत्येक देश के लिए रिकॉर्ड के साथ एक डेटाबेस और प्रत्येक प्रसंस्करण चरण के लिए एक फ़ील्ड हो सकता है, और फिर प्रसंस्करण किसी दिए गए देश के लिए फ़ील्ड्स के अनुसार जा सकता है और तदनुसार प्रक्रिया कर सकता है। तब रखरखाव मुख्य रूप से डेटाबेस में होता है, नए कोड के साथ केवल तब आवश्यक होता है जब नए चरणों की आवश्यकता होती है, और डेटा डेटाबेस में मानव पठनीय हो सकता है। यह मानता है कि चरण स्वतंत्र हैं और एक-दूसरे के साथ हस्तक्षेप नहीं करते हैं; अगर ऐसा नहीं है तो चीजें जटिल हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.