2015-06-12 3 views
5

मैं अपरिवर्तनीय User इकाई है:एनीमिक डेटा मॉडल से कैसे बचें? क्या संस्थाओं को भंडारित किया जा सकता है?

public class User { 
    final LocalDate lastPasswordChangeDate; 
    // final id, name, email, etc. 
} 

मैं अगर उपयोगकर्ता का पासवर्ड आई.डी. परिवर्तित किया जाना चाहिए एक तरीका है कि जानकारी वापस आ जाएगी जोड़ने की जरूरत इसे passwordValidIntervalInDays सिस्टम सेटिंग से अधिक के लिए बदला नहीं गया है।

वर्तमान दृष्टिकोण:

public class UserPasswordService { 
    private SettingsRepository settingsRepository; 

    @Inject 
    public UserPasswordService(SettingsRepository settingsRepository) { 
    this.settingsRepository = settingsRepository; 
    } 

    public boolean passwordMustBeChanged(User user) { 
    return user.lastPasswordChangeDate.plusDays(
     settingsRepository.get().passwordValidIntervalInDays 
    ).isBefore(LocalDate.now()); 
    } 
} 

सवाल कैसे उपरोक्त कोड अधिक वस्तु उन्मुख बनाने के लिए और कमजोर डोमेन मॉडल antipattern से बचने के लिए है? यदि ऐसा है तो कैसे SettingsRepository तक पहुँचने के लिए passwordMustBeChanged विधि User के लिए ले जाया जाना चाहिए, यह User के निर्माता में इंजेक्ट किया जाना चाहिए, या एक Settings उदाहरण ctor प्रदान की जानी चाहिए, या passwordMustBeChanged विधि एक Settings उदाहरण से किया जा सकेगा प्रदान किया जाना?

Settings और SettingsRepository का कोड महत्वपूर्ण नहीं है, लेकिन completness के लिए, यहाँ यह है:

public class Settings { 
    int passwordValidIntervalInDays; 
    public Settings(int passwordValidIntervalInDays) { 
    this.passwordValidIntervalInDays = passwordValidIntervalInDays; 
    } 
} 

public class SettingsRepository { 
    public Settings get() { 
    // load the settings from the persistent storage 
    return new Settings(10); 
    } 
} 
+0

मैं http://stackoverflow.com/questions/5694241/ddd-the-rule-that-entities-cant-access-repositories-directly पढ़ सकते हैं और http://stackoverflow.com है/प्रश्न/827670/is-it-ok-for-entities-to-access-repositories लेकिन उनमें से कोई भी मेरे प्रश्न का उत्तर देने लगता है –

+0

[this] (https://blog.inf.ed.ac पर एक नज़र डालें। uk/sapm/2014/02/04/the-anemic-domain-model-is-no-anti-pattern-its-a-solid-design /) –

उत्तर

4

सिस्टम-वाइड पासवर्ड समाप्ति नीति अपने दृष्टिकोण के रूप में अपने UserPasswordService है जब तक कि बुरा नहीं है, के लिए एक डोमेन सेवा, एक आवेदन सेवा नहीं। उपयोगकर्ता के भीतर पासवर्ड समाप्ति नीति को एम्बेड करना एसआरपी आईएमएचओ का उल्लंघन होगा, जो कि बेहतर नहीं है।

PasswordExpirationPolicy policy = passwordExpirationPolicyFactory().createDefault(); 
boolean mustChangePassword = user.passwordMustBeChanged(policy); 


//class User 
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) { 
    return policy.hasExpired(currentDate, this.lastPasswordChangeDate); 
} 

अंततः नीति व्यक्तिगत उपयोगकर्ताओं के लिए निर्दिष्ट किया जा सकता है, तो आप बस User पर नीति वस्तुओं स्टोर कर सकते हैं:

तुम भी तरह कुछ (जहां कारखाना सही सेटिंग्स के साथ प्रारंभ किया गया था) पर विचार कर सकते।

आप अपने वर्तमान डिजाइन के साथ आईएसपी का उपयोग भी कर सकते हैं और इंटरफ़ेस को UserPasswordService सेवा पर कार्यान्वित कर सकते हैं। यह आपको User नीति के साथ कैसे इंटरैक्ट करता है, इसे बदलने के बिना बाद में वास्तविक नीति वस्तुओं में पुन: सक्रिय करने की लचीलापन प्रदान करेगा।

आप एक Password मूल्य वस्तु था, तो आप भी बातें थोड़ा अधिक एकजुट कर सकते हैं, जैसे (पासवर्ड निर्माण तिथि पासवर्ड VO में एम्बेडेड होगा) कुछ होने से:

//class User 
public boolean passwordMustBeChanged(PasswordExpirationPolicy policy) { 
    return this.password.hasExpired(policy); 
} 
+0

धन्यवाद, मैंने चुना है "आपका दृष्टिकोण इतना बुरा नहीं है" समाधान :) –

+1

@AdamSiemion अधिक ओओपी डिज़ाइन के लिए बस अपनी सेवा पर एक पासवर्ड एक्स्पिरेशन पॉलिसी इंटरफ़ेस लागू करें और फिर आप 'user.passwordMustBeChanged (yourDomainSer' कर सकते हैं उपाध्यक्ष) '। यदि आपका डिज़ाइन अंततः बदलता है तो यह कम घर्षण होगा और यह वास्तव में एक बड़ा रिफैक्टर नहीं है। – plalx

+0

विशिष्ट उद्देश्यों के लिए स्पष्ट अनुमान-जैसे VALUE ऑब्जेक्ट बनाएं। एक विनिर्देश एक अनुमान है जो यह निर्धारित करता है कि कोई ऑब्जेक्ट कुछ मानदंडों को पूरा करता है या नहीं करता है। –

1

सिर्फ एक और बाहर निकालने के लिए संभावित समाधान एक लंबी चल रही प्रक्रिया को कार्यान्वित करना होगा जो समाप्ति जांच कर सकता है और पासवर्डएक्सिडहैंडलर को एक कमांड भेज सकता है जो उपयोगकर्ता को समय सीमा समाप्त होने के साथ चिह्नित कर सकता है।

+0

का उल्लेख करता हूं, मैं सिर्फ यह जोड़ना चाहता था कि यह एक ऐसा विकल्प नहीं है जो हमने प्रस्तावित किया है। एक लंबी चल रही प्रक्रिया के साथ भी, आपको नीति की जांच करने के लिए एक साफ तरीका चाहिए। – plalx

+0

@plax सहमत हुए। लंबे समय तक चलने वाली प्रक्रिया के बारे में क्या अच्छा है, आप वर्कफ़्लो के भीतर अन्य प्रकार की चीजें बना सकते हैं, जैसे कि उनका पासवर्ड समाप्त होने के बारे में एक दोस्ताना अनुस्मारक भेजना। – Marco

0

मैं एक दस्तावेज है कि मेरे सवाल का एक जवाब प्रदान करता है पर ठोकर खाई है

DDD को लागू करने में एक आम समस्या है जब एक इकाई के लिए एक को पूरा करने के लिए भंडार या अन्य प्रवेश द्वार में डेटा तक पहुँच की आवश्यकता है व्यापार आपरेशन। एक समाधान सीधे संस्था में भंडार निर्भरता को इंजेक्ट करना है, हालांकि यह अक्सर फहराया जाता है। इसका एक कारण यह है क्योंकि इसे एक अनुप्रयोग निर्भरता ग्राफ का हिस्सा बनने के लिए इकाइयों को लागू करने वाली सादे-पुरानी- (सी #, जावा, आदि ...) की आवश्यकता होती है।एक अन्य कारण यह है कि अकेले जिम्मेदारता सिद्धांत का उल्लंघन होने के कारण संस्थाओं के व्यवहार के बारे में तर्क अधिक कठिन होता है। एक बेहतर समाधान यह है कि एक एप्लिकेशन सेवा किसी इकाई द्वारा आवश्यक जानकारी को पुनर्प्राप्त करती है, प्रभावी रूप से निष्पादन वातावरण को स्थापित करती है, और इसे इकाई को प्रदान करती है।

http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/

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

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