क्या व्यावसायिक तर्क के लिए यह संभव है कि दृश्य में रेंगना न हो?


31

मैंने पिछले 3 वर्षों के लिए कई वेब एप्लिकेशन परियोजनाओं के लिए विकसित किया है, दोनों व्यक्तिगत और काम पर, और मुझे यह पता नहीं लग सकता है कि क्या कम से कम कुछ व्यावसायिक तर्क के लिए यह संभव है कि आवेदन की दृश्य परत में समाप्त न हो।

ज्यादातर मामलों में ऐसी समस्याएं होंगी "यदि उपयोगकर्ता ने विकल्प x का चयन किया है, तो एप्लिकेशन को उसे y के लिए जानकारी की आपूर्ति करने में सक्षम करना चाहिए, यदि नहीं तो उसे जानकारी z की आपूर्ति करनी चाहिए"। या कुछ AJAX ऑपरेशन करें जो मॉडल में कुछ बदलाव लागू करें लेकिन जब तक उपयोगकर्ता ने स्पष्ट रूप से अनुरोध नहीं किया है, तब तक उन्हें लागू न करें। ये मेरे द्वारा सामना की गई कुछ सरल समस्याएं हैं और मैं यह पता नहीं लगा सकता कि दृश्य में जटिल तर्क से बचना कैसे संभव है।

ज्यादातर किताबें जो मैंने एमवीसी का वर्णन करते हुए पढ़ी हैं, आमतौर पर कुछ बहुत ही तुच्छ उदाहरण दिखाती हैं, जैसे कि सीआरयूडी ऑपरेशन जो सर्वर पर डेटा को अपडेट करते हैं और उन्हें प्रदर्शित करते हैं, लेकिन सीआरयूडी अधिकांश समृद्ध अनुप्रयोगों पर ऐसा नहीं है।

क्या यह संभव है कि किसी भी व्यावसायिक तर्क के साथ कोई विचार न हो?


2
MVC व्युत्पन्न MVP और MVVM ( en.wikipedia.org/wiki/Model_View_Presenter और en.wikipedia.org/wiki/Model_View_ViewMenel ) पर एक नज़र डालें , वे वही हो सकते हैं जो आप देख रहे हैं।
डॉक ब्राउन

संबंधित (संभवतः एक डुप्लिकेट): उपयोगकर्ता इंटरफ़ेस से कक्षाएं
काटना

2
दृश्य आपके डेटा और तर्क की बाहरी, दृश्यमान अभिव्यक्ति है। व्यावसायिक तर्क प्रस्तुत करना दृश्य के लिए संभव नहीं है। या आप कह रहे हैं कि दृश्य में कोई कोड नहीं होना चाहिए? आप निश्चित रूप से HTML- केवल विचार बना सकते हैं।
बोबडलिंगिश

आप टेम्पलेट एनीमेशन में देख सकते हैं ; हालांकि यह संभवतः दृश्य परत से सभी तर्क को नहीं मिटाएगा , ऐसा लगता है कि इससे चीजों को थोड़ा अलग करना चाहिए।
पौल

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

जवाबों:


22

क्या यह संभव है कि किसी भी व्यावसायिक तर्क के साथ कोई विचार न हो?

मुझे यह उत्तर देने के लिए एक भ्रामक कठिन प्रश्न लगता है। (सोचा-समझा सवाल!)

सैद्धांतिक रूप से, हाँ, इस बात पर निर्भर करता है कि हम व्यावसायिक तर्क के रूप में क्या परिभाषित करते हैं। व्यवहार में, सख्त अलगाव बहुत कठिन हो जाता है, और शायद अवांछनीय भी।

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

लेकिन, जैसा कि सभी चीजों के साथ होता है, ट्रेड-ऑफ होते हैं। सर्वश्रेष्ठ वैचारिक स्थान अन्य कारणों से सर्वश्रेष्ठ स्थान नहीं हो सकता है। हो सकता है कि आपके वेब सर्वर पर बहुत अधिक लोड है, इसलिए आप अपने सर्वर को हिट करने से पहले आसान इनपुट त्रुटियों को पकड़ने के लिए अपने वेब पेजों में कुछ जावास्क्रिप्ट जोड़ते हैं; अब आपके पास अपने दृष्टिकोण में कुछ व्यावसायिक तर्क हैं।

अपने आप पर, व्यापार तर्क के बिना इसका कोई मूल्य नहीं है। और स्पष्ट रूप से या स्पष्ट रूप से उपयोग और प्रदर्शन में प्रभावी होने के लिए, दृश्य को इसके पीछे चल रही व्यावसायिक प्रक्रियाओं का कुछ ज्ञान होगा। हम उस ज्ञान की मात्रा को सीमित कर सकते हैं, और हम इसके कुछ हिस्सों को बंद कर सकते हैं, लेकिन व्यावहारिक विचार अक्सर हमें चिंताओं को अलग करने के लिए बाध्य करेंगे।


2
The best conceptual location may not be the best location for other reasons: वाहवाही!!
मैग्नो सी

8

मैं आमतौर पर ऐसा करता हूं: यदि उपयोगकर्ता ने विकल्प x चुना है, तो दृश्य कॉल करता है

controller->OptionXChanged()

फिर नियंत्रक दृश्य पर y सक्षम करें:

view->SetEnableInfoY(True) // suppose False=SetDisable

दृश्य कुछ भी तय किए बिना क्या होता है के नियंत्रक को सूचित करता है।


+1। ओपी की तुच्छ समस्याओं को आमतौर पर इस तरह से संभाला जा सकता है
निंदनीय

इस तर्क को नियंत्रक में रखने से दो समस्याएं होती हैं: 1) यह इकाई परीक्षण को जटिल बनाता है, और एक ही डेटा के कई विचारों का समर्थन करना असंभव है।
केविन क्लाइन

4

मैं सवाल करता हूं कि क्या आपके द्वारा वर्णित उदाहरण वास्तव में व्यावसायिक तर्क हैं। आपके द्वारा वर्णित उदाहरण ऐसे ऑपरेशन हैं जो सिस्टम पर किए जा सकते हैं। यह है कि आपने उपयोगकर्ता को पसंद पेश करने के लिए कैसे चुना है कि शायद यह आभास देता है कि आप दृश्य में व्यापार तर्क कर रहे हैं।

"व्यू" सहूलियत बिंदु से यह केवल सिस्टम को InfoY या InfoZ प्रदान कर रहा है। सिर्फ इसलिए कि आपका UI कार्यान्वयन ऑपरेटर की पसंद के आधार पर कुछ गतिशील अपडेट कर रहा है (जैसे कि InfoY या InfoZ को सक्षम करना) कार्यक्षमता को व्यावसायिक तर्क नहीं बनाता है। यह वास्तव में कार्यान्वयन तर्क है। आप बहुत अच्छी तरह से बस ऑपरेटर को पूरी सक्षम बात के बिना InfoY या InfoZ दर्ज करने का विकल्प दे सकते हैं। उस संदर्भ में, क्या आप अभी भी इसे व्यावसायिक तर्क मानेंगे? यदि नहीं, तो सूचना क्षेत्रों को गतिशील रूप से सक्षम / अक्षम करने के लिए भी यही लागू होता है।

एक ही उदाहरण के लिए जाता है। ये 2 अलग-अलग ऑपरेशन हैं जिन्हें सिस्टम को ठीक से काम करने की आवश्यकता होती है। आपका दृश्य वांछित कार्यक्षमता करने के लिए उचित कार्यों को आरंभ करने में सक्षम होना चाहिए। क्या आपके सिस्टम का उपयोग करने का तरीका जानने का मतलब है कि व्यापार तर्क के माध्यम से लीक हो रहा है? मैं देख सकता हूं कि कोई व्यक्ति हां कैसे कह सकता है लेकिन अगर आप उस तरह से विश्वास करते हैं तो वास्तविकता यह है कि किसी भी चीज से व्यापारिक तर्क को अलग करने जैसी कोई बात नहीं है। आपको यह जानना होगा कि कुछ भी सार्थक करने के लिए सिस्टम क्या कर रहा है / काम कर रहा है। अन्यथा, यह एकल जेनेरिक व्यू और कंट्रोलर बनाने के लिए एक हवा होगी जो हर कल्पनीय एमवीसी एप्लिकेशन के साथ काम करता है। जिसे हम जानते हैं वह असंभव है।

नीचे पंक्ति, मुझे लगता है कि आपके व्यापार तर्क की परिभाषा दूसरों की परिभाषा के समान नहीं है।


1

मैं इस तरह से काम करता हूं (Struts2 + Hibernate):

मेरा स्ट्रट्स एक्ट केवल वेब ब्राउजर पर शो के लिए जिम्मेदार है। नहीं सोच रहा है।

उपयोगकर्ता -> कार्रवाई -> सेवा -> भंडार -> डेटा एक्सेस

या:

मैं चाहता हूं कि देखें -> कैसे देखें -> क्या करें -> कैसे प्राप्त करें -> कहां से प्राप्त करें

इसलिए, पहली परत में (दृश्य) मेरे पास कुछ ऐसा है:

public String execute ()   {
    try {
        CourseService cs = new CourseService();
        Course course = cs.getCourse(idCourse);
    } catch (NotFoundException e) {
        setMessageText("Course not found.");
    } catch (Exception e) {

    }
    return "ok";
}

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

इसलिए, यदि मैं अपनी सेवाएँ, रिपॉजिटरी और DAOS विभिन्न पुस्तकालयों में रखता हूँ, तो मैं इसका उपयोग पाठ-आधारित कार्यक्रम या विंडो आधारित डेस्कटॉप सिस्टम में भी कर सकता हूँ, जिसमें कुछ भी नहीं बदल सकता है।

सेवा जानता है कि क्या करना है, लेकिन पता नहीं है कि कैसे दिखाना है। दृश्य दिखाता है कि कैसे दिखाना है, लेकिन यह नहीं जानता कि क्या करना है। सेवा / रिपॉजिटरी के साथ समान: सेवा डेटा के लिए भेजती है और अनुरोध करती है, लेकिन यह नहीं जानती है कि डेटा कहां है और इसे कैसे लेना है। भंडार वस्तुओं को खरीदने के लिए कच्चे डेटा को "मेक अप" करता है ताकि सेवा के साथ काम कर सके।

लेकिन रिपॉजिटरी को डेटाबेस के बारे में कुछ भी पता नहीं है। डेटाबेस प्रकार (MySQL, PostgreSQL, ...) DAO की चिंता करता है।

यदि आप डेटाबेस को बदलना चाहते हैं तो आप DAO को बदल सकते हैं और ऊपरी परतों को प्रभावित नहीं करना चाहिए। यदि आप अपने डेटा प्रबंधन को अद्यतन करना चाहते हैं, तो आप रिपॉजिटरी को बदल सकते हैं, लेकिन यह DAO और ऊपरी परतों को प्रभावित नहीं करना चाहिए। यदि आप अपना तर्क बदलना चाहते हैं, तो आप सेवाओं को बदल सकते हैं, लेकिन इसके लिए ऊपर या नीचे की परतों में गड़बड़ नहीं करनी चाहिए।

और आप कुछ भी देखने में बदल सकते हैं, यहां तक ​​कि प्रौद्योगिकी (वेब, डेस्कटॉप, पाठ) लेकिन इसका मतलब यह नहीं है कि नीचे कुछ भी स्पर्श किया जाना चाहिए।

व्यापार तर्क सेवा है। लेकिन यह देखने के लिए कैसे बातचीत करनी है। अब क्या बटन दिखायें? क्या उपयोगकर्ता इस लिंक को देख सकता है? सोचें कि आपका सिस्टम एक कंसोल-आधारित प्रोग्राम है: आपको इस बात से इनकार करना होगा कि क्या गलत उपयोगकर्ता #> myprogram -CourseService -option=getCourse -idCourse=234इस कमांड को लिखने के लिए कुंजी दबाने के लिए उसे चुनते हैं या रोकते हैं?

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

                <div id="userDetailSubBox">
                    <c:forEach var="actionButton" items="${actionButtons}" varStatus="id">
                        ${actionButton.buttonCode}
                    </c:forEach>
                </div>

तथा

private List<ActionButton> actionButtons;

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


1

ज्यादातर मामलों में समस्याएँ होंगी जैसे "यदि उपयोगकर्ता ने विकल्प x का चयन किया है, तो एप्लिकेशन को उसे y के लिए जानकारी की आपूर्ति करने में सक्षम करना चाहिए, यदि नहीं तो s / उसे जानकारी z की आपूर्ति करनी चाहिए"

यह मॉडल के लिए तर्क है, दृश्य नहीं। यह "व्यू-मॉडल" हो सकता है, विशेष रूप से UI का समर्थन करने के लिए बनाया गया है, लेकिन यह अभी भी मॉडल तर्क है। नियंत्रण अनुक्रम है:

  • नियंत्रक घटनाओं को देखने के लिए एक हैंडलर संलग्न करता है
  • देखें मॉडल की घटनाओं के लिए एक हैंडलर संलग्न करता है
  • उपयोगकर्ता विकल्प X का चयन करता है।
  • दृश्य एक घटना को बढ़ाता है "विकल्प एक्स चयनित"
  • नियंत्रक ईवेंट प्राप्त करता है और model.selectOptionX () कहता है
  • मॉडल एक घटना उठाता है "मॉडल स्थिति बदल गई"
  • दृश्य मॉडल परिवर्तित घटना को प्राप्त करता है और नए राज्य से मिलान करने के लिए दृश्य को अपडेट करता है: inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());

UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------| यह क्लासिक एमवीसी पैटर्न है। यूआई से अलग मॉडल लॉजिक का पूरी तरह से परीक्षण करना संभव है। नियंत्रक और दृश्य बहुत पतले और परीक्षण में आसान हैं।

=== डंक के जवाब में ===

एक यूआई MVC पैटर्न में मॉडल है (आमतौर पर) नहीं एक व्यापार ऑब्जेक्ट मॉडल। यह यूआई राज्य के लिए सिर्फ मॉडल है। एक डेस्कटॉप एप्लिकेशन में, यह कई व्यावसायिक मॉडल के संदर्भ रख सकता है। एक वेब 2.0 एप्लिकेशन में, यह एक जावास्क्रिप्ट क्लास है जो UI स्थिति रखता है, और सर्वर पर AJAX के माध्यम से संचार करता है। यूआई राज्य मॉडल के हाथों-बंद इकाई परीक्षणों को लिखने में सक्षम होना बहुत महत्वपूर्ण है, क्योंकि जहां सबसे अधिक यूआई बग पाए जाते हैं। दृश्य और नियंत्रक बहुत पतले कनेक्टर होने चाहिए।


1
मुझे लगता है कि एमवीसी की परिभाषा क्या है, इस पर आप सभी को गर्व है। यह संस्करण निश्चित रूप से एमवीसी की बहुत सख्त व्याख्या का पालन करता है। समस्या यह है कि यह सख्त व्याख्या शायद ही कभी वास्तविक जीवन में एक उपयोगी या बनाए रखने योग्य प्रणाली प्रदान करती है। कारण यह है कि हर बार जब आप एक नया यूआई तत्व / तरीका अपनाते हैं तो आपको मॉडल को बदलना होगा। मॉडल तब यूआई के लिए केवल प्रासंगिक गुणों के साथ अव्यवस्थित हो जाता है। आपके पास उस एप्लिकेशन से कोई लेना-देना नहीं है जिसे आप बनाने की कोशिश कर रहे हैं लेकिन केवल यह कि आप ऑपरेटर को डेटा कैसे पेश करना चाहते हैं। खराब!
डंक

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

@MagnoC: मैंने संपादित किया कि उसने डंक के जवाब में उत्तर दिया क्योंकि मुझे लगा कि जोड़ा गया पाठ उत्तर को बेहतर बनाता है। यह वही है जो साइट के बारे में है: सवाल और जवाब। मॉडल एक बहुत ही सामान्य शब्द है, और एमवीसी पैटर्न में, इसका अर्थ है "यूआई राज्य मॉडल"।
केविन क्लाइन

0

एक व्यावसायिक तर्क अधिक पसंद है If X then return InfoType.Y, फिर UI डोमेन द्वारा लौटाए गए परिणाम के आधार पर फ़ील्ड प्रदर्शित करेगा।

// Controller method pseudocode
option changed routine

    get selected option

    get required info type from domain routine based on selected option

    display fields based on required info type

यदि UI को व्यावसायिक तर्क की आवश्यकता होती है, तो विकल्प को डोमेन पर सौंप दें। UI निर्णय पर कार्य करेगा।


0

यदि उपयोगकर्ता ने विकल्प x का चयन किया है, तो एप्लिकेशन को उसे y के लिए जानकारी की आपूर्ति करने में सक्षम करना चाहिए, यदि नहीं तो उसे जानकारी z की आपूर्ति करनी चाहिए "।

ऐसे इनपुट हैं जिनके पास सशर्त रूप से आवश्यक मूल्य हैं। अधिकांश GUI वातावरणों में, विशेष रूप से समय पर आदानों को संभालने के तरीके पर बहुत सारे विकल्प हैं। चयनित विकल्प (इस मामले में x) को संसाधित करने की आवश्यकता है, इसलिए इसे नियंत्रक को भेजें। जब उपयोगकर्ता इनपुट फ़ील्ड छोड़ता है तो उसे भेजें। तब तक प्रतीक्षा करें जब तक कि वे किसी अन्य ऑब्जेक्ट पर क्लिक न करें या बचत न करें। व्यापार तर्क के लिए कोई फर्क नहीं पड़ता। एक तरह से या किसी अन्य, नियंत्रक एक निर्णय करेगा और दृश्य को बताने के लिए, "y की आवश्यकता है"।

दृश्य कैसे व्याख्या करता है या इसे लागू करता है यह वास्तव में व्यावसायिक तर्क के दृष्टिकोण से कोई मायने नहीं रखता है। फिर आवश्यक क्षेत्र बनाओ। एक पॉप-अप लें या एक तोप को गोली मार दें और उपयोगकर्ता को y में प्रवेश करने के लिए कहें या बस जिद्दी रहें और गरीब उपयोगकर्ता को तब तक कुछ न करने दें जब तक वह यह पता नहीं लगा ले।

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.