2011-03-18 23 views
10

का उपयोग कर रहा है 3 वर्गों:जावा विरासत, बिल्डर पैटर्न

  1. त्रुटि
  2. ShellError
  3. WebError

जहां

ShellError extends Error 

और

WebError extends Error 

ShellError में ऐसे क्षेत्र हैं जिनमें से कुछ वैकल्पिक हैं और अन्य आवश्यक हैं। आगे

shellError = new ShellError.Builder().setFile(filePattern) 
.setHost(host).setPath(path).setSource(file.isSource()) 
.setJobName(p.getJobName()).build(); 

ShellError के बाद से फैली Error, मैं: मैं निम्नलिखित तरीके से वस्तु के निर्माण कर रहा हूँ

shellError.setDescription(msg.toString()); 
shellError.setExceptionClass("MyEvilException"); 
shellError.setExceptionMessage("Some clever error message"); 
shellError.setStacktrace(stack); 

तो ... क्यों बिल्डर से परेशान? मुझे यह तथ्य पसंद है कि मेरे निर्माण() अन्य चीजों के साथ आसानी से मान्य हैं कि सभी फ़ील्ड उचित रूप से सेट किए गए हैं।

अगर मैं कर सकता हूं तो मैं इसे प्यार करूंगा .. बिल्ड() ShellError और Error कक्षा से फ़ील्ड इसमें जोड़ें।

मैंने क्या काम किया।

  • सवाल यह है:

वहाँ एक बेहतर तरीका है, या यह मैं क्या किया मतलब है?

- संपादित करें

मैं अद्यतन बिल्डर() पैरामीटर जो पहले त्रुटि कक्षा में थे में से कुछ को स्वीकार करने के। अब मेरे पास

shellError = new ShellError.Builder(exception, "Some description").setFile(filePattern).setHost(host) 
.setPath(path).setSource(file.isSource()). 
setJobName(p.getJobName()).build(); 

आप क्या कहते हैं? बेहतर? और भी बुरा?

उत्तर

5

आपके द्वारा संदर्भित कार्यों के आधार पर, यह स्पष्ट रूप से मानक java.lang.Error वर्ग नहीं है। आम तौर पर बिल्डरों का उपयोग एक अपरिवर्तनीय वस्तु को आसानी से निर्मित करने या उन मामलों में "नामित पैरामीटर" जैसी कार्यक्षमता प्रदान करने के लिए किया जाता है जहां बहुत सारे कॉन्फ़िगरेशन/निर्माण पैरामीटर होते हैं।

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

आपने जो किया वह समझ में आया।ऐसा लगता है कि बिल्डर और त्रुटि वर्गों के डिज़ाइन की आवश्यकता पूरी तरह से समझ में नहीं आती है, जो आपको असंगत या असंगत महसूस करने वाले कोड को लिखने के लिए मजबूर करती है।

14

builder pattern, जोश ब्लोच द्वारा लोकप्रिय, several benefits है, लेकिन यह this discussion by our colleagues in the C# world में समझाया गया है, लेकिन यह माता-पिता/उप-वर्गों पर इतनी सुंदरता से काम नहीं करता है। मैंने अब तक का सबसे अच्छा समाधान this one (या slight variant) देखा है।

+0

बस इस पोस्ट को पूरा करने, "मामूली संस्करण" का अर्थ है: पिछले और अंतिम उदाहरण में: (1) निर्माता को (2) obj होना चाहिए और यह ओबीजे सुरक्षित होना चाहिए (3) निर्मित -> obj –

0

जैसा कि पहले से ही कहा गया था, निर्माता पैटर्न ऐसा कुछ नहीं है जो मौजूदा जावा ऑब्जेक्ट प्रारंभिक राजनीति में व्यवस्थित रूप से फिट हो सके। आवश्यक परिणाम प्राप्त करने के लिए कई दृष्टिकोण हैं। हालांकि, निश्चित रूप से, किसी भी संदिग्ध प्रथाओं से बचने के लिए हमेशा बेहतर होता है, यह हमेशा संभव नहीं होता है। मेरे हैक जेनरिक के साथ जावा प्रतिबिंब एपीआई पर आधारित है:

abstract public class AbstractClass { 

    public static class Builder { 

     public <T extends AbstractClass> T build(Class<T> implementingClass) { 
      try { 
       Constructor<T> constructor = implementingClass 
         .getConstructor(new Class[]{Builder.class}); 
       return constructor.newInstance(this); 
      } catch (NoSuchMethodException e) { 
       // TODO handle the exception 
      } catch (InvocationTargetException | InstantiationException | 
        IllegalAccessException e) { 
       // TODO handle the exception 
      } 
     } 
    } 

    protected AbstractClass(Builder builder) { 

    } 
} 

public class ImplementingClass extends AbstractClass { 

    public ImplementingClass (Builder builder) { 
     super(builder); 
    } 
} 

प्रारंभ:

ImplementingClass instance = new AbstractClass.Builder() 
        .build(ImplementingClass.class); 
संबंधित मुद्दे