
हाल की एक परियोजना में, मुझे एक वेब सिस्टम के बड़े हिस्सों को रिफैक्टर करने का काम सौंपा गया था। यह C# में लिखा गया है। समय के साथ कुछ कोड-बिहाइंड फ़ाइलें 4000 लाइनों तक बढ़ गई थीं। लक्ष्य इस संख्या को अधिक रखरखाव योग्य स्तर तक कम करना था।
अगली कुछ पोस्टों में, मैंने कोड के स्निपेट्स लिए हैं जिन्हें मैंने रिफैक्टर किया है और अपने विचारों और समाधान तक पहुंचने की प्रक्रिया को समझाऊंगा।
पहला कोड स्निपेट:
string tmp = Request.QueryString["st"];
_varStartRecNum = tmp;
if ((tmp != null) & (!Page.IsPostBack))
{
_varStartRecNum = tmp;
postBack = true;
}
tmp = Request.QueryString["det"];
if ((tmp != null) & (!Page.IsPostBack))
{
_varDetailsRecNum = tmp;
postBack = true;
}
tmp = Request.QueryString["return"];
if ((tmp != null) & (!Page.IsPostBack))
{
postBack = true;
}
tmp = Request.QueryString["searchnow"];
if ((tmp != null) & (!Page.IsPostBack))
{
Session["selectedTab"] = "mtf";
Session["sessionDSProviders"] = null;
Session["mtfs"] = null;
}
tmp = Request.QueryString["displaywalking"];
if (tmp == "true")
{
dispMtf = false;
postBack = true;
}
tmp = Request.QueryString["sb"];
if ((tmp != null) & (!Page.IsPostBack))
{
_varSortBy = tmp;
postBack = true;
switch (_varSortBy)
{
case "Distance":
case "Drive time":
ddlSortBy.SelectedIndex = 0;
break;
case "Name":
ddlSortBy.SelectedIndex = 1;
break;
case "Gender":
ddlSortBy.SelectedIndex = 2;
break;
case "Clinic":
ddlSortBy.SelectedIndex = 3;
break;
case "City":
ddlSortBy.SelectedIndex = 4;
break;
case "Description":
ddlSortBy.SelectedIndex = 5;
break;
}
}
उपरोक्त कोड स्निपेट if स्टेटमेंट्स का एक संग्रह है, जो एक मूल्यांकन और एक निष्पादन हैं। मेरे पहले प्रयास में, मैंने सभी if स्टेटमेंट्स के लिए समान मूल्यांकन का उपयोग करने की कोशिश की, लेकिन फिर मुझे एहसास हुआ कि एक अलग था। कोड के इरादे को न समझते हुए मैं तर्क को शब्दशः संरक्षित करने के लिए मजबूर था।
अलग if मूल्यांकन:
tmp = Request.QueryString["displaywalking"];
if (tmp == "true")
{
dispMtf = false;
postBack = true;
}
स्विच स्टेटमेंट ने मुझे चिंतित किया। स्विच स्टेटमेंट में प्रवेश करने की शर्त अन्य के समान है। मैंने आगे बढ़ने और बाद में स्विच स्टेटमेंट के बारे में चिंता करने का फैसला किया।
कोड समान वेरिएबल, ‘tmp’ वेरिएबल का उपयोग करके विभिन्न क्वेरी वैल्यू प्राप्त करता है। प्रत्येक क्वेरी वैल्यू पुनर्प्राप्ति के साथ वैल्यू को अधिलेखित कर दिया जाता है। स्पष्टता के लिए मैं प्रत्येक क्वेरी वैल्यू के लिए एक वेरिएबल बनाता हूं:
string st = Request.QueryString["st"];
string det = Request.QueryString["det"];
string @return = Request.QueryString["return"];
string searchNow = Request.QueryString["searchnow"];
string displayWaling = Request.QueryString["displaywalking"];
string sb = Request.QueryString["sb"];
अगला कदम मूल्यांकन और अभिव्यक्ति को अलग करना था जबकि उन्हें एक दूसरे के साथ जुड़ा रखना था। यदि कोई मूल्यांकन सत्य है, तो मैं इसकी संबंधित अभिव्यक्ति को निष्पादित करना चाहता हूं। मैंने एक क्लास बनाई जो इस संबंध का प्रतिनिधित्व करती है।
private class Evaluate
{
public Func Evaluation { get; set; }
public Action Expression { get; set; }
}
अब मैं एक मूल्यांकन बना सकता हूं, और यदि यह सत्य है, तो मैं इसकी अभिव्यक्ति को निष्पादित कर सकता हूं।
अगली समस्या यह थी कि उपरोक्त क्लास का उपयोग सभी if स्टेटमेंट्स के साथ कैसे करें। मुझे चिंता थी कि अभिव्यक्तियां एक संग्रह में अनावश्यक रूप से जटिल हो सकती हैं। पूरा उद्देश्य एक संक्षिप्त स्केलेबल समाधान बनाना था। मौजूदा समाधान न तो था।
var eval = new[]
{
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(st) && !IsPostBack), Expression = () => { _varStartRecNum = st;postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(det) && !IsPostBack), Expression = () => { _varStartRecNum = det;postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(@return) && !IsPostBack), Expression = () => {postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(searchNow) && !IsPostBack), Expression = () => {Session["selectedTab"] = "mtf";Session["sessionDSProviders"] = null; Session["mtfs"] = null;}},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(displayWaling)), Expression = () => {dispMtf = false; postBack = true;}},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(sb) && !IsPostBack), Expression = () => {_varSortBy = sb;postBack = true; SetSort(_varSortBy);}},
};
यह मेरी अपेक्षा से बेहतर निकला। मेरे समाधान की एक कमी यह है कि यदि आप नहीं जानते कि डेलिगेट्स का उपयोग कैसे करना है, तो उपरोक्त कोड को बनाए रखने की बात आने पर आप मुश्किल में पड़ जाएंगे।
अंतिम बाधा स्विच स्टेटमेंट था। यह मेरे अनाम संग्रह में सुंदरता से फिट नहीं होने वाला था, लेकिन फिर इसकी आवश्यकता भी नहीं थी:
private void SetSort(string sortBy)
{
switch (sortBy)
{
case "Distance":
case "Drive time":
ddlSortBy.SelectedIndex = 0;
break;
case "Name":
ddlSortBy.SelectedIndex = 1;
break;
case "Gender":
ddlSortBy.SelectedIndex = 2;
break;
case "Clinic":
ddlSortBy.SelectedIndex = 3;
break;
case "City":
ddlSortBy.SelectedIndex = 4;
break;
case "Description":
ddlSortBy.SelectedIndex = 5;
break;
}
}
इसे एक मेथड में एनकैप्सुलेट करके, मैं अभिव्यक्ति में मेथड का संदर्भ देने में सक्षम था। यह बहुत अच्छी तरह से काम किया।
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(sb) && !IsPostBack), Expression = () => {_varSortBy = sb;postBack = true; SetSort(_varSortBy);}
अंतिम घटक संग्रह पर पुनरावृत्ति है:
foreach (var evaluate in eval.Where(evaluate => evaluate.Evaluation()))
{
evaluate.Expression();
}
पूरा समाधान:
private class Evaluate
{
public Func Evaluation { get; set; }
public Action Expression { get; set; }
}
private void SetSort(string sortBy)
{
switch (sortBy)
{
case "Distance":
case "Drive time":
ddlSortBy.SelectedIndex = 0;
break;
case "Name":
ddlSortBy.SelectedIndex = 1;
break;
case "Gender":
ddlSortBy.SelectedIndex = 2;
break;
case "Clinic":
ddlSortBy.SelectedIndex = 3;
break;
case "City":
ddlSortBy.SelectedIndex = 4;
break;
case "Description":
ddlSortBy.SelectedIndex = 5;
break;
}
}
private void EvaluateQueryParameters()
{
string st = Request.QueryString["st"];
string det = Request.QueryString["det"];
string @return = Request.QueryString["return"];
string searchNow = Request.QueryString["searchnow"];
string displayWaling = Request.QueryString["displaywalking"];
string sb = Request.QueryString["sb"];
var eval = new[]
{
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(st) && !IsPostBack), Expression = () => { _varStartRecNum = st;postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(det) && !IsPostBack), Expression = () => { _varStartRecNum = det;postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(@return) && !IsPostBack), Expression = () => {postBack = true; }},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(searchNow) && !IsPostBack), Expression = () => {Session["selectedTab"] = "mtf";Session["sessionDSProviders"] = null; Session["mtfs"] = null;}},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(displayWaling)), Expression = () => {dispMtf = false; postBack = true;}},
new Evaluate {Evaluation = () => (!string.IsNullOrEmpty(sb) && !IsPostBack), Expression = () => {_varSortBy = sb;postBack = true; SetSort(_varSortBy);}},
};
foreach (var evaluate in eval.Where(evaluate => evaluate.Evaluation()))
{
evaluate.Expression();
}
}
अंत में, मुझे यह समाधान मूल से बेहतर लगता है। एक कमी यह है कि यह जिस स्तर पर लिखा गया है। मैं एक सरल समाधान बनाना चाहता था जिसे कोई भी डेवलपर बनाए रख सके। उपरोक्त कोड के बारे में कुछ भी कठिन नहीं है; मैं एक संग्रह बना रहा हूं और उस पर पुनरावृत्ति कर रहा हूं। भ्रम मूल्यांकन और अभिव्यक्तियों के साथ आता है। यह एक शुरुआती विषय नहीं है।
लेखक: चक कॉनवे सॉफ्टवेयर इंजीनियरिंग और जेनेरेटिव AI में विशेषज्ञता रखते हैं। उनसे सोशल मीडिया पर जुड़ें: X (@chuckconway) या उन्हें YouTube पर देखें।