2013-04-26 6 views
6

मेरे पास एक उपयोग कक्षा है जो कुछ काम करती है। जाहिर है, यह विस्तार के लिए बंद है और सभी विधियां स्थैतिक हैं। सादगी के लिए, वर्ग इस तरह दिखता है:स्थैतिक वर्गों के लिए टेम्पलेट विधि पैटर्न

public final class Util { 
    private Util() { } 

    public static void doWork() { 
     // some work 
     int variable = help(); 
     // some work uses variable 
    } 

    private static int help() { 
     // some helper functionality 
    } 
} 

वर्ग विधि doWork कि गणना का एक बहुत करता है। वैसे, विधि कुछ परिणाम प्राप्त करने के लिए सहायक विधि help पर कॉल करती है और शेष कोड help विधि द्वारा परिणाम का उपयोग करते हैं।

अब, ग्राहक कोड में मैं विधि doWork की कार्यक्षमता का पुन: उपयोग करना चाहते हैं, लेकिन इसके बजाय help बुलाने की मैं help2 विधि कॉल करना चाहते हैं। सबसे आसान समाधान केवल helphelp2 को बदलने के साथ विधि doWork2 बनाएं।

यह बहुत खराब दृष्टिकोण है, क्योंकि doWork में प्रत्येक परिवर्तन को doWork2 में दोहराया जाना चाहिए। यह Template Method पैटर्न के समान है, लेकिन इस तथ्य के कारण कि हमारे पास यहां विस्तार नहीं है, हम इसे लागू नहीं कर सकते हैं।

बेस्ट समाधान मैं इस विधि के लिए पैरामीटर जोड़ने, लेकिन doWork की सभी मौजूदा उपयोगकर्ताओं की रक्षा करने के साथ आया था:

public static void doWork() { 
    doWorkWithParameter(true); 
} 

public static void doWorkWithParameter(boolean helpOrHelp2) { 
    // some work 
    int variable = helpOrHelp2 ? help() : help2(); 
    // some work uses variable 
} 

बेहतर डिजाइन समाधान इस समस्या को हल करने के लिए लागू किया जा सकता कर रहे हैं क्या? Template Pattern जैसे लचीलापन प्राप्त करने का कोई तरीका है, लेकिन कक्षाओं का उपयोग करने के लिए आवेदन में है।

अग्रिम धन्यवाद।

+0

तो ऐसा कोई कारण आप अपने समाधान में विधि अधिभार का उपयोग नहीं करते है? 'सार्वजनिक स्थिर शून्य doWork() {...} ' ' सार्वजनिक स्थैतिक शून्य doWork (बूलियन परम) {...}' – Crazenezz

+0

या बेहतर अभी भी 'सार्वजनिक स्थिर शून्य doWork (int चर) '। हालांकि मुझे संदेह है कि वास्तविक जवाब यह है कि भ्रम statics के कारण है और वह वस्तुएं एक क्लीनर उत्तर प्रदान करती हैं - हालांकि अमूर्त उदाहरणों के साथ बताना मुश्किल है। –

+0

जो आप खोज रहे हैं वह रणनीति पैटर्न है। अर्नाल्डो के जवाब की जांच करें। –

उत्तर

5

मेरे सुझाव Command Pattern, जहां util वर्ग एक Invoker और प्रत्येक doWork सहायता जोड़े है में प्रेरित है कार्यकर्ता इंटरफ़ेस का उपयोग कर समाहित हैं।

कार्यकर्ता Inteface

public interface Worker { 
    public void doWork(); 
    public int help(); 
} 

जैसे कुछ हो सकता है util कक्षा

public final class Util { 
    private Util() { } 

    public static void toWork(Worker worker){ 
     worker.doWork(); 
    } 

} 

कंक्रीट कार्यकर्ता

public class ConcreteWorker implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 

एक अन्य कार्यकर्ता

(और doWork के कार्यान्वयन)
public class ConcreteWorker2 implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 1; 
    } 

} 

और निष्पादन

Util.toWork(new ConcreteWorker()); 
Util.toWork(new ConcreteWorker2()); 
+0

वर्कर इंटरफ़ेस के बजाय आप इसे बेहतर तरीके से doWork() विधि के साथ एक अमूर्त वर्ग के रूप में बनाते हैं। यह वास्तव में वही है जो मैं सुझाता हूं, लेकिन बस अधिक कोड के साथ। आपके पास चार की बजाय चार कक्षाएं हैं। मुझे लगता है कि enums स्थिर तरीकों के बेहतर प्रतिस्थापन हैं। – Mikhail

+1

बढ़िया! यह रणनीति पैटर्न 'संग्रह .sort (lst, तुलनात्मक)' की तरह दिखता है। मैं इसे कैसे याद कर सकता हूं? – mishadoff

1

आप 2 स्थिर वस्तु Help1 & Help2 को लागू करने Help इंटरफ़ेस जो बना सकते हैं एक मदद() विधि है और इस तरह से अपनी doWorkWithParameter पद्धति को बदलने:

public static void doWorkWithParameter(Help h) { 
    int variable = h.help(); 
} 

यह बारीकी से अपने वर्तमान समाधान से संबंधित है। लेकिन मुझे लगता है कि यह थोड़ा और अधिक "ऑब्जेक्ट ओरिएंटेड" है।

1

ऐसा नहीं है बहुत समय पहले मैं इस बना दिया है:

public static enum Helper{ 
    OLD(){ 
     public int help(){ 
      return 0; 
     } 
    }, 

    NEW(){ 
     public int help(){ 
      return 1; 
     } 
    }; 

    public abstract int help(); 

    public void doWork() { 
     int variable = help(); 
    } 
} 

public static Helper HELPER = Helper.NEW; 

तो हम कॉल कर सकते हैं:

Constants.HELPER.doWork() 

HELPER निरंतर मूल्यों स्विच करने से मैं व्यवहार बदल सकते हैं। या आप कर सकते हैं:

Helper.OLD.doWork(); 
Helper.NEW.doWork(); 
+0

धन्यवाद, अच्छी चाल। – mishadoff

+0

यह प्रभावी जावा पुस्तक से है - "आइटम 34: इंटरफेस के साथ अनुकरण एक्स्टेंसिबल एनम्स" – Mikhail

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