उदाहरण
मैं एक ही स्थान पर "सब कुछ" करता है जो मोनोलिथिक कोड में आया था - डेटाबेस से डेटा लोड करना, HTML मार्कअप दिखाना, राउटर / कंट्रोलर / एक्शन के रूप में कार्य करना। मैंने अपनी फ़ाइल में SRP मूविंग डेटाबेस कोड लागू करना शुरू किया, चीजों के लिए बेहतर नामकरण प्रदान किया, और यह सब अच्छा लग रहा था, लेकिन फिर मुझे संदेह होने लगा कि मैं ऐसा क्यों कर रहा हूं।
रिफ्लेक्टर क्यों? उद्देश्य क्या है? क्या यह बेकार है? क्या फायदा है? ध्यान दें कि मैंने ज्यादातर मोनोलिथिक फ़ाइल को छोड़ दिया है, लेकिन केवल उस छोटे हिस्से को फिर से सक्रिय किया है जो उस क्षेत्र के लिए प्रासंगिक था जहां मुझे कुछ काम करने की आवश्यकता थी।
मूल कोड:
एक ठोस उदाहरण देने के लिए, मैं इस कोड स्निपेट में आया था - यह उत्पाद विनिर्देशों को ज्ञात उत्पाद आईडी या उपयोगकर्ता द्वारा चयनित संस्करण आईडी द्वारा लोड करता है:
if ($verid)
$sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
$sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */
पुनर्रचना:
चूंकि मैं कोड के इस विशिष्ट भाग में चीजों को बदलने के लिए कुछ काम कर रहा हूं, इसलिए मैंने इसे रिपॉजिटरी पैटर्न का उपयोग करने के लिए बदल दिया और इसे ऑब्जेक्ट-ओरिएंटेड MySQL सुविधाओं का उपयोग करने के लिए अपग्रेड किया:
//some implementation details omitted
$this->repository = new SpecRepository($mysql);
if ($verid)
$row1 = $this->repository->getSpecByVersion($verid);
else
$row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/
//added new class:
class SpecRepository extends MySqlRepository
{
function getSpecByVersion(int $verid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE id = ?
", $verid)->getSingleArray();
}
function getSpecByProductId(int $productid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE product_id = ?
", $productid)->getSingleArray();
}
}
क्या मुझे ऐसा करना चाहिए?
परिवर्तनों को देखते हुए, कोड अभी भी है, समान कार्यक्षमता वाला कोड, लेकिन विभिन्न फ़ाइलों, विभिन्न नामों, स्थानों में, प्रक्रियात्मक के बजाय अधिक ऑब्जेक्ट-उन्मुख शैली का उपयोग करके। वास्तव में यह नोट करना मज़ेदार है कि बहुत ही कार्यक्षमता होने के बावजूद रिफलेक्टेड कोड बहुत अधिक फूला हुआ दिखता है।
मैंने कुछ जवाबों को यह कहते हुए छोड़ दिया कि "यदि आप उन कारणों को नहीं जानते हैं जिनके कारण आप रिफ्लेक्टर करते हैं, तो ऐसा न करें", और शायद मैं सहमत हो सकता हूं। मेरे कारण समय के साथ कोड की गुणवत्ता में सुधार करना है (और मेरी आशा है कि मैं एसआरपी और अन्य सिद्धांतों का पालन करके ऐसा करूंगा)।
क्या वे पर्याप्त अच्छे कारण हैं या क्या मैं इस तरह से "आसपास के कोड को फिर से व्यवस्थित करने" पर अपना समय बर्बाद कर रहा हूं? समग्र रूप से इसे रिफैक्ट करने से थोड़ा सा लगता है कि पानी को ईमानदार बनाना - इसमें समय लगता है और यह उतना ही अधिक "अलग" हो जाता है जितना कि एसआरपी जाता है लेकिन मेरे अच्छे इरादों के बावजूद मुझे ऐसा नहीं लगता कि मैं आश्चर्यजनक सुधार कर रहा हूं। इसलिए, बहस करना कि क्या पहले की तरह कोड छोड़ना सबसे अच्छा है और रिफ्लेक्टर नहीं।
मैंने पहली बार रिफ्लेक्टर क्यों लगाया?
मेरे मामले में मैं एक नई उत्पाद लाइन के लिए नई कार्यक्षमता जोड़ रहा हूं, इसलिए मुझे या तो समान उत्पाद लाइनों के लिए मौजूदा कोड संरचना का पालन करना होगा, या अपना खुद का लिखना होगा।
select *
यह "सर्वोत्तम अभ्यास" बन जाता है।
Select * from ..
एक विरोधी पैटर्न माना जा सकता है। देखें stackoverflow.com/q/3639861/31326