এনামগুলি কখন কোনও কোডের গন্ধ হয় না?


17

উভয়সঙ্কট

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

যেমন, আমি খোঁজ করছি নির্দেশিকা এবং / অথবা ব্যবহার-মামলা যেখানে enums হয় না একটি কোড গন্ধ ও একটি বৈধ কনস্ট্রাক্ট আসলে।

সূত্র:

"সতর্কতা থাম্বের একটি নিয়ম হিসাবে, এনামগুলি কোডের গন্ধ এবং এটিকে বহুবর্ষীয় ক্লাসগুলিতে রিফ্যাক্ট করা উচিত [[৮]" সিম্যান, মার্ক,। নেট ইন ডিপেন্ডেন্সি ইনজেকশন, নেট, ২০১১, পৃষ্ঠা। 342

[8] মার্টিন ফোলার এট।, রিফ্যাক্টরিং: বিদ্যমান কোডের নকশা উন্নতি করা (নিউ ইয়র্ক: অ্যাডিসন-ওয়েসলি, 1999), 82।

প্রসঙ্গ

আমার দ্বিধাটির কারণটি একটি ট্রেডিং এপিআই। তারা আমাকে এই পদ্ধতিতে প্রেরণ করে টিক ডেটার একটি স্ট্রিম দেয়:

void TickPrice(TickType tickType, double value)

কোথায় enum TickType { BuyPrice, BuyQuantity, LastPrice, LastQuantity, ... }

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

Dictionary<TickType,double> LastValues

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

এনামগুলি না করা সহজ, তবে ডিওগুলি, এত সহজ নয় এবং আমি যদি লোকেরা তাদের দক্ষতা, উপকারিতা এবং স্বভাবগুলি ভাগ করে নিতে পারি তবে আমি এটির প্রশংসা করব।

দ্বিতীয় চিন্তা

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

নীচে তালিকাবদ্ধ এমন নমুনা শ্রেণীর একটি যেখানে আমার সন্দেহ রয়েছে যে আমি কোনও এনাম ভুল ব্যবহার করছিলাম:

public class ExecutionSimulator
{
  Dictionary<TickType, double> LastReceived;
  void ProcessTick(TickType tickType, double value)
  {
    //Store Last Received TickType value
    LastReceived[tickType] = value;

    //Perform Order matching only on specific TickTypes
    switch(tickType)
    {
      case BidPrice:
      case BidSize:
        MatchSellOrders();
        break;
      case AskPrice:
      case AskSize:
        MatchBuyOrders();
        break;
    }       
  }
}

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

25
কি বই enums একটি কোড গন্ধ বলে? আরও ভাল বই পান
জ্যাকবিবি

3
সুতরাং প্রশ্নের উত্তর হবে "বেশিরভাগ সময়"।
gnasher729

5
একটি সুন্দর, টাইপ নিরাপদ মান যা বোঝায়? এটি নিশ্চিত করে যে কোনও অভিধানে যথাযথ কীগুলি ব্যবহৃত হয়? এটি কখন একটি কোড গন্ধ হয়?

7
প্রসঙ্গ ব্যতীত আমি মনে করি আরও ভাল শব্দটি হবেenums as switch statements might be a code smell ...
প্লিমে

উত্তর:


31

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

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


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

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

@ জুলস - "আপনি যদি নিশ্চিত হন যে কোনও নতুন টিক টাইপ আর কখনও যুক্ত হবে না ..." এই বক্তব্যটি এত স্তরে ভুল is প্রতিটি একক ধরণের একটি শ্রেণি, প্রতিটি ধরণের সত্ত্বেও একই রকম আচরণ থাকা সত্ত্বেও একটি "যুক্তিসঙ্গত" পদ্ধতির থেকে দূরে যতটা সম্ভব এটি পেতে পারে। আপনার ভিন্ন আচরণ না হওয়া এবং যেখানে "রেখাটি আঁকতে হবে" যেখানে "স্যুইচ / যদি-তবে" স্টেটমেন্টের প্রয়োজন না শুরু হয় তা নয়। ভবিষ্যতে আমি আরও এনাম মান যুক্ত করতে পারি কিনা তা অবশ্যই নির্ভর করে না is
ডঙ্ক

@ ডাঙ্ক আমি মনে করি আপনি আমার মন্তব্যকে ভুল বুঝেছেন। আমি কখনও অনুরূপ আচরণের সাথে একাধিক প্রকারের তৈরির পরামর্শ দিইনি - এটি পাগল হবে।
জুলস

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

17

প্রথমত, একটি কোড-গন্ধের অর্থ এই নয় যে কিছু ভুল হয়েছে। এর অর্থ হ'ল কিছু ভুল হতে পারে। enumগন্ধযুক্ত কারণ এটি ঘন ঘন অপব্যবহার করা হয়, তবে এর অর্থ এই নয় যে আপনাকে সেগুলি এড়াতে হবে। কেবলমাত্র আপনি নিজেকে টাইপ করতে enum, থামাতে এবং আরও ভাল সমাধানের জন্য পরীক্ষা করে দেখুন।

বিশেষত যে ঘটনাটি প্রায়শই ঘটে তা হ'ল যখন বিভিন্ন এনামের সাথে বিভিন্ন আচরণের সাথে একই আচরণ করা হয় তবে একই ইন্টারফেস। উদাহরণস্বরূপ, বিভিন্ন ব্যাক-এন্ডের সাথে কথা বলা, বিভিন্ন পৃষ্ঠাগুলি রেন্ডারিং ইত্যাদি pol এগুলি বহুবিধ ক্লাস ব্যবহার করে প্রাকৃতিকভাবে প্রয়োগ করা হয়।

আপনার ক্ষেত্রে, টিকটাইপ বিভিন্ন আচরণের সাথে মিলে না। এগুলি বিভিন্ন ধরণের ইভেন্ট বা বর্তমান রাষ্ট্রের বিভিন্ন বৈশিষ্ট্য। সুতরাং আমি মনে করি এটি একটি এনামের জন্য আদর্শ জায়গা।


আপনি কি বলছেন যে এনামগুলিতে এনট্রি (যেমন রঙ) হিসাবে Nouns থাকে, সেগুলি সম্ভবত সঠিকভাবে ব্যবহৃত হয়। এবং যখন তারা ক্রিয়াগুলি হয় (সংযুক্ত, রেন্ডারিং) তখন এটি একটি চিহ্ন যে এটির অপব্যবহার হচ্ছে?
স্ট্রোমস

2
@ রোস্টস, ব্যাকরণটি সফ্টওয়্যার আর্কিটেকচারের একটি ভয়ঙ্কর গাইড is টিকটাইপ যদি এনামের পরিবর্তে ইন্টারফেস হত, তবে পদ্ধতিগুলি কী হবে? আমি কোনও দেখতে পাচ্ছি না, এ কারণেই এটি আমার কাছে এনাম কেস বলে মনে হচ্ছে। অন্যান্য কেস, যেমন স্ট্যাটাস, রঙ, ব্যাকএন্ড, ইত্যাদি, আমি পদ্ধতিগুলি নিয়ে আসতে পারি এবং সে কারণেই সেগুলি ইন্টারফেস।
উইনস্টন ইওয়ার্ট

@WinstonEwert এবং সম্পাদনা সঙ্গে, এটা মনে হচ্ছে যে তারা হয় বিভিন্ন আচরণে।

OHHH। সুতরাং যদি আমি এনুমের জন্য কোনও পদ্ধতি ভাবতে পারি তবে এটি কোনও ইন্টারফেসের প্রার্থী হতে পারে? এটি একটি খুব ভাল পয়েন্ট হতে পারে।
stromms

1
@ রোস্টস, আপনি কি সুইচের আরও উদাহরণ ভাগ করতে পারেন, তাই আপনি কীভাবে টিকটাইপ ব্যবহার করবেন সে সম্পর্কে আমি আরও ভাল ধারণা পেতে পারি?
উইনস্টন ইওয়ার্ট

8

ডেটা এনামগুলি প্রেরণ করার সময় কোনও কোডের গন্ধ হয় না

আইএমএইচও, যখন enumsকোনও ক্ষেত্রের মধ্যে একটি সীমাবদ্ধ (কদাচিৎ পরিবর্তন) মানগুলির সেট থেকে ভাল হতে পারে তা বোঝাতে ডেটা প্রেরণ করার সময় ।

আমি এটিকে স্বেচ্ছাচারিত stringsবা সংক্রমণের চেয়ে অগ্রাধিকার হিসাবে বিবেচনা করি ints। স্ট্রিংগুলি বানান এবং মূলধনটির বিভিন্নতার কারণে সমস্যা তৈরি করতে পারে। Ints পরিসীমা মূল্যবোধের বাইরে প্রেরণের জন্য অনুমতি দেয় এবং সামান্য শব্দার্থবিদ্যা (আছে যেমন আমি পাই 3আপনার ট্রেডিং পরিষেবা থেকে, এটা কি মানে? LastPrice? LastQuantity? অন্য কিছু?

বস্তু প্রেরণ এবং শ্রেণিবদ্ধ স্তর ব্যবহার সবসময় সম্ভব নয়; উদাহরণস্বরূপ, কোন শ্রেণীর পাঠানো হয়েছে তা প্রাপ্তির আলাদা করার অনুমতি দেয় না।

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

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

সুইচ স্টেটমেন্টগুলি কি খারাপ?

আইএমএইচও, একটি একক- switch স্টেটমেন্ট যা কোনও ভিন্ন ভিন্ন নির্মাতাকে কল করে কোনও enumকোডের গন্ধ নয়। এটি অন্য পদ্ধতির তুলনায় অগত্যা ভাল বা খারাপ নয়, যেমন কোনও টাইপনেমের প্রতিবিম্ব ভিত্তি; এটি প্রকৃত পরিস্থিতির উপর নির্ভর করে।

একটি enumজায়গায় সমস্ত জায়গায় স্যুইচ করা কোড গন্ধ, এমন বিকল্প দেয় যা প্রায়শই ভাল হয়:

  • ওভাররাইড পদ্ধতিতে হায়ারার্কির বিভিন্ন শ্রেণীর অবজেক্ট ব্যবহার করুন; অর্থাত্ পলিমারফিজম।
  • শ্রেণিবিন্যাসের ক্লাসগুলি খুব কমই পরিবর্তিত হয় এবং যখন (অনেক) ক্রিয়াকলাপটি শিথিলভাবে শ্রেণিবদ্ধের সাথে ক্লাসে যোগ করা উচিত তখন দর্শনার্থীর প্যাটার্নটি ব্যবহার করুন।

আসলে, টিকটাইপটি তার হিসাবে একটি হিসাবে প্রেরণ করা হচ্ছে int। আমার মোড়কটি TickTypeএমনটি ব্যবহার করে যা প্রাপ্ত থেকে কাস্ট করা হয় int। বেশ কয়েকটি ইভেন্ট এই টিকটাইপটিকে বন্য বিভিন্ন পরিবর্তনের স্বাক্ষরের সাথে ব্যবহার করে যা বিভিন্ন অনুরোধের প্রতিক্রিয়া। intবিভিন্ন ফাংশনের জন্য নিয়মিত ব্যবহার করা কি সাধারণ অভ্যাস ? যেমন TickPrice(int type, double value)1,3 এবং 6 জন্য ব্যবহার typeকরার সময় TickSize(int type, double valueব্যবহার 2,4, এবং 5? এমনকি এগুলি দুটি ইভেন্টে পৃথক করা কি বুদ্ধিযুক্ত?
stromms

2

আপনি যদি আরও জটিল ধরণের সাথে যান:

    abstract class TickType
    {
      public abstract string Name {get;}
      public abstract double TickValue {get;}
    }

    class BuyPrice : TickType
    {
      public override string Name { get { return "Buy Price"; } }
      public override double TickValue { get { return 2.35d; } }
    }

    class BuyQuantity : TickType
    {
      public override string Name { get { return "Buy Quantity"; } }
      public override double TickValue { get { return 4.55d; } }
    }
//etcetera

তারপরে আপনি নিজের ধরণের প্রতিবিম্বটি থেকে লোড করতে পারেন বা নিজেই এটি তৈরি করতে পারেন তবে এখানে যাবার প্রাথমিক বিষয়টি হ'ল আপনি সলিডের ক্লোজ নীতিটি খুলুন


1

টি এল; ডিআর

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

আমি আমার উত্তরাধিকারের কোডটি টন হিসাবে রিফ্যাক্টর হিসাবে আমাকে ক্ষমা করুন। / দীর্ঘশ্বাস; ^ ডি


কিন্তু কেন?

খুব ভাল পর্যালোচনা কেন এখানে লসটেকিজের ঘটনা তা :

// calculate the service fee
public double CalculateServiceFeeUsingEnum(Account acct)
{
    double totalFee = 0;
    foreach (var service in acct.ServiceEnums) { 

        switch (service)
        {
            case ServiceTypeEnum.ServiceA:
                totalFee += acct.NumOfUsers * 5;
                break;
            case ServiceTypeEnum.ServiceB:
                totalFee += 10;
                break;
        }
    }
    return totalFee;
} 

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

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

পলিমারফিক আচরণ ব্যবহার করতে এটি রিফ্যাক্টর যাক। আমাদের যা প্রয়োজন তা বিমূর্ততা যা আমাদের কোনও পরিষেবার জন্য ফি গণনা করার জন্য প্রয়োজনীয় আচরণ রাখতে দেয়।

public interface ICalculateServiceFee
{
    double CalculateServiceFee(Account acct);
}

...

এখন আমরা ইন্টারফেসের আমাদের কংক্রিট বাস্তবায়নগুলি তৈরি করতে এবং এটিকে [অ্যাকাউন্টে] সংযুক্ত করতে পারি।

public class Account{
    public int NumOfUsers{get;set;}
    public ICalculateServiceFee[] Services { get; set; }
} 

public class ServiceA : ICalculateServiceFee
{
    double feePerUser = 5; 

    public double CalculateServiceFee(Account acct)
    {
        return acct.NumOfUsers * feePerUser;
    }
} 

public class ServiceB : ICalculateServiceFee
{
    double serviceFee = 10;
    public double CalculateServiceFee(Account acct)
    {
        return serviceFee;
    }
} 

আর একটি বাস্তবায়ন মামলা ...

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

private static string _getErrorCKey(int statusCode)
{
    string ret;

    switch (statusCode)
    {
        case StatusCodes.Status403Forbidden:
            ret = "BRANCH_UNAUTHORIZED";
            break;

        case StatusCodes.Status422UnprocessableEntity:
            ret = "BRANCH_NOT_FOUND";
            break;

        default:
            ret = "BRANCH_GENERIC_ERROR";
            break;
    }

    return ret;
}

... সম্ভবত আমার ক্লাসে স্থিতি কোডগুলি মোড়ানো উচিত।

public interface IAmStatusResult
{
    int StatusResult { get; }    // Pretend an int's okay for now.
    string ErrorKey { get; }
}

তারপরে প্রতিবার যখন আমার নতুন ধরণের আইএএমস্ট্যাটাসস রেজাল্টের দরকার হয় তখন আমি এটিকে কোড করি ...

public class UnauthorizedBranchStatusResult : IAmStatusResult
{
    public int StatusResult => 403;
    public string ErrorKey => "BRANCH_UNAUTHORIZED";
}

... এবং এখন আমি নিশ্চিত করতে পারি যে পূর্ববর্তী কোডটি বুঝতে পারে যে এর কোনও IAmStatusResultসুযোগ রয়েছে এবং entity.ErrorKeyআরও সংশ্লেষিত, ডেডেন্ডের পরিবর্তে এর রেফারেন্স রয়েছে _getErrorCode(403)

এবং আরও গুরুত্বপূর্ণ, প্রতিবার আমি যখন নতুন ধরণের রিটার্ন মান যুক্ত করি, এটি পরিচালনা করার জন্য অন্য কোনও কোড যুক্ত করার দরকার নেই । Waddya জানেন, enumএবং switchসম্ভবত কোড গন্ধ ছিল।

লাভ।


কিভাবে কেস যেখানে যেমন সম্পর্কে, আমি আছে বহুরুপী ক্লাস এবং আমি একটি কমান্ড লাইন প্যারামিটার মাধ্যমে ব্যবহার করছি যা এক কনফিগার করতে চান? কমান্ড লাইন -> এনাম -> স্যুইচ / মানচিত্র -> বাস্তবায়নটি বেশ কার্যকর ব্যবহারের ক্ষেত্রে বলে মনে হচ্ছে। আমি মনে করি মূল বিষয়টি হ'ল এনামটি অর্কেস্টেশনের জন্য ব্যবহৃত হয়, শর্তাধীন যুক্তির প্রয়োগ হিসাবে নয়।
পিপীলিকা পি

@ এন্টপি এই ক্ষেত্রে মানটি কেন ব্যবহার করবেন না StatusResult? আপনি তর্ক করতে পারেন যে এনামটি ব্যবহারের ক্ষেত্রে মানব-স্মরণীয় শর্টকাট হিসাবে দরকারী, তবে আমি সম্ভবত এখনও একটি কোড গন্ধ বলব, কারণ এমন ভাল বিকল্প রয়েছে যার জন্য বন্ধ সংগ্রহের প্রয়োজন নেই।
রাফিন

বিকল্প কি? একটি স্ট্রিং? এটি "এনামগুলিকে পলিমারফিজম দিয়ে প্রতিস্থাপন করা উচিত" এর দৃষ্টিকোণ থেকে একটি স্বেচ্ছাসেবী পার্থক্য - হয় পদ্ধতির কোনও ধরণের মান মানচিত্রের প্রয়োজন; এই ক্ষেত্রে এনাম এড়ানো কিছুই অর্জন করে না।
পিপীলিকা পি

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

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

0

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

  • ক্রিয়াকলাপ অনুযায়ী কোডটি সংগঠিত করুন। এক্ষেত্রে আপনি বিভিন্ন ধরণের ট্যাগ করতে একটি গণনা ব্যবহার করতে পারেন এবং প্রতিটি পদ্ধতিতে একটি ট্যাগ রয়েছে যা ডেটা ব্যবহার করে statement
  • ডেটা টাইপ অনুযায়ী কোড সাজান। এই ক্ষেত্রে আপনি একটি ইন্টারফেস দ্বারা গণনা প্রতিস্থাপন করতে পারেন এবং গণনার প্রতিটি উপাদান জন্য একটি বর্গ ব্যবহার করতে পারেন। তারপরে আপনি প্রতিটি ক্লাসে একটি পদ্ধতি হিসাবে প্রতিটি ক্রিয়াকলাপ বাস্তবায়ন করেন।

কোন সমাধান ভাল?

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

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

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

সুতরাং, আপনার অ্যাপ্লিকেশনটি কোন দিকে বিকশিত হতে পারে তা বোঝার চেষ্টা করা উচিত এবং তারপরে একটি উপযুক্ত সমাধান বেছে নেওয়া উচিত।

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

বটমলাইন: এনামগুলিতে অগত্যা কোড গন্ধ হয় না।


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

@ ডেভোউসিনিউ: "আমি যেমন বর্ণনা করি তেমন একজনকে" অপরটির চেয়ে ভাল "হিসাবে দেখি না": আমি বলিনি যে একজন সর্বদা অপরের চেয়ে ভাল। আমি বলেছিলাম যে প্রসঙ্গের উপর নির্ভর করে একজনের চেয়ে অন্যটি ভাল। যেমন অপারেশন বেশী বা কম ঠিক করা হয়েছে এবং আপনি নতুন ধরনের যোগ করার পরিকল্পনা যদি (যেমন একটি GUI সংশোধন paint(), show(), close() resize()অপারেশন এবং কাস্টম উইজেট) তাহলে অবজেক্ট ওরিয়েন্টেড পদ্ধতির অর্থে উত্তম যে এটা খুব প্রভাবিত না করেই একটি নতুন ধরনের যোগ করতে পারবেন প্রচুর বিদ্যমান কোড (আপনি মূলত একটি নতুন শ্রেণি প্রয়োগ করেন যা স্থানীয় পরিবর্তন)।
জর্জিও

আপনি বর্ণিত হিসাবে আমি "উন্নত" হিসাবে দেখছি না অর্থ এই যে আমি দেখতে পাচ্ছি না যে এটি পরিস্থিতির উপর নির্ভর করে। আপনাকে যে পরিমাণ কোড লিখতে হবে তা উভয় পরিস্থিতিতেই একই। পার্থক্যটি হ'ল এক উপায় হ'ল ওওপি (এনামস) এর প্রতিরোধমূলক এবং একটি নয়।
ডেভ কাজিনো

@ ডেভকৌসিনো: আপনার যে পরিমাণ কোড লিখতে হবে তা সম্ভবত স্থানীয় অঞ্চল (উত্স কোডের যে জায়গাগুলিতে আপনাকে পরিবর্তন করতে হবে এবং পুনরায় সংস্থাপিত করতে হবে) পরিবর্তনগুলি খুব মারাত্মকভাবে পরিবর্তিত হবে। যেমন ওওপি-তে, আপনি যদি কোনও ইন্টারফেসে একটি নতুন পদ্ধতি যুক্ত করেন, আপনাকে প্রতিটি শ্রেণীর জন্য একটি প্রয়োগকরণ যুক্ত করতে হবে যা সেই ইন্টারফেসটি প্রয়োগ করে।
জর্জিও

এটি কি কেবল প্রস্থের ভিএস গভীরতার বিষয় নয়? 1 টি পদ্ধতি 10 টি ফাইল বা 10 টি পদ্ধতিতে 1 ফাইল যুক্ত করা হচ্ছে।
ডেভ কাজিনো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.