2009-10-22 7 views
13

जटिल व्यापार तर्क को संभालने के अच्छे तरीके क्या हैं कि पहली नज़र से बयान में कई घोंसले की आवश्यकता होती है?जटिल व्यवसाय "आईएफ" तर्क को सरल कैसे करें?

उदाहरण:

डिस्काउंट कूपन। हो सकता है:

1 क) मूल्य छूट
1b) का प्रतिशत छूट

2 ए) सामान्य छूट
2b) प्रगतिशील छूट

3a) आवश्यक पहुँच कूपन
3 बी) का उपयोग कूपन

की आवश्यकता नहीं है

4 ए) केवल उस ग्राहक को लागू किया गया जो पहले से ही
4b से पहले खरीदा गया है) किसी भी ग्राहक को लागू

5a) केवल उन्हीं देशों (पहला, दूसरा, से ग्राहकों के लिए लागू होता है ...)

कोड की आवश्यकता है यही कारण है कि और भी जटिल तो यह:

if (discount.isPercentage) { 
    if (discount.isNormal) { 
     if (discount.requiresAccessCoupon) { 
     } else { 
     } 
    } else if (discount.isProgressive) { 
     if (discount.requiresAccessCoupon) { 
     } else { 
     } 
    } 
} else if (discount.isValue) { 
    if (discount.isNormal) { 
     if (discount.requiresAccessCoupon) { 
     } else { 
     } 
    } else if (discount.isProgressive) { 
     if (discount.requiresAccessCoupon) { 
     } else { 
     } 
    } 
} else if (discount.isXXX) { 
    if (discount.isNormal) { 
    } else if (discount.isProgressive) { 
    } 
} 

भले ही आप आईएफएस की जगह स्विच करने के लिए/मामला यह है अभी भी बहुत जटिल है। इसे पठनीय, रखरखाव करने योग्य, अधिक परीक्षण करने योग्य और समझने में आसान बनाने के तरीके क्या हैं?

उत्तर

4

मैं एक सामान्य राज्य मशीन है कि चीजों की तुलना करने के लिए की सूची पर फ़ीड लिखेंगे।

9

Specification pattern जो भी आप खोज रहे हैं हो सकता है।

सारांश:

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

2

कर की वस्तु उन्मुख जिस तरह से यह एक आम इंटरफेस को लागू करने के लिए कई छूट वर्गों है:

dicsount.apply(order) 

का निर्धारण करने के क्रम छूट वर्गों के भीतर छूट के लिए उत्तीर्ण के लिए तर्क रखो।

+0

यह अलग छूट वर्ग नहीं है। यह एक छूट वर्ग है जो उन सभी 1-5 चीजों के साथ संभावित गुणों के साथ है। – Zelid

+0

मैं सुझाव दे रहा हूं कि आप इसे बदल दें ताकि आपके पास कई छूट कक्षाएं हों। –

+0

ठीक है, तो फिर निर्दिष्ट करें कि छूट एक ही समय में 1 ए, 2 बी, 3 ए, 4 बी होना चाहिए? – Zelid

0

मेरा पहला विचार यह है कि यह टेस्टेबल नहीं है, जो मुझे परीक्षण करने योग्य बनाने के लिए एक समाधान के लिए प्रेरित करता है।

if (discount.isPercentage) { 
    callFunctionOne(...); 
} else if (discount.isValue) { 
    callFunctionThree(...); 
} else if (discount.isXXX) { 
    callFunctionTwo(...); 
} 

फिर यदि आप एक अलग कॉल हो तो प्रत्येक नेस्टेड हो सकता है। इस तरह आप उन्हें अलग-अलग परीक्षण कर सकते हैं और जब आप बड़े समूह का परीक्षण करते हैं तो आप जानते हैं कि प्रत्येक व्यक्ति काम करता है।

+0

ऐसा लगता है कि इसे अभी लागू किया गया है, फिर भी CallFunctionX() के अंदर कई आईएफ की आवश्यकता है और इसी तरह ... – Zelid

+0

आप अपने तर्क का मूल्यांकन करना चाह सकते हैं। उदाहरण के लिए, यदि आप कार्यक्षमता को सबक्लास में समूहित कर सकते हैं तो आप देख सकते हैं कि यह छूट उप-वर्ग पर लागू होती है और उसे वहां पास करती है। –

0

किसी विशेष मामले की जांच करने वाली विधियां बनाएं।

bool IsValueNormalAndRequiresCoopon (डिस्काउंट छूट) {...}

bool IsValueNormalAndRequiresCoupon (डिस्काउंट छूट) {...}

आदि

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

जटिल निर्णयों के लिए मैं अक्सर एक ऐसे वर्ग के साथ समाप्त होता हूं जो संभावित राज्यों को संभालता है।

+1

गुणों के सभी संयोजनों के लिए ~ 32 ऐसे फ़ंक्शन भी बहुत अच्छे नहीं हैं – Zelid

+0

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

1

guard clauses का उपयोग करने से कुछ मदद मिल सकती है।

+0

लेकिन क्या यह एकल निकास सिद्धांत का उल्लंघन नहीं करता है? –

+0

निश्चित रूप से। हालांकि मुझे नहीं पता कि नियम अब कितना महत्व रखता है। मैं निश्चित रूप से इसका पालन करने के अपने रास्ते से बाहर नहीं जाता हूं। भले ही आप इसकी सदस्यता लेते हैं, मुझे लगता है कि गार्ड क्लॉज एक स्वीकार्य अपवाद होगा। –

+1

गार्ड क्लॉज के लिए 5 अलग-अलग डिस्काउंट कूपन गुणों (वॉल्यूम/प्रतिशत, सामान्य/प्रगतिशील, RequCoupon/DoNotRequireCoupon, ...) के प्रत्येक संभावित संयोजन के लिए एक नया फ़ंक्शन की आवश्यकता होगी, जो भी अच्छा नहीं है – Zelid

11

अच्छा सवाल। "सशर्त जटिलता" एक कोड गंध है। Polymorphism आपका मित्र है।

सशर्त तर्क, अपनी प्रारंभिक अवस्था में निर्दोष है जब यह समझते हैं और कोड का एक कुछ लाइनों के भीतर समाहित करने के लिए आसान है। दुर्भाग्यवश, यह शायद ही कभी उम्र बढ़ता है। आप कई नई सुविधाओं को लागू करते हैं और अचानक आपका सशर्त तर्क जटिल और विशाल हो जाता है। [यहोशू Kerevsky: पैटर्न को Refactoring]

सरल चीजें आप नेस्टेड से बचने के लिए अगर ब्लॉक Guard Clauses उपयोग करने के लिए सीखने के लिए है क्या कर सकते हैं में से एक।

double getPayAmount() { 
if (_isDead) return deadAmount(); 
if (_isSeparated) return separatedAmount(); 
if (_isRetired) return retiredAmount(); 
return normalPayAmount(); 
}; 

दूसरी बात मैं पाया है बहुत अच्छी तरह से चीजों को सरल है, और जो अपने कोड आत्म दस्तावेज़ीकृत कर बनाता है, Consolidating conditionals है।

double disabilityAmount() { 
    if (isNotEligableForDisability()) return 0; 
    // compute the disability amount 

अन्य मूल्यवान refactoring सशर्त भाव के साथ जुड़े तकनीक Decompose Conditional, Replace Conditional with Visitor, और Reverse Conditional शामिल हैं।

+0

+1 - मुझे आपके द्वारा दिया गया तरीका पसंद है विभिन्न विकल्प –

+1

ऐसा लगता है कि "गार्ड क्लॉज" समाधान केवल तभी काम करेगा जब गुणों की तुलना स्वयं-बहिष्कारशील हो (_isDead, _isSeparated, isRetired) प्रदान किए गए उदाहरण के लिए इस समाधान का उपयोग करना संभव नहीं है, क्योंकि डिस्काउंट कूपन दोनों "1 ए) मूल्य छूट, 2 ए) हो सकता है सामान्य छूट, 3 बी) एक्सेस कूपन, 4 ए की आवश्यकता नहीं है) केवल ग्राहक को लागू किया गया है जो पहले से ही खरीदा गया है और 5 ए) केवल ग्राहकों (एक्स, वाई, ...) से ग्राहक को लागू किया गया है " – Zelid

+0

या 32 ऐसे रिटर्न स्टेटमेंट्स को जोड़ें: _isValueAndNoramAndAcees() _isValueAndProgressiveAndNotRequireAccessAndRequireCountires() .... IF में और अन्य कार्यों में सभी अन्य संयोजन – Zelid

0

एफडब्ल्यूआईडब्ल्यू, मैंने Hamcrest का उपयोग इस तरह की चीज के लिए बहुत सफलतापूर्वक किया है। मेरा मानना ​​है कि आप कह सकते हैं कि यह विशिष्टता पैटर्न लागू करता है, @ अरनिस ने बात की।

1

आप वास्तव में Misko Hevery

Google प्रौद्योगिकी वार्ता 20 नवंबर तक

Clean Code Talks - Inheritance, Polymorphism, & Testing
देखना चाहिए, 2008

अमूर्त

अपने कोड बयान करता है, तो से भरा है? कथन स्विच करें? क्या आपके पास विभिन्न स्थानों पर एक ही स्विच स्टेटमेंट है? जब आप परिवर्तन करते हैं तो क्या आप खुद को एक ही बदलाव कर पाते हैं यदि कई स्थानों पर स्विच किया जाता है? क्या आपने कभी एक भूल लिया था?

यह बात उन सशर्तों को हटाने के लिए ऑब्जेक्ट ओरिएंटेड तकनीकों का उपयोग करने के दृष्टिकोणों पर चर्चा करेगी। परिणाम क्लीनर, कड़ा, बेहतर डिज़ाइन किया गया कोड है जो परीक्षण, समझने और बनाए रखने में आसान है।

+0

धन्यवाद, ध्वनि बहुत उपयोगी पढ़ेगा – Zelid

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