যদি আমি চাচা ববের ক্লিন কোড নীতিমালা মেনে চলতে পারি তবে আমি কীভাবে একটি চেইন সম্পাদনা করব?


45

আমি চাচা বব এর পরিষ্কার কোড পরামর্শগুলি এবং বিশেষত পদ্ধতিগুলি সংক্ষিপ্ত রাখতে অনুসরণ করার চেষ্টা করছি।

আমি যদিও এই যুক্তিটি সংক্ষিপ্ত করতে নিজেকে অক্ষম মনে করি:

if (checkCondition()) {addAlert(1);}
else if (checkCondition2()) {addAlert(2);}
else if (checkCondition3()) {addAlert(3);}
else if (checkCondition4()) {addAlert(4);}

আমি এলিজগুলি অপসারণ করতে পারি না এবং পুরো জিনিসটিকে ছোট ছোট বিটগুলিতে পৃথক করতে পারি না, "অন্যথায়" "যদি অন্যটি" সম্পাদন করতে সহায়তা করে - তবে এই শর্তগুলির মূল্যায়ন ব্যয়বহুল এবং যদি আমি নীচের শর্তগুলির মূল্যায়ন এড়াতে পারি তবে প্রথমটির মধ্যে একটির কারণ তৈরি করুন সত্য, আমি তাদের এড়াতে চাই

এমনকি শব্দার্থভাবে বলতে গেলে, পূর্বের শর্তটি পূরণ করা হলে পরবর্তী শর্তটি মূল্যায়ন করা ব্যবসায়ের দৃষ্টিকোণ থেকে বোঝা যায় না।


সম্পাদনা: এই প্রশ্নটি হোল্ড করার মার্জিত উপায়গুলির সম্ভাব্য নকল হিসাবে চিহ্নিত করা হয়েছিল (অন্যথায় যদি)

আমি বিশ্বাস করি এটি একটি আলাদা প্রশ্ন (আপনি এই প্রশ্নের উত্তরগুলির তুলনা করে এটি দেখতেও পারেন)।

  • আমার প্রশ্ন জন্য চেক করা হয় দ্রুত শেষ প্রথম গ্রহণ শর্ত
  • লিঙ্কযুক্ত প্রশ্নটি করার চেষ্টা করছে যে কিছু করার জন্য সমস্ত শর্ত মেনে নেওয়া উচিত । (এই প্রশ্নের উত্তরে আরও ভালভাবে দেখা যাবে: https://softwareengineering.stackexchange.com/a/122625/96955 )

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

38
এই কোডটিতে কিছু ভুল নেই। এটি খুব পাঠযোগ্য এবং অনুসরণযোগ্য। আপনি এটি আরও সঙ্কুচিত করতে যা কিছু করেন তা ইন্ডিয়ারেশন যুক্ত করতে এবং বোঝা আরও শক্ত করে তুলতে চলেছে।
26

20
আপনার কোড ঠিক আছে। আপনার অবশিষ্ট শক্তিটিকে আরও ছোট করার চেষ্টা করার চেয়ে আরও বেশি উত্পাদনশীল কিছুতে রাখুন।
রবার্ট হার্ভে

5
যদি এটি সত্যিই মাত্র 4 শর্ত থাকে তবে এটি ঠিক আছে। যদি এটি সত্যিই 12 বা 50 এর মতো কিছু হয় তবে আপনি সম্ভবত এই একটি পদ্ধতির চেয়ে উচ্চ স্তরে রিফ্যাক্টর করতে চান।
জিমি জেমস

9
আপনার কোডটি ঠিক যেমন রেখে দিন। আপনার পিতা-মাতা সর্বদা আপনাকে যা বলেছিলেন তা শোনো: রাস্তায় বাচ্চাদের মিষ্টি দেওয়ার কোনও চাচা বিশ্বাস করবেন না। @ হার্ভে ফানি যথেষ্ট, কোডটির "উন্নতি" করার বিভিন্ন প্রচেষ্টা সমস্ত এটিকে অনেক বড়, আরও জটিল এবং কম পঠনযোগ্য করে তুলেছে।
gnasher729 20

উত্তর:


81

আদর্শভাবে আমি মনে করি আপনার নিজের পদ্ধতিতে সতর্কতা কোড / নম্বর পাওয়ার জন্য আপনার যুক্তিটি বের করা উচিত। সুতরাং আপনার বিদ্যমান কোডটি সমস্ত উপায়ে কমিয়ে দেওয়া হয়েছে

{
    addAlert(GetConditionCode());
}

এবং আপনার কাছে গেটকন্ডিশনকোড () শর্তাদি যাচাইয়ের জন্য লজিককে সজ্জিত করে। ম্যাজিক নম্বরের চেয়ে এনাম ব্যবহার করা আরও ভাল।

private AlertCode GetConditionCode() {
    if (CheckCondition1()) return AlertCode.OnFire;
    if (CheckCondition2()) return AlertCode.PlagueOfBees;
    if (CheckCondition3()) return AlertCode.Godzilla;
    if (CheckCondition4()) return AlertCode.ZombieSharkNado;
    return AlertCode.None;
}

2
আপনার বর্ণনার মতো এনক্যাপসুলেট করা সম্ভব হলে (আমি সন্দেহ করি এটি নাও হতে পারে বলে আমার ধারণা, ওপি সরলতার জন্য ভেরিয়েবলগুলি ছেড়ে চলেছে), এটি কোডটি পরিবর্তন করে না, যা নিজেই ভাল, তবে কোড এরগনোমিক্স এবং কিছুটা পাঠযোগ্যতা যুক্ত করে + 1
14-15 এ 15

17
এই সতর্কতা কোডগুলির সাথে, আমি কোডকে ধন্যবাদ জানাই যে একবারে কেবল একটিই ফিরে আসতে পারে
জোশ পার্ট

12
এটি একটি স্যুইচ বিবৃতি ব্যবহারের জন্য একটি নিখুঁত ম্যাচ বলে মনে হয় - যদি এটি ওপির ভাষায় উপলব্ধ।
ফ্র্যাঙ্ক হপকিন্স

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

6
এই reimplementation সঙ্গে একটি বিষয় যে এটা ফাংশন করে তোলে addAlertবাজে সতর্কতা অবস্থার জন্য চেক করতে হবে AlertCode.None
ডেভিড হামেন

69

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

আরও "সরলকরণ" করার যে কোনও প্রচেষ্টা আসলে বিষয়গুলিকে জটিল করে তুলবে।

অবশ্যই, আপনি elseকীওয়ার্ডটি returnঅন্যের পরামর্শ অনুসারে একটি প্রতিস্থাপন করতে পারেন , তবে এটি কেবল স্টাইলের বিষয়, জটিলতায় কোনও পরিবর্তন নয়।


একপাশে:

আমার সাধারণ পরামর্শটি হ'ল, ক্লিন কোডের কোনও নিয়ম সম্পর্কে কখনই ধর্মীয় হওয়া উচিত নয়: ইন্টারনেটে আপনি যে কোডিংয়ের বেশিরভাগ পরামর্শ দেখেন এটি বেশ উপযুক্ত, যদি এটি কোনও উপযুক্ত প্রসঙ্গে প্রয়োগ করা হয় তবে সর্বত্র একই পরামর্শ কার্যকরভাবে প্রয়োগ করা আপনাকে প্রবেশ করতে পারে IOCCC । কৌশলটি সর্বদা একটি ভারসাম্য রোধ করা যা মানবকে আপনার কোড সম্পর্কে সহজেই যুক্তিসঙ্গত করতে দেয়।

খুব বড় পদ্ধতি ব্যবহার করুন এবং আপনি বিভ্রান্ত হয়েছেন। খুব ছোট ফাংশন ব্যবহার করুন, এবং আপনি বিচলিত। ত্রৈমাসিক অভিব্যক্তিগুলি এড়িয়ে চলুন এবং আপনি ভ্রষ্ট হন। সর্বত্র ত্রৈমাসিক অভিব্যক্তি ব্যবহার করুন, এবং আপনি চতুর হন। বুঝতে পারেন যে এমন এক জায়গাগুলি রয়েছে যেগুলি এক-লাইন ফাংশনগুলির জন্য কল করে এবং এমন জায়গাগুলি যেগুলি 50-লাইন ফাংশনগুলির জন্য কল করে (হ্যাঁ, তারা বিদ্যমান!)। বুঝতে পারেন যে এমন জায়গাগুলি রয়েছে যেগুলি if()বিবৃতি চেয়েছিল, এবং এমন জায়গাগুলি রয়েছে যা ?:অপারেটরের জন্য কল করে । আপনার নিষ্পত্তিযোগ্য পুরো অস্ত্রাগারটি ব্যবহার করুন এবং আপনি খুঁজে পেতে পারেন এমন সবচেয়ে উপযুক্ত সরঞ্জামটি সর্বদা ব্যবহার করার চেষ্টা করুন। এবং মনে রাখবেন, এমনকি এই পরামর্শটি সম্পর্কে ধর্মীয় হয়ে উঠবেন না।


2
আমি যুক্তি দিয়ে বলছি যে else ifকোনও অভ্যন্তরের পরিবর্তে returnএকটি সরল if(মুছে ফেলা else) পরে প্রতিস্থাপন করা কোডটি পড়া আরও কঠিন করে তুলবে । কোডটি বলে else if, আমি তাত্ক্ষণিকভাবে জানি যে পরের ব্লকের কোডটি কেবল তখনই কার্যকর করা হবে যদি পূর্ববর্তীটি না করে। কোন ঝাঁকুনি নেই, গোলমাল নেই। এটি যদি কোনও সমভূমি হয় ifতবে এটি কার্যকর হতে পারে বা এটি নাও নির্বিশেষে পূর্ববর্তীটিকে কার্যকর করা হয়েছে কিনা। এখন আমি যে এটি একটি দিয়ে শেষ হয় নোট আগের ব্লক বিশ্লেষণ করতে মানসিক প্রচেষ্টার কিছু সময়ের ব্যয় করতে হবে return। আমি বরং সেই যুক্তিটি ব্যবসায়িক যুক্তিকে পার্স করার জন্য ব্যয় করব।
একটি সিভিএন

1
আমি জানি, এটি একটি ছোট জিনিস, তবে আমার কাছে কমপক্ষে else ifএকটি শব্দার্থক ইউনিট গঠন করে। (এটি সংকলকটিতে অগত্যা একক ইউনিট নয়, তবে এটি ঠিক আছে)) ...; return; } if (...না; এটি একাধিক লাইনে ছড়িয়ে থাকলে কেবল ছেড়ে দিন। এটি এমন কিছুর জন্য যা যা আছে তা সরাসরি দেখার জন্য আমাকে আসলে এটি কী করছে তা দেখতে হবে else if
একটি সিভিএন

@ মাইকেলKjörling সম্পূর্ণ আক.আমি নিজেই এই নির্মাণটি পছন্দ করবো else if, বিশেষত যেহেতু এর শৃঙ্খলিত আকারটি এটি একটি সুপরিচিত প্যাটার্ন। তবে, ফর্মের if(...) return ...;কোডটিও একটি সুপরিচিত প্যাটার্ন, তাই আমি এর পুরোপুরি নিন্দা করব না। যদিও আমি এটিকে সত্যিই একটি ছোটখাটো সমস্যা হিসাবে দেখছি: নিয়ন্ত্রণ প্রবাহের যুক্তি উভয় ক্ষেত্রেই একই রকম, এবং if(...) { ...; return; }মইয়ের একটি ঘনিষ্ঠ দৃষ্টিপাত আমাকে বলবে যে এটি সত্যই একটি else ifমইয়ের সমতুল্য । আমি একটি শব্দটির কাঠামো দেখতে পাচ্ছি, আমি এর অর্থটি অনুমান করি, আমি বুঝতে পারি যে এটি সর্বত্র পুনরাবৃত্তি হয়েছে, এবং আমি জানি কী ঘটছে।
মাসের

জাভাস্ক্রিপ্ট / নোড.জেএস থেকে আসা, কেউ কেউ "বেল্ট এবং সাসপেন্ডার" কোড ব্যবহার করবে এবং উভয়ই । যেমনelse if returnelse if(...) { return alert();}
user949300

1
"এবং মনে রাখবেন, এই পরামর্শটি সম্পর্কে এমনকি ধর্মীয় হয়ে উঠবেন না।" +1
মতো শব্দগুলি

22

এটি বিতর্কিত কিনা এটি যদি প্লেইন থেকে ভাল 'তবে ভাল' যদি কোনও প্রদত্ত মামলার জন্য হয়। তবে আপনি চাইলে অন্য কিছু চেষ্টা করতে করার একটি সাধারণ উপায়।

আপনার শর্তাদি বস্তুগুলিতে রাখুন এবং সেই বস্তুগুলিকে একটি তালিকায় রাখুন

foreach(var condition in Conditions.OrderBy(i=>i.OrderToRunIn))
{
    if(condition.EvaluatesToTrue())
    {
        addAlert(condition.Alert);
        break;
    }
}

শর্তে যদি একাধিক ক্রিয়া প্রয়োজন হয় তবে আপনি কিছু ক্রেজি পুনরাবৃত্তি করতে পারেন

void RunConditionalAction(ConditionalActionSet conditions)
{
    foreach(var condition in conditions.OrderBy(i=>i.OrderToRunIn))
    {
        if(condition.EvaluatesToTrue())
        {
            RunConditionalAction(condition);
            break;
        }
    }
}

অবশ্যই হ্যাঁ এটি কেবল তখনই কাজ করে যদি আপনার লজিকের কোনও ধরণ থাকে। যদি আপনি একটি সুপার জেনেরিক পুনরাবৃত্ত শর্তসাপেক্ষ পদক্ষেপ করার চেষ্টা করেন তবে অবজেক্টের জন্য সেটআপ যদি স্টেটমেন্টের মূল হিসাবে জটিল হয়। আপনি নিজের নতুন ভাষা / কাঠামো উদ্ভাবন করবেন।

কিন্তু আপনার উদাহরণ আছে একটি প্যাটার্ন আছে

এই প্যাটার্নের জন্য একটি সাধারণ ব্যবহারের ক্ষেত্রে বৈধতা হবে। পরিবর্তে :

bool IsValid()
{
    if(condition1 == false)
    {
        throw new ValidationException("condition1 is wrong!");
    }
    elseif(condition2 == false)
    {
    ....

}

হয়ে

[MustHaveCondition1]
[MustHaveCondition2]
public myObject()
{
    [MustMatchRegExCondition("xyz")]
    public string myProperty {get;set;}
    public bool IsValid()
    {
        conditions = getConditionsFromReflection()
        //loop through conditions
    }
}

27
এটি কেবল if...elseসিঁড়িটি Conditionsতালিকার নির্মাণে সরিয়ে নিয়েছে । নিট লাভটি নেতিবাচক, কারণ এটি নির্মাণে Conditionsওপি কোডের মতোই কোড নেবে, তবে যোগযোগ্য দিকনির্দেশটি পাঠযোগ্যতার ব্যয় নিয়ে আসে। আমি অবশ্যই একটি পরিষ্কার কোডড মই পছন্দ করব।
মাস্টার

3
@ মাস্টার হ্যাঁ আমি মনে করি আমি ঠিক বলেছি "" তবে যদি স্টেটমেন্টের বিবরণটি মূল বক্তব্যটির মতো জটিল হবে £
ইওয়ান

7
এটি আসলটির চেয়ে কম পঠনযোগ্য। আসলে কোন শর্তটি পরীক্ষা করা হচ্ছে তা নির্ধারণ করার জন্য আপনাকে কোডের অন্য কোনও অঞ্চলে খনন করতে হবে। এটি নির্দেশের একটি অপ্রয়োজনীয় স্তর যুক্ত করে যা কোডটি বোঝা শক্ত করে to
26

8
একটি if .. অন্যথায় যদি .. অন্যথায় .. পূর্বাভাস এবং কর্মের একটি সারণীতে চেইনটি বোঝা যায় তবে কেবলমাত্র বৃহত্তর উদাহরণগুলির জন্য। টেবিলটি কিছু জটিলতা এবং নির্দেশনা যুক্ত করে, তাই আপনার এই ধারণাগত ওভারহেডটি আরও বাড়িয়ে তুলতে পর্যাপ্ত এন্ট্রি দরকার। সুতরাং, 4 প্রাকটিক / অ্যাকশন জোড়ার জন্য, সাধারণ মূল কোডটি রাখুন, তবে আপনার যদি 100 থাকে তবে অবশ্যই টেবিলটি সহ যান। ক্রসওভার পয়েন্ট এর মাঝে কোথাও রয়েছে। @ মাস্টার, টেবিলটি স্থিতিশীলভাবে শুরু করা যেতে পারে, সুতরাং প্রিডিকেট / অ্যাকশন জোড় যুক্ত করার জন্য বর্ধিত ওভারহেড এক লাইনে কেবল তাদের নাম দেয়: আরও ভাল করা শক্ত।
স্টিফেন সি স্টিল

2
পঠনযোগ্যতা ব্যক্তিগত নয়। প্রোগ্রামিং পাবলিকের জন্য এটি একটি কর্তব্য। এটা বিষয়গত হয়। কোনটি ঠিক এই কারণেই এই জাতীয় জায়গায় আসা এবং প্রোগ্রামিং পাবলিকদের এর সম্পর্কে কী বলা উচিত তা শুনতে গুরুত্বপূর্ণ। ব্যক্তিগতভাবে আমি এই উদাহরণটি অসম্পূর্ণ দেখতে পাই। আমাকে দেখান কিভাবে নির্মিত conditionsহয় ... এআরজি! টীকা-গুণাবলী নয়! কেন খোদা? আমার চোখের মালিক!
candied_orange

7

return;একটি শর্ত সাফল্যের পরে ব্যবহারের কথা বিবেচনা করুন , এটি আপনাকে সমস্ত সংরক্ষণ করে else। এমনকি return addAlert(1)যদি সেই পদ্ধতির কোনও ফেরতের মান থাকে তবে আপনি সরাসরি সক্ষম হতে পারেন।


3
অবশ্যই, এটি ধরে নিয়েছে যে এর শৃঙ্খলার পরে আর কিছুই ঘটে না if... এটি একটি যুক্তিসঙ্গত অনুমান হতে পারে এবং এটি আবার নাও হতে পারে।
একটি সিভিএন

5

আমি কখনও কখনও এই বিবেচিত ক্লিনার মত নির্মাণ দেখেছি:

switch(true) {
    case cond1(): 
        statement1; break;
    case cond2():
        statement2; break;
    case cond3():
        statement3; break;
    // .. etc
}

ডান ফাঁক দিয়ে টেরানারি একটি ঝরঝরে বিকল্প হতে পারে:

cond1() ? statement1 :
cond2() ? statement2 :
cond3() ? statement3 : (null);

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


1
টার্নারি ঝরঝরে
ইওয়ান

6
@ ইভান একটি ভাঙ্গা "গভীর পুনরাবৃত্তীয় ত্রৈমাসিক" ডিবাগ করা একটি অস্বস্তিকর ব্যথা হতে পারে।
dfri

5
এটা দেখে মনে হচ্ছে যদিও পর্দায় ঝরঝরে।
ইয়ান

আহ, কোন ভাষা caseলেবেলগুলির সাথে ফাংশনগুলি ব্যবহার করতে দেয় ?
আন্ডার কেট

1
@undercat এটি একটি বৈধ ECMAScript / জাভাস্ক্রিপ্ট আফাইক
zworek

1

@ ইভানের উত্তরের বৈকল্পিক হিসাবে আপনি শর্তগুলির একটি শৃঙ্খলা ("ফ্ল্যাট তালিকার পরিবর্তে") তৈরি করতে পারেন:

abstract class Condition {
  private static final  Condition LAST = new Condition(){
     public void alertOrPropagate(DisplayInterface display){
        // do nothing;
     }
  }
  private Condition next = Last;

  public Condition setNext(Condition next){
    this.next = next;
    return this; // fluent API
  }

  public void alertOrPropagate(DisplayInterface display){
     if(isConditionMeet()){
         display.alert(getMessage());
     } else {
       next.alertOrPropagate(display);
     }
  }
  protected abstract boolean isConditionMeet();
  protected abstract String getMessage();  
}

এইভাবে আপনি আপনার শর্তাদি একটি সংজ্ঞায়িত ক্রমে প্রয়োগ করতে পারেন এবং পরিকাঠামো (বিমূর্ত শ্রেণি দেখানো) প্রথম দেখা হওয়ার পরে অবশিষ্ট চেকগুলি এড়িয়ে যায়।

এটিই "ফ্ল্যাট তালিকা" পদ্ধতির চেয়ে উচ্চতর যেখানে আপনাকে শর্তগুলি প্রয়োগ করে এমন লুপে "স্কিপিং" প্রয়োগ করতে হবে।

আপনি কেবল কন্ডিশন চেইন সেটআপ করেছেন:

Condition c1 = new Condition1().setNext(
  new Condition2().setNext(
   new Condition3()
 )
);

এবং সাধারণ কল দিয়ে মূল্যায়ন শুরু করুন:

c1.alertOrPropagate(display);


4
আমি অন্য কারও পক্ষে কথা বলার ভান করব না, তবে প্রশ্নটির কোডটি তাত্ক্ষণিকভাবে পাঠযোগ্য এবং এর আচরণে সুস্পষ্ট হলেও আমি এটিকে কী করে তা অবিলম্বে সুস্পষ্ট বলে বিবেচনা করব না
একটি সিভিএন

0

প্রথমত, আসল কোডটি ভয়ানক আইএমও নয়। এটি বেশ বোধগম্য এবং এর মধ্যে অন্তর্নিহিত খারাপ কিছুই নেই।

তারপরে যদি আপনি এটি অপছন্দ করেন তবে @ ইওনের একটি তালিকা ব্যবহারের ধারণাটি তৈরি করে তবে তার কিছুটা অপ্রাকৃত foreach breakপ্যাটার্ন অপসারণ :

public class conditions
{
    private List<Condition> cList;
    private int position;

    public Condition Head
    {
        get { return cList[position];}
    }

    public bool Next()
    {
        return (position++ < cList.Count);
    }
}


while not conditions.head.check() {
  conditions.next()
}
conditions.head.alert()

এখন এটি আপনার পছন্দের ভাষায় মানিয়ে নিন, তালিকার প্রতিটি উপাদানকে একটি বস্তু, একটি টুপল, যাই হোক না কেন তৈরি করুন এবং আপনি ভাল।

সম্পাদনা: দেখে মনে হচ্ছে এটি এতটা পরিষ্কার নয় যে আমি ভেবেছিলাম, সুতরাং আমাকে আরও ব্যাখ্যা করতে দিন। conditionsকিছু সাজানোর একটি আদেশ তালিকা; headবর্তমান উপাদানটি তদন্ত করা হচ্ছে - শুরুতে এটি তালিকার প্রথম উপাদান এবং প্রতিটি সময়কে next()বলা হয় এটি নিম্নলিখিতটি হয়ে যায়; check()এবং alert()হয় checkConditionX()এবং addAlert(X)ও.পি. থেকে।


1
(ডাউনওয়েট করেনি তবে) আমি এটি অনুসরণ করতে পারি না। মাথা কি ?
-সোফি

@ বেলে আমি উত্তরটি আরও ব্যাখ্যা করার জন্য সম্পাদনা করেছি। এটি ইভানের মত একই ধারণা কিন্তু while notপরিবর্তে এর সাথে foreach break
নিকো

একটি উজ্জ্বল ধারণার একটি উজ্জ্বল বিবর্তন
ইওয়ান

0

প্রশ্নটিতে কিছু সুনির্দিষ্টতার অভাব রয়েছে। শর্তগুলি যদি হয়:

  • পরিবর্তন সাপেক্ষে বা
  • অ্যাপ্লিকেশন বা সিস্টেমের অন্যান্য অংশে পুনরাবৃত্তি বা
  • নির্দিষ্ট ক্ষেত্রে সংশোধিত (যেমন বিভিন্ন বিল্ড, পরীক্ষা, স্থাপনা)

বা যদি বিষয়বস্তুগুলি addAlertআরও জটিল হয়, তবে সি # এর একটি সম্ভবত আরও ভাল সমাধান হ'ল:

//in some central spot
IEnumerable<Tuple<Func<bool>, int>> Conditions = new ... {
  Tuple.Create(CheckCondition1, 1),
  Tuple.Create(CheckCondition2, 2),
  ...
}

//at the original place
var matchingCondition = Conditions.Where(c=>c.Item1()).FirstOrDefault();
if(matchingCondition != null) 
  addAlert(matchingCondition.Item2)

টিপলগুলি সি # <8 এ এত সুন্দর নয়, তবে কনভেনিয়েন্সের জন্য বেছে নেওয়া হয়েছে।

এই পদ্ধতির সুবিধাগুলি, এমনকি উপরের বিকল্পগুলির মধ্যে কোনওটি প্রয়োগ না করা হলেও, কাঠামোটি স্থিতিশীলভাবে টাইপ করা। আপনি দুর্ঘটনাক্রমে স্ক্রু আপ করতে পারবেন না, বলুন, একটি অনুপস্থিত else


0

আপনার প্রচুর পরিমাণে সাইক্লোমেটিক জটিলতা হ্রাস করার সর্বোত্তম উপায় if->then statementsহ'ল অভিধান বা তালিকা ব্যবহার করা মূল মূল্য (যদি বিবৃতি মান বা এর কিছু মান থাকে) সংরক্ষণ (ভাষা নির্ভর) ব্যবহার করা এবং তারপরে একটি মান / ফাংশন ফলাফল।

উদাহরণস্বরূপ, (সি #) এর পরিবর্তে:

if (i > 10) { return "Two"; }
else if (i > 8) { return "Four" }
else if (i > 4) { return "Eight" }
return "Ten";  //etc etc say anything after 3 or 4 values

আমি সহজভাবে করতে পারি

var results = new Dictionary<int, string>
{
  { 10, "Two" },
  { 8, "Four"},
  { 4, "Eight"},
  { 0, "Ten"},
}

foreach(var key in results.Keys)
{
  if (i > results[key]) return results.Values[key];
}

আপনি যদি আরও আধুনিক ভাষা ব্যবহার করে থাকেন তবে আপনি আরও যুক্তি সঞ্চয় করতে পারেন তবে কেবল মান (সি #)। এটি সত্যিই কেবল ইনলাইন ফাংশন, তবে যুক্তিটি যদি ইন-লাইনটি অবলম্বন করতে হয় তবে আপনি কেবল অন্য ফাংশনগুলিতেও নির্দেশ করতে পারেন।

var results = new Dictionary<Func<int, bool>, Func<int, string>>
{
  { (i) => return i > 10; ,
    (i) => return i.ToString() },
  // etc
};

foreach(var key in results.Keys)
{ 
  if (key(i)) return results.Values[key](i);
}

0

আমি চাচা বব এর পরিষ্কার কোড পরামর্শগুলি এবং বিশেষত পদ্ধতিগুলি সংক্ষিপ্ত রাখতে অনুসরণ করার চেষ্টা করছি।

আমি যদিও এই যুক্তিটি সংক্ষিপ্ত করতে নিজেকে অক্ষম মনে করি:

if (checkCondition()) {addAlert(1);}
else if (checkCondition2()) {addAlert(2);}
else if (checkCondition3()) {addAlert(3);}
else if (checkCondition4()) {addAlert(4);}

আপনার কোডটি ইতিমধ্যে খুব ছোট, তবে যুক্তিটি নিজেই পরিবর্তন করা উচিত নয়। প্রথম নজরে দেখে মনে হচ্ছে আপনি চারটি কল দিয়ে নিজেকে পুনরাবৃত্তি করছেন checkCondition()এবং কোডটি সাবধানে পড়ার পরে প্রত্যেকটি আলাদা is আপনার যথাযথ বিন্যাস এবং ফাংশন নাম যুক্ত করা উচিত, যেমন:

if (is_an_apple()) {
  addAlert(1);
}
else if (is_a_banana()) {
  addAlert(2);
}
else if (is_a_cat()) {
  addAlert(3);
}
else if (is_a_dog()) {
  addAlert(4);
}

আপনার কোডটি অন্য সমস্ত কিছুর উপরে পড়তে হবে। চাচা বব এর বেশ কয়েকটি বই পড়ে আমি বিশ্বাস করি যে এই বার্তাটি তিনি ধারাবাহিকভাবে চেষ্টা করার চেষ্টা করছেন।


0

ধরুন যে সমস্ত ফাংশন একই উপাদানে প্রয়োগ করা হয়েছে, আপনি প্রবাহের একাধিক শাখা থেকে মুক্তি পেতে ক্রিয়াকলাপগুলিকে কিছুটা স্থিতি বজায় রাখতে পারবেন।

ইজি: checkCondition1()হয়ে যাবে evaluateCondition1(), যার উপর এটি পূর্বের শর্তটি পূরণ হয়েছে কিনা তা পরীক্ষা করে দেখবে; যদি তাই হয় তবে এটি পুনরুদ্ধার করার জন্য কিছু মানকে ক্যাশে করে getConditionNumber()

checkCondition2()হয়ে যাবে evaluateCondition2(), যার উপর এটি পূর্ববর্তী শর্তগুলি পূরণ করেছে কিনা তা যাচাই করবে। পূর্ববর্তী শর্তটি যদি পূরণ না করা হয়, তবে এটি কন্ডিশনের পরিস্থিতি 2 পরীক্ষা করে, পুনরুদ্ধার করার জন্য একটি মান ক্যাশে করে getConditionNumber()। ইত্যাদি।

clearConditions();
evaluateCondition1();
evaluateCondition2();
evaluateCondition3();
evaluateCondition4();
if (anyCondition()) { addAlert(getConditionNumber()); }

সম্পাদনা করুন:

এই পদ্ধতির কাজের জন্য কীভাবে ব্যয়বহুল শর্তগুলির জন্য চেক প্রয়োগ করা প্রয়োজন তা এখানে's

bool evaluateCondition34() {
    if (!anyCondition() && A && B && C) {
        conditionNumber = 5693;
        return true;
    }
    return false;
}

...

bool evaluateCondition76() {
    if (!anyCondition() && !B && C && D) {
        conditionNumber = 7658;
        return true;
    }
    return false;
}

অতএব, আপনার যদি খুব বেশি ব্যয়বহুল চেক সম্পাদন করতে হয় এবং এই কোডের জিনিসগুলি ব্যক্তিগত থাকে, তবে এই পদ্ধতিকে এটি বজায় রাখতে সহায়তা করে, প্রয়োজনে চেকের ক্রম পরিবর্তন করতে সক্ষম করে।

clearConditions();
evaluateCondition10();
evaluateCondition9();
evaluateCondition8();
evaluateCondition7();
...
evaluateCondition34();
...
evaluateCondition76();

if (anyCondition()) { addAlert(getConditionNumber()); }

এই উত্তরটি অন্য উত্তরগুলি থেকে কিছু বিকল্প পরামর্শ দেয় এবং সম্ভবত আমরা যদি 4 টি লাইনের কোড বিবেচনা করি তবে সম্ভবত মূল কোডের চেয়ে ভাল হবে না। যদিও, এটি কোনও ভয়ানক পদ্ধতি নয় (এবং রক্ষণাবেক্ষণকে অন্যরা যেমন বলেছেন , ততটাই কঠিন করে তোলে না) আমি যে দৃশ্যের কথা উল্লেখ করেছি (অনেকগুলি চেক, কেবল প্রধান ফাংশন পাবলিক হিসাবে প্রকাশিত, সমস্ত ফাংশন একই শ্রেণীর প্রয়োগের বিবরণ)।


আমি এই পরামর্শটি পছন্দ করি না - এটি একাধিক ফাংশনের ভিতরে পরীক্ষার যুক্তি লুকায়। এটি কোড বজায় রাখা শক্ত করে তুলতে পারে যদি উদাহরণস্বরূপ, আপনার ক্রম পরিবর্তন করতে হবে এবং # 2 এর আগে # 3 করা উচিত।
লরেন্স

না। আপনি কিছু পরীক্ষা করতে পারেন যদি কিছু পূর্ববর্তী শর্তটি মূল্যায়ন করা হয় কিনা anyCondition() != false
এমারসন কার্ডোসো

1
ঠিক আছে, আমি দেখতে পাচ্ছি আপনি কী পাচ্ছেন। তবে, যদি (বলুন) শর্ত 2 এবং 3 উভয়ই মূল্যায়ন করে true, ওপি 3 শর্তটি মূল্যায়ন করতে চায় না।
লরেন্স

আমি বলতে চাইছি আপনি anyCondition() != falseফাংশন মধ্যে পরীক্ষা করতে পারেন evaluateConditionXX()। এটি বাস্তবায়ন সম্ভব। যদি অভ্যন্তরীণ অবস্থা ব্যবহারের পদ্ধতির পছন্দ না হয় তবে আমি বুঝতে পারি, তবে এই যুক্তিটি কার্যকর হয় না।
এমারসন কার্ডোসো

1
হ্যাঁ, আমার আপত্তিটি হ'ল এটি অনিচ্ছাকৃতভাবে পরীক্ষার যুক্তি লুকিয়ে রাখে, এটি কাজ করে না এমন নয়। আপনার উত্তরে (অনুচ্ছেদ 3), শর্তাবলীর শর্তাবলীর জন্য 1 চেকটি ইভাল ... 2 () এর ভিতরে রাখা হয়েছে। তবে যদি তিনি শীর্ষ স্তরে (এবং গ্রাহকের প্রয়োজনীয়তার পরিবর্তনের কারণে ইত্যাদি) কন্ডিশন 1 এবং 2 স্যুইচ করেন তবে আপনাকে শর্ত 1 এর চেকটি সরাতে ওয়াল ... 2 () এ যেতে হবে, আরও ভালভাবে যেতে হবে। ..1 () শর্তের জন্য একটি চেক যোগ করার জন্য 2. এটি কাজ করা যেতে পারে, তবে এটি রক্ষণাবেক্ষণে সহজেই সমস্যা তৈরি করতে পারে।
লরেন্স

0

আরও দুটি "অন্য" ধারাগুলি কোডের পাঠককে আগ্রহের একটিটি খুঁজে পেতে পুরো চেইন থেকে যেতে বাধ্য করে। একটি পদ্ধতি ব্যবহার করুন যেমন: অকার্যকর অ্যালার্টআপোনকন্ডিশন (শর্ত শর্ত) {স্যুইচ (শর্ত) {কেস কন্ডিশন.কন 1: ... ব্রেক; কেস কন্ডিশন। কন 2: ... ব্রেক; ইত্যাদি ... "যেখানে" শর্ত "একটি উপযুক্ত এনাম um প্রয়োজনে একটি বুল বা মান ফিরিয়ে দিন। একে এটিকে কল করুন: AlertOnCondition (getCondition ());

এটি সত্যিই কোনও সহজ পেতে পারে না, এবং একবার আপনি কয়েকটি কেস ছাড়িয়ে গেলে if-other চেইনের চেয়ে দ্রুত।


0

আমি আপনার নির্দিষ্ট পরিস্থিতির জন্য কথা বলতে পারি না কারণ কোডটি নির্দিষ্ট নয়, তবে ...

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

পলিমারফিজম আপনার আরও ভাল উপযোগী হতে পারে।

দীর্ঘ বা জটিল যদি লম্বা জটিল থাকে তবে কোডগুলি সন্দেহজনক হতে পারে then আপনি বেশ কয়েকটি ভার্চুয়াল পদ্ধতিতে প্রায়শই সেখানে একটি শ্রেণির গাছ চান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.