Skip to content

পোস্ট

কোড রিফ্যাক্টর

২২ অক্টোবর, ২০১০ • 6 মিনিট পড়া

কোড রিফ্যাক্টর

সাম্প্রতিক একটি প্রকল্পে, আমাকে একটি ওয়েব সিস্টেমের বড় অংশগুলো রিফ্যাক্টর করার দায়িত্ব দেওয়া হয়েছিল। এটি C# এ লেখা। সময়ের সাথে সাথে কিছু কোড-বিহাইন্ড ফাইল ৪০০০ লাইন পর্যন্ত বেড়ে গিয়েছিল। লক্ষ্য ছিল এই সংখ্যাটি আরো রক্ষণাবেক্ষণযোগ্য স্তরে নামিয়ে আনা।

পরবর্তী কয়েকটি পোস্টে, আমি যে কোডের অংশগুলো রিফ্যাক্টর করেছি তার স্নিপেট নিয়েছি এবং আমার চিন্তাভাবনা এবং কীভাবে আমি সমাধানে পৌঁছেছি তা ব্যাখ্যা করব।

প্রথম কোড স্নিপেট:

    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;
}

switch স্টেটমেন্টটি আমাকে চিন্তিত করেছিল। switch স্টেটমেন্টে প্রবেশের শর্ত অন্যদের মতোই। আমি এগিয়ে যাওয়ার সিদ্ধান্ত নিয়েছিলাম এবং switch স্টেটমেন্ট নিয়ে পরে চিন্তা করার।

কোডটি একই ভেরিয়েবল, ‘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);}}, 
               };

এটি আমার প্রত্যাশার চেয়ে ভাল হয়েছে। আমার সমাধানের একটি অসুবিধা হল, যদি আপনি ডেলিগেট কীভাবে ব্যবহার করতে হয় তা না জানেন, তাহলে উপরের কোড রক্ষণাবেক্ষণের ক্ষেত্রে আপনি সমস্যায় পড়বেন।

শেষ বাধা ছিল switch স্টেটমেন্ট। এটি আমার অ্যানোনিমাস কালেকশনে সুন্দরভাবে ফিট হতে যাচ্ছিল না, কিন্তু তারপর এটির প্রয়োজনও ছিল না:

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();
    }
}

শেষ পর্যন্ত, আমি এই সমাধানটি মূল সমাধানের চেয়ে ভাল পছন্দ করি। একটি অসুবিধা হল এটি যে স্তরে লেখা। আমি একটি সহজ সমাধান তৈরি করতে চেয়েছিলাম যা যেকোনো ডেভেলপার রক্ষণাবেক্ষণ করতে পারে। উপরের কোডে কঠিন কিছু নেই; আমি একটি কালেকশন তৈরি করছি এবং এর উপর ইটারেট করছি। বিভ্রান্তি আসে মূল্যায়ন এবং এক্সপ্রেশনের সাথে। এটি একটি শিক্ষানবিস বিষয় নয়।

লেখক: চাক কনওয়ে সফটওয়্যার ইঞ্জিনিয়ারিং এবং জেনারেটিভ এআই-তে বিশেষজ্ঞ। তার সাথে সোশ্যাল মিডিয়ায় যোগাযোগ করুন: X (@chuckconway) অথবা তাকে YouTube-এ দেখুন।

↑ উপরে ফিরে যান

আপনি এগুলোও পছন্দ করতে পারেন