2012-12-19 37 views
6

यह आइटम 40 के एक हिस्से को समझने का प्रयास है: प्रभावी विधि द्वितीय संस्करण से डिजाइन विधि हस्ताक्षर सावधानी सेविधि आमंत्रण के लिए बिल्डर पैटर्न को अनुकूलित करना

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

एक तिहाई तकनीक है कि जोड़ती है पहले दो के पहलुओं बिल्डर पैटर्न अनुकूल करने के लिए है से (आइटम 2) विधि आमंत्रण के लिए ऑब्जेक्ट निर्माण। यदि आपके पास कई पैरामीटर के साथ कोई तरीका है, खासकर यदि उनमें से कुछ वैकल्पिक हैं, तो यह ऑब्जेक्ट को परिभाषित करने के लिए फायदेमंद हो सकता है जो सभी मानकों का प्रतिनिधित्व करता है, और क्लाइंट को इस ऑब्जेक्ट पर एकाधिक "सेटर" कॉल करने की अनुमति देने के लिए , जिनमें से प्रत्येक एक पैरामीटर या एक छोटा, संबंधित समूह सेट करता है। एक बार वांछित पैरामीटर सेट हो जाने के बाद, क्लाइंट ऑब्जेक्ट की "निष्पादन" विधि को आमंत्रित करता है, जो पैरामीटर पर अंतिम वैधता जांच करता है और वास्तविक गणना करता है।

मैं बिल्डर पैटर्न से परिचित हूं क्योंकि इसका उपयोग ऑब्जेक्ट निर्माण के लिए किया जाता है, लेकिन मुझे यकीन नहीं है कि मैंने सही तरीके से समझ लिया है कि विधिवत आमंत्रण के लिए इसे कैसे अनुकूलित किया जाए।

public class Space { 

    public static class Builder { 
     // Required parameters 
     private final int x; 
     private final int y; 
     private final int z; 

     // optional params 
     private long time = 0; 

     public Builder(int x, int y, int z) { 
      this.x = x; 
      this.y = y; 
      this.z = z; 
     } 

     public Builder time(long val) { 
      time = val; 
      return this; 
     } 

     public void move() { 
      if (x == 0 || y == 0 || z == 0) { 
       throw new IllegalArgumentException("Cannot move to the centre of the universe"); 
      } 

      // Do the actual work here 
     } 
    } 

// public void move(int x, int y, int z, long time) { 
//  // Do the work here 
// } 

    public static void main(String[] args) { 
     new Builder(1, 1, -1).time(1234).move(); 
    } 
} 

यहोशू बलोच की सलाह मेरी व्याख्या सही है (मैं move विधि के लिए विधि मंगलाचरण में सुधार करने का प्रयास किया है):

यहाँ मैं अब तक किया है?

+0

आह मुझे ऐसा करने का मतलब था लेकिन यह मेरे दिमाग में फिसल गया। मैं जावा के लिए jsfiddle की तरह कुछ खोजना चाहता था। –

+1

हो गया। धन्यवाद assylias! –

+0

मुझे लगता है कि विचार कुछ लिखना है: 'बिल्डर बिल्डर = नया मूवबिल्डर()। X (123) .y (456) .टाइम (78 9); yourObject.execute (बिल्डर); ' – assylias

उत्तर

1

मेरे द्वारा की गई reifications: एक धाराप्रवाह बिल्डर और एक कारखाने पद्धति का उपयोग करके।

इस पर अतिरिक्त जानकारी और संबंधित "द्विदिश बिल्डर" के लिए यहाँ देखें: http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html?page=3

मैं निम्नलिखित की तरह कुछ करना होगा; यद्यपि यह संभवतः 3 आवश्यक फ़ील्ड के लिए अधिक है, लेकिन प्रत्येक आवश्यक फ़ील्ड के लिए लेखांकन करते समय बड़ी वस्तुओं का निर्माण करना बहुत उपयोगी होता है।

public Class Space 
{  
    public interface Builder 
    { 
     public Space build(); 
     public int x(); 
     public int y(); 
     public int z(); 
    } 

    // Build a complete Space object accounting for every field. 
    public Space(Space.Builder spaceBuilder) 
    { 
     this.x = spaceBuilder.x(); 
     this.y = spaceBuilder.y(); 
     this.z = spaceBuilder.z(); 
     this.time = builder.time(); 
    } 

    // Might not be necessar if you update time when you update x, y, and z 
    public Builder time(long val) 
    { 
      time = val; 
      return this; 
    } 

    public void move() 
    { 
     // ... 
    } 

    public static void main(String[] args) 
    { 
     new Builder() 
     { 
      @Override 
      public Space build(){ return new Space(this);} 

      @Override 
      public int x(){ return 1;} 

      @Override 
      public int y{ return 1;} 

      @Override int z{ return -1;} 
     }.build().time(1234).move(); 
    } 
} 
2

तरह से है कि मैं इसे देखना, आप अपने बिल्डर वर्ग (एक साथ की तरह) माता-पिता वर्ग के साथ जुड़े होगा और ग्राहकों को इस तरह यह प्रयोग करेंगे:

Space space = new Space(); 
... 
Space.MoveBuilder moveBuilder = space.new MoveBuilder(1, 1, -1); 
moveBuilder.setTime(1234); 
moveBuilder.execute(); 

यह आगे से सरल किया जा सकता है एक अंतरफलक वर्ग मैं का दृष्टांत करना चाहते हैं अंदर परिभाषित निर्माता का उपयोग करके पैटर्न के

space.startMove(1, 1, -1).withTime(1234).endMove(); 
+1

हां, मैं मानता हूं कि एक गैर स्थैतिक वर्ग इसके और बाध्यकारी वर्ग के बीच बाध्यकारी पर जोर देने के लिए बेहतर होगा। –

0

मैं Java Method Invocation Builder कि, संकलन समय पर, बिल्डरों कि तरीकों का आह्वान उत्पन्न बनाया। यह जावा में विधि पैरामीटर पर डिफ़ॉल्ट मानों के लिए समर्थन भी जोड़ता है।

इसका उपयोग कक्षाओं या इंटरफेस पर किया जा सकता है। @GenerateMethodInvocationBuilder और @Default प्रकार के एनोटेशन जोड़कर।

@GenerateMethodInvocationBuilder 
public interface BitBucketServerService { 
@GET("/rest/api/1.0/projects/{projectkey}/repos/{repositoryslug}/pull-requests?direction={direction}&at={at}&state={state}&order={order}&withattributes={withattributes}&withproperties={withproperties}") 
Call<BitbucketServerResponse<BitBucketServerPullRequest>> pullRequests(// 
    @Default("PROJ") @Query("projectkey") String projectKey,// 
    @Default("REPO") @Query("repositoryslug") String repositoryslug,// 
    @Default("INCOMING") @Query("direction") String direction,// 
    @Default("23") @Query("at") String at,// 
    @Default("OPEN") @Query("state") String state,// 
    @Default("NEWEST") @Query("order") String order,// 
    @Default("true") @Query("withattributes") String withattributes,// 
    @Default("true") @Query("withproperties") String withproperties); 
} 

फिर, एक बिल्डर जब कोड संकलित किया गया है उत्पन्न हो जाएगा और आप डिफ़ॉल्ट पैरामीटर के साथ यह आह्वान कर सकते हैं:

BitBucketServerServicePullRequestsBuilder.pullRequests() 
.invoke(bitBucketServerService); 

या सेट आप की तरह किसी भी पैरामीटर:

BitBucketServerServicePullRequestsBuilder.pullRequests() 
.withAt("24") 
.invoke(bitBucketServerService); 

अधिक पर गिटहब: https://github.com/tomasbjerre/java-method-invocation-builder

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

  • कोई संबंधित समस्या नहीं^_^