2010-11-24 13 views
7

मैं सोच रहा हूं कि मुझे वास्तव में सेवा परत की आवश्यकता है या नहीं।जावा स्विंग एप्लिकेशन में सेवा परत

मैं डेस्कटॉप स्विंग एप्लिकेशन के लिए वसंत + हाइबरनेट का उपयोग कर रहा हूं और इस समय मेरे पास गुई/स्विंग परत-> सेवा परत-> दाओ परत है। मैं वसंत का उपयोग केवल @ ट्रांसेक्शन समर्थन के लिए और आईओसी-इंजेक्शन

सर्वोत्तम अभ्यास कहता है कि मुझे अपने दास का उपयोग करने के लिए एक सेवा लिखनी है, और सेवा में सभी लेनदेन प्रबंधन रखना है।

लेकिन मैं साकार कर रहा हूँ कि बहुत बहुत बार, सेवा परत केवल दाव तरीकों को दोहराने, उदाहरण के लिए इतना:

// a DAO example 
@Repository 
public class CustomerHibernateDAO extends BaseHibernateDAO implements CustomerDAO { 

public List<Customer> findAllCustomerILikeName(String name){ 
    return getSession() 
    .createCriteria(Customer.class) 
    .add(Restriction.ilike("name", name)) 
    .list(); 
} 
} 

// Customer service to use this dao... 
@Service 
@Transactional 
public class CustomerService { 

@Autowired 
CustomerDAO customerDAO; 

// Why i can't call DAO instead the service? 
public List<Customer> getAllCustomersByName(String name){ 
     return customerDAO.findAllCustomerILikeName(name); 
} 

} 

यह सेवा परत की एक खदान tipical उपयोग है ... हाइबरनेट db-नास्तिक है, वसंत टेक्नोलॉजी-अज्ञेयवादी हैं: तो, मुझे वास्तव में इसकी आवश्यकता है?

सभी डीएओ का प्रबंधन करने के लिए एक अद्वितीय सेवा वर्ग के बारे में क्या ?? मुझे लगता है कि यह एक अच्छा समझौता हो सकता है, या, एक बुरा अभ्यास है?

मैं जानता हूँ कि डीएओ पर @Transactional डाल एक बुरा तरीका है, लेकिन इस समय मैं केवल उस पर @Transactional डाल के लिए सेवाएं लिखने के लिए ...

संपादित

अधिक के बारे में infos है मेरी एप्लिकेशन।

मेरा आवेदन एक प्रबंधन सॉफ्टवेयर है और उपयोगकर्ता पंजीकरण, उत्पाद, आदेश और अन्य चीजों को प्रबंधित करता है। प्रैक्टिस में इसमें बहुत सी पढ़ी गई इकाई-> संपादित करें-> इकाई को सहेजें या बनाएं-> संपादित करें-> ऑपरेशन सहेजें, और, हाइबरनेट के लिए धन्यवाद, इन परिचालनों को अधिकांश समय में एक दाओ द्वारा प्रबंधित किया जाता है, क्योंकि @manyto के साथ हाइबरनेट ... संग्रह और cascade.save_update एक ही लगातार संचालन में दो या दो से अधिक इकाइयों को बचाने के लिए अनुमति देता है।

तो, उदाहरण के लिए, मेरे आइटम में JFrame मैं जहां सम्मिलित कर सकते हैं, संपादित करें या किसी आइटम को बनाने (बेचने के लिए एक उत्पाद) देखते हैं:

public ItemFrame(){ 
// the constructor 
itemService=springAppContext.getBeans(ItemService.class); 
} 

public boolean validateForm(){ 
// test if the gui is correctly filled by user 
} 

public boolean save(){ 
// create an Item entity taking value from swing gui(JTextField etc) 
Item item=new Item(); 
item.setName(nameTextField.getText()); 
item.setEtc... 
// ItemService ' save method is a wrap around itemDao.save(item)... 
itemService.save(item); 
} 

private void saveItemActionPerformed(ActionEvent evt){ 
// When i press SAVE button 
if(validateForm()){ 
    save(); 
} 
} 

यह मैं क्या अधिकांश मामलों में है, तो मुझे लगता है कि मैं एनीमिक-डोमेन-एंटीपाटरर्न में गिर गया ...

धन्यवाद।

+0

मेरे हिसाब के लिए इस्तेमाल आप कर रहे हैं किया जा रहा है की अनुमति देता है पर विचार correctly.Services entity.It Wil प्रति होना चाहिए मैं मानक पैटर्न बनाए रखता हूं + यदि डीबी में बदलाव आता है तो आप डीएओ परत, + 1 बीटीडब्ल्यू –

+0

का निर्माण कर रहे हैं यदि डीबी में बदलाव आता है और मैंने सेवाओं का उपयोग नहीं किया है, तो समस्या क्या है? मैं सिर्फ अपने डीएओ का पुनर्निर्माण करूंगा और सब ठीक है ... या नहीं? – blow

+0

मुझे यहां थोड़ा सा विषय मिल रहा है, लेकिन आइटमफ्रेम कन्स्ट्रक्टर में कंटेनर से बीन प्राप्त करने का क्या कारण है? मैं कंटेनर द्वारा बीन इंजेक्शन प्राप्त करने के इस दृष्टिकोण के किसी भी लाभ को नहीं देख सकता। – prasopes

उत्तर

3

आपकी सेवा परत डुप्लिकेट तो दाव, आप बिल्कुल सेवा परत का उपयोग नहीं कर रहे हैं। मैंने अपने कुछ अनुप्रयोगों में भी यही गलती की, मैं सोच रहा था कि "सेवा परत इतनी बदसूरत क्यों दिखती है, और डुप्लिकेशंस डीएओ है" ...

सेवा परत आपके appliacation के लिए इंटरफेस होना चाहिए, यह मतलब मतलब है कि दाओ और सेवा में कुछ विधियां समान नहीं हैं, लेकिन मुख्य भाग काफी अलग है। मैं इसे आपके बाकी कोड को देखे बिना नहीं कह सकता, लेकिन आपके प्रश्न से (जो लगभग कुछ महीने पहले मेरे प्रश्न थे), ऐसा लगता है कि आप anemic domain model antipattern का उपयोग कर रहे हैं। एनीमिक डोमेन मॉडल में, आपके मॉडल में केवल फ़ील्ड और गेटर्स, कोई असली विधि (व्यवहार) नहीं है, जो मौलिक ऑब्जेक्ट उन्मुख सिद्धांतों (ऑब्जेक्ट == डेटा + व्यवहार) का उल्लंघन करता है ... आपका व्यवहार संभवतया ऐसा कुछ है जो सेवा में लेनदेन स्क्रिप्ट जैसा दिखता है परत, लेकिन आपके मॉडल (डोमेन परत) में होना चाहिए।

इसका तरीका समृद्ध डोमेन मॉडल (बीन्स को @ कॉन्फिगर करने योग्य के माध्यम से मॉडल में इंजेक्शन) का उपयोग करना है। आप कह सकते हैं, कि यह परत पैटर्न का उल्लंघन करता है और आप शायद सही होंगे। लेकिन मुझे आश्वस्त है कि हमें एक ही घटक के रूप में हमारे आवेदन (डोमेन + दाओ + सेवा) के बारे में सोचना चाहिए (एलिस्टेयर कॉकबर्न Hexagonal architecture/Ports and adapters देखें)।

आपका स्विंग ऐप/वेब क्लाइंट तब आपके मूल घटक के लिए क्लाइंट होगा, फिर आप उन्हें बिना किसी सीमा के स्विच कर सकते हैं (सभी चीजों को मॉडिफ़ीज़ डेटा कोर में छोड़ दें)।

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

मुझे आशा है कि मैंने आपके आर्किटेक्चर का अनुमान लगाया है, यदि नहीं, तो मुझे यहां पहिया का आविष्कार करने के लिए खेद है, लेकिन यह पोस्ट किसी ऐसे व्यक्ति की मदद कर सकती है जो इसे नहीं जानता (जैसा कि मैंने पहले कुछ पतंगों को देखा था)।

संपादित

अपने संपादित करने के लिए

: यहां तक ​​कि साधारण CRUD आवेदन में, कार्रवाई के कुछ प्रकार के सेवा परत में होना चाहिए - उदाहरण के सत्यापन (नहीं सत्यापन "यह एक संख्या है", लेकिन कुछ व्यापार विशिष्ट सत्यापन के लिए)। यह आपके विचार में होना चाहिए, क्योंकि यदि आप इसे बदलते हैं, तो आपके पास प्रतिलिपि & प्रतिलिपि होगी। जब आप अपना कोड देखते हैं, तो आपको एक क्यूस्टिंग से पूछना चाहिए "अगर मैं पतली ग्राहक (वेब ​​ब्राउजर में देखें) लिखने का फैसला करता हूं, तो क्या कोई कोड है, मुझे कॉपी करना होगा? यदि उत्तर हाँ है, तो आपको इस संभावित रिमोट कॉल के लिए एक सेवा विधि बनाना चाहिए।

सेवा परत पर आपको जो करना चाहिए/कर सकता है वह अन्य चीज है (इस भूमिका में उपयोगकर्ता इस प्रविष्टि को हटाने की अनुमति देता है)। आपके पास लगभग सभी इकाइयों के लिए एक सेवा परत होनी चाहिए, क्योंकि सरल उपयोगकर्ता अपनी प्रविष्टियों को संपादित (हटाएं) करने में सक्षम होना चाहिए, लेकिन शायद अन्य उपयोगकर्ताओं को हटा नहीं देना चाहिए। लेकिन भूमिका में उपयोगकर्ता व्यवस्थापक यह कर सकते हैं।

उदाहरण कोड (मेरे एप्लिकेशन में लेख सेवा इंटरफ़ेस का हिस्सा (स्प्रिंग सुरक्षा)):

@Secured("ROLE_EDITOR") 
public void save(ArticleDTO selectedArticle, ArticleDetailsDTO selectedArticleDetails); 

टिप्पणी में सेवा हर कोई लेख के लिए उनकी टिप्पणी को बचा सकता है ....

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

ui -> service -> DAO 

लागू करने के :-)

+0

आपको बहुत उपयोगी धन्यवाद, मैं अपनी पहली पोस्ट में और जानकारी जोड़ता हूं, कृपया इसके बारे में एक टिप्पणी छोड़ दें! धन्यवाद! – blow

+0

मेरी इकाइयों में केवल गेटर और सेटर होता है, लेकिन मेरे दास में सीआरयूडी की तुलना में अधिक विधि होती है, इसलिए वे वास्तविक भंडार (डीडीडी के अनुसार, संचालित डोमिनिन डिजाइन के अनुसार) होते हैं। जब मैं इकाई लिखता हूं तो मैं हमेशा ओओ तरीके से सोचने की कोशिश करता हूं। तो मेरे पास एनीमिक और डोमेन मॉडल का मिश्रण है। – blow

+0

ग्रेट लिंक, मुझे पता नहीं था कि फाउलर के पास इस पर एक लेख था। – prasopes

0

आखिरकार, आपको कई डीएओ के बीच व्यवहार समन्वय करने की आवश्यकता होगी। आप अपने व्यावसायिक नियमों में कुछ जटिलता भी पेश कर सकते हैं (उदा: [यह] अपडेट न करें, अगर [वह] किसी विशेष स्थिति में है)। यह वह जगह है जहां सेवा परत काम में आती है।

उस ने कहा, सेवा तकनीक को पूरी तरह समाप्त करने के साथ "तकनीकी रूप से" कुछ भी गलत नहीं है। जब आप अंततः निर्णय लेते हैं कि आपको एक की आवश्यकता है तो यह थोड़ा और दर्दनाक होगा।

1

किसी बिंदु पर, आपका आवेदन कुछ व्यावसायिक तर्क चाहते हैं। साथ ही, आप यह सुनिश्चित करने के लिए इनपुट को मान्य करना चाहेंगे कि कुछ बुरा या गैर-प्रदर्शनकारी अनुरोध नहीं किया जा रहा है। यह तर्क आपकी सेवा परत में है।

इसके अलावा, आपके डीएओ को काफी सामान्य बनाना संभव हो सकता है, ताकि आपके पास केवल एक या दो विधियां हों जो अधिक नहीं बदले। यह हर बार जब आप ऐप की कार्यक्षमता को जोड़ना/बदलना चाहते हैं तो अपने डीएओ कक्षाओं में कुछ गलत करने का जोखिम कम कर देता है।

डीएओ एक्सेस डेटा के लिए है। सेवा व्यापार तर्क के लिए है। उन्हें अलग रखें और आप लंबे समय तक खुश रहेंगे।

0

यह बिना रह सकते हैं यह सब इस चीज क्या करना चाहते हैं न तो हर ऑपरेशन के लिए, दोनों

ui -> DAO 
ui -> service -> DAO 

बाद और अधिक जटिल आपरेशनों

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