2012-06-07 15 views
12

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

विशेष रूप से, मैं गूगल मैप्स वेब सेवा एपीआई, सामान्य वेब सेवा अनुरोध

http://maps.googleapis.com/maps/api/service/output?{parameters} 

service और output अनिवार्य तर्क हैं, और sensor एक अनिवार्य पैरामीटर के रूप में है कि के लिए डिजाइनिंग हूँ। एक वैकल्पिक पैरामीटर language भी है।

प्रत्येक सेवा में अनिवार्य और वैकल्पिक पैरामीटर का सेट होता है। जियोकोड सेवा में दो वैकल्पिक पैरामीटर होते हैं, bounds और region। इसमें परस्पर अनन्य अनिवार्य पैरामीटर भी हैं, address या location, जो सेवा के प्रकार (क्रमशः प्रत्यक्ष या रिवर्स जियोकोडिंग) निर्दिष्ट करते हैं। मैं नए बच्चों के वर्गों के साथ इस पारस्परिक बहिष्कार का प्रतिनिधित्व करता हूं।

मैं जैसे वर्ग पदानुक्रम की कल्पना:

.-----. 
    | Url | 
    '-----' 
    ^
    | 
.---------. 
| Request | 
'---------' 
    ^
    |----------------------------+--------------... 
.---------.     .------------. 
| Geocode |     | Directions | 
'---------'     '------------' 
    ^      ^
    |------------+    . 
.--------. .---------.   . 
| Direct | | Reverse |   . 
'--------' '---------' 

फिर, मैं की तरह कुछ करना चाहते हैं निम्नलिखित:

String output = "xml"; 
boolean sensor = true; 
String address = "Av. Paulista, São Paulo, Brasil"; 
Bounds bounds = new Bounds(-20, -10, -25, -20); //Geographic rectangle 
String region = "br"; 
String lang = "pt-BR"; 
Coord location = new Coord(-12,-22); 

DirectGeocodeRequestUrl direct = 
    new DirectGeocodeRequestUrl.Builder(output, sensor, address) 
           .bounds(bounds) 
           .language(lang) 
           .build(); 

ReverseGeocodeRequestUrl reverse = 
    new ReverseGeocodeRequestUrl.Builder(output, sensor, location) 
           .language(lang) 
           .region(region) 
           .build(); 

मैं एक बिल्डर से तर्क और तरीकों का उपयोग करता है बना सकते हैं कैसे कक्षा और सुपरक्लास जिसमें इसे डाला जाता है?

उत्तर

17

मैं https://stackoverflow.com/a/9138629/946814 पर अपना उत्तर बना रहा हूं, लेकिन इस बहु-स्तर पदानुक्रम पर विचार कर रहा हूं।

बिल्डर आंतरिक कक्षाओं के साथ समान पदानुक्रम को दोहराने के लिए हमें क्या चाहिए। चूंकि हम विधि श्रृंखला चाहते हैं, हमें getThis() विधि की आवश्यकता है जो पदानुक्रम के पत्ते की वस्तु को वापस कर दे। अपने प्रकार के ऊपर पदानुक्रम को पारित करने के लिए, अभिभावक वर्गों में एक सामान्य T होता है, और पत्ता T को स्वयं से बांधता है।

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

RequestUrl:

public abstract class RequestUrl{ 
    public static abstract class Builder<T extends Builder<T>>{ 
     protected String output; 
     protected boolean sensor; 
     //Optional parameters can have default values 
     protected String lang = "en"; 

     public Builder(String output, boolean sensor){ 
      this.output = output; 
      this.sensor = sensor; 
     } 

     public T lang(String lang){ 
      this.lang = lang; 
      return getThis(); 
     } 

     public abstract T getThis(); 
    } 

    final private String output; 
    final private boolean sensor; 
    final private String lang; 

    protected RequestUrl(Builder builder){ 
     this.output = builder.output; 
     this.sensor = builder.sensor; 
     this.lang = builder.lang; 
    } 

    // other logic... 
} 

GeocodeRequestUrl:

public abstract class GeocodeRequestUrl extends RequestUrl { 
    public static abstract class Builder<T extends Builder<T>> 
     extends RequestUrl.Builder<Builder<T>>{ 

     protected Bounds bounds; 
     protected String region = "us"; 

     public Builder(String output, boolean sensor){ 
      super(output, sensor); 
     } 

     public T bounds(Bounds bounds){ 
      this.bounds = bounds; 
      return getThis(); 
     } 

     public T region(String region){ 
      this.region = region; 
      return getThis(); 
     } 

     @Override 
     public abstract T getThis(); 
    } 

    final private Bounds bounds; 
    final private String region; 

    protected GeocodeRequestUrl(Builder builder){ 
     super (builder); 
     this.bounds = builder.bounds; 
     this.region = builder.region; 
    } 

    // other logic... 
} 

DirectGeocodeRequestUrl:

public class DirectGeocodeRequestUrl extends GeocodeRequestUrl { 
    public static class Builder<Builder> 
     extends GeocodeRequestUrl.Builder<Builder>{ 

     protected String address; 

     public Builder(String output, boolean sensor, String address){ 
      super(output, sensor); 
      this.address = address; 
     } 

     @Override 
     public Builder getThis(){ 
      return this; 
     } 

     public DirectGeocodeRequestUrl build(){ 
      return new DirectGeocodeRequestUrl(this); 
     } 
    } 

    final private String address; 

    protected DirectGeocodeRequestUrl(Builder builder){ 
     super (builder); 
     this.address = builder.address; 
    } 

    // other logic... 
} 

ReverseGeocodeRequestUrl:

public class ReverseGeocodeRequestUrl extends GeocodeRequestUrl { 
    public static class Builder<Builder> 
     extends GeocodeRequestUrl.Builder<Builder>{ 

     protected Coord location; 

     public Builder(String output, boolean sensor, Coord location){ 
      super(output, sensor); 
      this.location = location; 
     } 

     @Override 
     public Builder getThis(){ 
      return this; 
     } 

     public ReverseGeocodeRequestUrl build(){ 
      return new ReverseGeocodeRequestUrl(this); 
     } 
    } 

    final private Coord location; 

    protected ReverseGeocodeRequestUrl(Builder builder){ 
     super (builder); 
     this.location = builder.location; 
    } 

    // other logic... 
} 
+0

ठोस वर्गों में 'getThis()' के ओवरराइड कार्यान्वयन को सार नहीं होना चाहिए। – Eric

+0

@EricTobias आप सही हैं, कॉपी-पेस्ट का खतरा है। फिक्स्ड। –

+1

यह आश्चर्यजनक है! ठीक वही जो मेरे द्वारा खोजा जा रहा था! – Maddy

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