2009-03-04 7 views
12

मैं समझने के लिए संघर्ष कर रहा हूं कि मेरी डीडीडी परियोजना में मेरे कारखाने वर्ग को क्या करना चाहिए। हां वस्तुओं का निर्माण करने के लिए एक कारखाने का उपयोग किया जाना चाहिए, लेकिन यह वास्तव में क्या करना चाहिए। निम्नलिखित फैक्टरी कक्षा पर विचार करें:मेरे डीडीडी कारखाने वर्ग में कौन सी विधियां चलनी चाहिए?

public class ProductFactory 
    { 
     private static IProductRepository _repository; 

     public static Product CreateProduct() 
     { 
      return new Product(); 
     } 

     public static Product CreateProduct() 
     { 
      //What else would go here? 
     } 

     public static Product GetProductById(int productId) 
     { 
      //Should i be making a direct call to the respoitory from here? 
      Greener.Domain.Product.Product p = _repository.GetProductById(productId); 
      return p; 
     } 
    } 

क्या मुझे कारखाने के भीतर से भंडार को सीधी कॉल करनी चाहिए?

डेटाबेस से डेटा को पुनर्प्राप्त करते समय मैं ऑब्जेक्ट निर्माण को कैसे प्रबंधित करना चाहिए?

मुझे इस कक्षा को पूरा करने की क्या ज़रूरत है, मेरे पास अन्य तरीकों का क्या होना चाहिए?

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

कृपया मदद करें!

+1

अपने कारखाने में भंडार तर्क न रखें। – mbillard

उत्तर

0

ऊपर दिए गए उदाहरण में, मैं आपके कारखाने और भंडार के बीच भेद पर थोड़ा अस्पष्ट हूं। मुझे आश्चर्य है कि क्या आपको रिपोजिटरी के लिए एक विधि के रूप में CreateProduct को बस नहीं जोड़ना चाहिए, और रिपॉजिटरी को उस कोड में धक्का देने के लिए DI का उपयोग करना चाहिए, जिसकी आवश्यकता है? यदि कारखाना नहीं है कर कुछ भी, आदि ...

या यदि आपने अभी यह एक विश्व स्तर पर पंजीकृत भंडार के रूप में कार्य करने के लिए, शायद कुछ की तरह हैं:

public static IFooRepository Default {get;private set;} 
public static void SetRepository(IFooRepository repository) { 
    Default = repository; 
} 

(मेरे मन में यह लगता है साफ अलग करने के लिए "सेट" इस मामले में है, लेकिन आप इस बात से सहमत करने के लिए नहीं है)

और कॉल करने वालों var product = YourFactory.Default.CreateProduct(); का उपयोग आदि

1

मैं व्यक्तिगत रूप से हालात की जोड़ी में कारखाने का उपयोग होता है:

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

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

उम्मीद है कि इससे मदद मिलती है।

2

आपके फैक्ट्री की मेक विधि में क्या जाना चाहिए, एक ब्रांड को नई वस्तु को एक वैध स्थिति में डालने के लिए जो भी आवश्यक है।

अब, कुछ वस्तुओं का मतलब है कि आप इस को छोड़कर कुछ भी करेंगे नहीं के लिए:

public Product Create() 
{ 
    return new Product(); 
} 

हालांकि, अगर आप व्यापार के नियम, डिफ़ॉल्ट सेटिंग्स, या अन्य आवश्यकताओं है कि आप लागू करने के लिए एक वस्तु है जब चाहते हो सकता है बनाया था। उस स्थिति में, आप उस विधि में उस तर्क को डाल देंगे।

और यह फैक्ट्री के लाभ का हिस्सा है।अब आपके पास एक और एक ही स्थान है जहां वह विशेष तर्क रहता है, और केवल एक ही स्थान जहां एक नई वस्तु बनाई जाती है।

11

क्या मुझे पर फैक्ट्री के भीतर से रेपॉजिटरी को सीधे कॉल करना चाहिए?

नहीं, अपनी पुनर्प्राप्ति सामग्री के दौरान कारखाने का उपयोग न करें, केवल तभी फैक्ट्री का उपयोग करें जब आप इसे पहली बार बना रहे हों।

डेटाबेस से डेटा को पुनर्प्राप्त करते समय मैं ऑब्जेक्ट निर्माण का प्रबंधन कैसे करना चाहिए?

उस वस्तु को कारखाने में पास करें, यदि यह वस्तु के आरंभिक निर्माण के लिए आवश्यक है।

क्या मैं इस वर्ग पूर्ण, अन्य क्या तरीकों मेरे पास है चाहिए बनाने के लिए की जरूरत है?

कई कारखानों में भी व्यक्तिगत कक्षाएं नहीं हैं, वे केवल विधियां हैं जो वस्तु निर्माण प्रदान करती हैं। यदि आप महसूस करते हैं कि यह पैरामीटर रहित कन्स्ट्रक्टर को कॉल करने जा रहा है, तो आप फैक्ट्री विधि को किसी अन्य वर्ग में फोल्ड कर सकते हैं।

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

भंडार मौजूदा वस्तुओं (एक अर्थ बनाने में) प्राप्त करने के लिए है, फैक्ट्री पहली बार जब आप ऑब्जेक्ट बनाते हैं।

प्रारंभ में कई कारखानों को एक कन्स्ट्रक्टर को छोड़कर बहुत कुछ नहीं किया जाएगा। लेकिन एक बार जब आप बड़े ऑब्जेक्ट पदानुक्रमों को रीफैक्टरिंग और/या बनाना शुरू करते हैं, तो कारखानियां अधिक प्रासंगिक हो जाती हैं।

स्पष्टीकरण और उदाहरण:

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

प्रोसेसर बेस क्लास:

public abstract class ExcelProcessor 
{ 
     public abstract Result Process(string ExcelFile); 
} 

प्रोसेसर उपवर्गों में से एक:

public class CompanyAExcelProcessor : ExcelProcessor 
{ 
    public override Result Process(string ExcelFile) 
    { 
     //cool stuff 
    } 
} 

फैक्टरी:

public static ExcelProcessor CreateExcelProcessor(int CompanyId, int CurrentUserId) 
{ 
     CompanyEnum company = GetCompanyEnum(CompanyId); 
     switch (company) 
     { 
      case CompanyEnum.CompanyA: 
       return new CompanyAExcelProcessor(); 
      case CompanyEnum.CompanyB: 
       return new CompanyBExcelProcessor(); 
      case CompanyEnum.CompanyC: 
       return new CompanyCExcelProcessor(CurrentUserId); 
      //etc... 
     } 
} 

उपयोग: यह और डेटाबेस से यह rehydrating बनाना:

ExcelProcessor processor = CreateExcelProcessor(12, 34); 
processor.Process(); 
6

सावधान रहो, वहाँ एक नई वस्तु का दृष्टांत को दो कारण हैं।

पहला मामला कारखाने द्वारा संभाला जाता है। आप फैक्ट्री पर ऑब्जेक्ट बनाने के लिए कई विधियां प्रदान कर सकते हैं। फैक्टरी विधियों को वैध वस्तुओं को वापस करना चाहिए, ताकि आप आवश्यक जानकारी प्रदान करने के लिए इन तरीकों से पैरामीटर पास कर सकें।

फैक्टरी विधि पैरामीटर के आधार पर तत्काल करने के लिए वास्तविक प्रकार भी चुन सकती है।

आपको डेटाबेस से रीहाइड्रेटिंग के साथ इसे मिश्रण नहीं करना चाहिए। इस प्रकार की तत्कालता को डाटरो से मूल्य लेना चाहिए और वस्तु को इसके साथ तुरंत चालू करना चाहिए। मैं आमतौर पर इसे डेटा निर्माताफैक्टरी के बजाय कॉल करता हूं।

मुख्य अंतर यह है कि कारखाना किसी ऑब्जेक्ट को एक नई पहचान के साथ चालू करेगा जबकि डाटाबेसर किसी ऑब्जेक्ट को पहले से मौजूद पहचान के साथ तुरंत चालू करेगा।

+3

कारखाना सामान्य रूप से डोमेन में है जबकि डेटा निर्माता स्थिरता आधारभूत संरचना में है। – thinkbeforecoding

0

@TinkBeforeCoding - @ m4bwav के उदाहरण में, कारखाने को एक सहायक विधि से वैध आईडी मिल रही है, लेकिन यह कहीं भी एक स्थिरता परत में एक नया रिकॉर्ड नहीं बना रहा है। यदि, हालांकि, मैं अपनी पहचान के रूप में डेटाबेस ऑटो-जनरेटेड पहचान कॉलम का उपयोग कर रहा हूं, ऐसा लगता है कि एक कारखाने को प्रारंभिक ऑब्जेक्ट सृजन करने के लिए भंडार में कॉल करना होगा। क्या आप टिप्पणी कर सकते हैं कि कौन सी विधि "सही" है?

0

बिल्डर आप किसी भी तर्क आप एक छोटे से उदाहरण जावा विकास भाषा के रूप में उपयोग करते हुए अपने entites पर अपरिवर्तनशीलताओं चालू करने की जरूरत है सकते हैं ...

मैं एक उपयोगकर्ता नाम, पासवर्ड और है कि एक उपयोगकर्ता इकाई है एक ई-मेल, आवश्यक सभी विशेषताओं तो मेरे पास है:

public class User { 

private String username; 
private String password; 
private String email: 

/** 
* @throws IllegalArgumentException if the username is null, the password is null or the 
* email is null. 
*/ 
public User(final String theUsername, final String thePassword, final String theEmail) { 
Validate.notNull(theUsername); 
Validate.notNull(thePassword); 
Validate.notNull(theEmail); 

this.username = theUsername; 
this.password = thePassword; 
this.email = theEmail; 
} 

// Getters/Setters/equal/hashCode/toString 
} 

और फिर मैं UserBuilder है:

public class UserBuilder { 
private String username; 
private String password; 
private String email; 

public UserBuilder withUsername(final String theUsername) { 
Validate.notNull(theUsername); 

this.username = theUsername; 

return this; 
} 

public UserBuilder withPassword(final String thePassword) { 
Validate.notNull(thePassword); 

this.password = thePassword; 

return this; 
} 

public UserBuilder withEmail(final String theEmail) { 
Validate.notNull(theEmail); 

this.email = theEmail; 

return this; 
} 

public User build() { 
User user = new User(this.username, this.password, this.email); 

return user; 
} 
}; 

और तुम इस तरह बिल्डर उपयोग कर सकते हैं :

UserBuilder builder = new UserBuilder(); 

try { 
User user = builder.withUsername("pmviva").withPassword("My Nifty Password").withEmail("[email protected]").build(); 
} catch (IllegalArgument exception) { 
    // Tried to create the user with invalid arguments 
} 

कारखाने का एकमात्र उद्देश्य व वस्तुओं के वैध उदाहरण बनाते हैं। सृजन और हाइड्रेशन कोड को डुप्लिकेट न करने के लिए आप डेटाबेस से एक रोसेट पूछने के लिए अपने भंडार प्राप्त कर सकते हैं और ऑब्जेक्ट के निर्माण को रोसेट के डेटा को पार करने वाले निर्माता को सौंप सकते हैं।

आशा इस मदद करता है

धन्यवाद पाब्लो