2015-01-16 4 views
6

मेरे पास "प्रभावी जावा" में शामिल "बिल्डर पैटर्न" से संबंधित एक प्रश्न था। पैटर्न को सही तरीके से कार्यान्वित करने के लिए हमें विधि की आवश्यकता है?क्या हमें बिल्डर पैटर्न में .build() विधि चाहिए?

public class CoffeeDrink { 

    private int numEspressoShots; 
    private short milkType; 
    private boolean withWhip; 

    private CoffeeDrink() { 
    } 

    public static CoffeeDrink buildNewDrink() { 
     return new CoffeeDrink(); 
    } 

    public CoffeeDrink withEspresso(int n) { 
     this.numEspressoShots = n; 
     return this; 
    } 

    public CoffeeDrink withMilkType(shot t) { 
     this.milkType = t; 
     return this; 
    } 

    public CoffeeDrink withWhip() { 
     this.withWhip = true; 
     return this; 
    } 
} 

और फिर हम उसका उपयोग कैसे:

CoffeeDrink c = CoffeeDrink.buildNewDrink() 
         .withEspresso(2) 
         .withMilkType(2) 
         .withWhip(); 

यह अभी भी मान्य है, तो मैं एक स्थिर भीतरी Builder वर्ग की जरूरत नहीं है नहीं होगा उदाहरण के लिए, मान लें कि हम निम्नलिखित वर्ग डालते हैं? मुझे लगता है कि फायदे में से एक यह है कि यह CoffeeDrink ऑब्जेक्ट बनाने से रोकता है जब तक कि विधि .build() को कॉल नहीं किया जाता है, लेकिन मैं अभी भी Builder ऑब्जेक्ट बना रहा हूं। बस कुछ स्पष्टीकरण मांगना।

+1

बिल्डर पैटर्न अपरिवर्तनीय वर्गों के साथ महान लाभ के लिए प्रयोग किया जाता है। उनके साथ, बिल्डर एक उत्परिवर्ती "सहायक" वर्ग है जो अंतिम उत्पाद के अंतिम निर्माण में सहायता करता है जो उसके बाद अपरिवर्तनीय है। आपका उदाहरण केवल एक साधारण POJO है और यह जावाबीन के नुकसान को साझा करता है (उत्परिवर्तनीय, अपूर्ण या असंगत स्थिति में देखा जा सकता है)। – scottb

उत्तर

14

नहीं, यह बिल्डर पैटर्न नहीं है। यह वैध जावा है, और यह संकलित और चलाएगा। लेकिन आपकी buildNewDrink() विधि, चाहे इसे build() या buildNewDrink() या कुछ और कहा जाता है, केवल एक साधारण फैक्टरी विधि है जो CoffeeDrink बनाता है। वे अन्य विधियां सेटर विधियों की तरह हैं जो स्वयं को वापस करने के लिए होती हैं।

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

+0

मैं आपकी टिप्पणियों से सहमत हूं। ये विधियां * चेनिंग * के साथ नियमित सेटर्स प्रतीत होती हैं। बस एक मामूली विस्तार, लेकिन हो सकता है कि आप अपने उत्तर में * "नहीं" * गायब हो जाएं, जैसा कि * "यह सुनिश्चित करने के लिए सत्यापन तर्क कर सकता है कि एक अवैध वस्तु ** ** बनाई गई ** नहीं है" *। – afsantos

+0

@afsantos धन्यवाद; ठीक कर दिया। – rgettman

+0

स्पष्टीकरण के लिए धन्यवाद। तो क्या मैं कॉफीड्रिंक के उदाहरण को वापस करने से पहले बिल्डर क्लास के बिल्डर फ़ंक्शन में सभी पैरामीटर को मान्य करूंगा? – victormejia

1

गोफ संदर्भ के अनुसार, build() आवश्यक नहीं है। मूल संदर्भ चेनिंग का उपयोग नहीं करता है, और Director.construct() विधि के अंत में getResult() चरण है। Director कक्षा बिल्ड प्रक्रिया को समाहित करने का ख्याल रखती है, इसलिए Client को चिंता करने की आवश्यकता नहीं है कि वे सही तरीके से चीजें बना रहे हैं। यह Director की ज़िम्मेदारी है।

यहाँ बिल्डर पर GOF संदर्भ से अनुक्रम आरेख है:

GoF Builder Sequence Diagram

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