কোনটি এবং কেন, আপনি ব্যতিক্রম বা রিটার্ন কোডগুলি পছন্দ করেন?


92

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

আমি কৌতুহল থেকে এই জিজ্ঞাসা করছি। ব্যক্তিগতভাবে আমি ত্রুটি রিটার্ন কোডগুলি পছন্দ করি যেহেতু তারা কম বিস্ফোরক এবং ব্যবহারকারী কোডগুলি ব্যর্থতার কার্যকারিতা জরিমানা দিতে বাধ্য না করে যদি তারা না চায়।

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


4
একটি মুরগি বা সফটওয়্যার জগতের ডিম সমস্যা ... চিরকাল বিতর্কযোগ্য। :)
গিশু

সে সম্পর্কে দুঃখিত, তবে আশা করি বিভিন্ন মতামত থাকা লোককে (আমার অন্তর্ভুক্ত) উপযুক্তভাবে বেছে নিতে সহায়তা করবে।
রবার্ট গোল্ড

উত্তর:


107

কিছু ভাষার জন্য (অর্থাত সি ++) রিসোর্সেস ফাঁসের কোনও কারণ হওয়া উচিত নয়

সি ++ আরএআইআই ভিত্তিক।

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

রিটার্ন কোডগুলি আরও ভার্জোজ

এগুলি ভার্জোজ এবং এ জাতীয় কিছুতে বিকাশ ঘটে:

if(doSomething())
{
   if(doSomethingElse())
   {
      if(doSomethingElseAgain())
      {
          // etc.
      }
      else
      {
         // react to failure of doSomethingElseAgain
      }
   }
   else
   {
      // react to failure of doSomethingElse
   }
}
else
{
   // react to failure of doSomething
}

শেষ পর্যন্ত, আপনার কোডটি আইডেন্টেড নির্দেশিকাগুলির একটি সংগ্রহ (আমি উত্পাদন কোডে এই ধরণের কোড দেখেছি)।

এই কোডটি ভাল অনুবাদ করা যেতে পারে:

try
{
   doSomething() ;
   doSomethingElse() ;
   doSomethingElseAgain() ;
}
catch(const SomethingException & e)
{
   // react to failure of doSomething
}
catch(const SomethingElseException & e)
{
   // react to failure of doSomethingElse
}
catch(const SomethingElseAgainException & e)
{
   // react to failure of doSomethingElseAgain
}

কোনটি পরিচ্ছন্নভাবে আলাদা কোড এবং ত্রুটি প্রক্রিয়াকরণ, যা করতে পারেন একটি হতে ভাল জিনিস।

রিটার্ন কোডগুলি আরও ভঙ্গুর

যদি একটি সংকলক থেকে কিছু অস্পষ্ট সতর্কতা না হয় ("phjr" এর মন্তব্য দেখুন), তারা সহজেই উপেক্ষা করা যেতে পারে be

উপরের উদাহরণগুলির সাথে, ধরে নিন যে কেউ তার সম্ভাব্য ত্রুটিটি পরিচালনা করতে ভুলে যায় (এটি ঘটে ...)। "ফিরে" আসার পরে ত্রুটিটিকে উপেক্ষা করা হবে এবং সম্ভবত পরে বিস্ফোরণ হবে (অর্থাত্ একটি NULL পয়েন্টার)। ব্যতিক্রম ছাড়া একই সমস্যা ঘটবে না।

ত্রুটি উপেক্ষা করা হবে না। কখনও কখনও, আপনি এটি বিস্ফোরিত না হওয়া চাই, যদিও ... তাই আপনাকে অবশ্যই সাবধানে বেছে নিতে হবে।

রিটার্ন কোডগুলি কখনও কখনও অনুবাদ করা উচিত

ধরা যাক আমাদের নিম্নলিখিত ফাংশন রয়েছে:

  • doSomething, যা NOT_FOUND_ERROR নামে পরিচিতি ফিরিয়ে আনতে পারে
  • doSomethingElse, যা একটি বুল "মিথ্যা" ফিরিয়ে দিতে পারে (ব্যর্থতার জন্য)
  • doSomeomingElseAgain, যা ত্রুটিযুক্ত বস্তুটি ফিরিয়ে দিতে পারে (__LINE__, __FILE__ এবং অর্ধেক স্ট্যাক ভেরিয়েবলের সাথে।
  • সবকিছুর সাহায্যে doTryToDoSomethingWithAess, ভাল ... উপরের ফাংশনগুলি ব্যবহার করুন, এবং প্রকারের একটি ত্রুটি কোডটি ফিরিয়ে দিন ...

এটির ডাকা ফাংশনগুলির কোনও একটি ব্যর্থ হলে doTryToDoSomethingWithAllThisMess এর ফেরতের প্রকারটি কী?

রিটার্ন কোডগুলি সর্বজনীন সমাধান নয়

অপারেটররা একটি ত্রুটি কোড ফেরত দিতে পারে না। সি ++ কনস্ট্রাক্টরও পারবেন না।

রিটার্ন কোডগুলির অর্থ আপনি এক্সপ্রেশনগুলি চেইন করতে পারবেন না

উপরোক্ত পয়েন্টটির তাত্পর্যপূর্ণ। আমি যদি লিখতে চাই তবে কী হবে:

CMyType o = add(a, multiply(b, c)) ;

আমি পারছি না, কারণ রিটার্নের মান ইতিমধ্যে ব্যবহৃত (এবং কখনও কখনও এটি পরিবর্তন করা যায় না)। সুতরাং রিটার্ন মানটি প্রথম প্যারামিটারে পরিণত হয়, রেফারেন্স হিসাবে পাঠানো হয় ... না হয় not

ব্যতিক্রম টাইপ করা হয়

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

প্রতিটি ধরা পরে বিশেষজ্ঞ করা যেতে পারে।

পুনরায় নিক্ষেপ না করে কখনও ক্যাচ (...) ব্যবহার করবেন না

সাধারণত, আপনার কোনও ত্রুটি লুকানো উচিত নয়। আপনি যদি খুব কম সময়ে পুনরায় নিক্ষেপ না করেন তবে কোনও ফাইলটিতে ত্রুটিটি লগ করুন, একটি বার্তা বাক্স খুলুন, যাই হোক না কেন ...

ব্যতিক্রম হ'ল ... NUKE

ব্যতিক্রম সহ সমস্যাটি হ'ল তাদের অতিরিক্ত ব্যবহার করা চেষ্টা / ক্যাচের পূর্ণ কোড তৈরি করবে। তবে সমস্যাটি অন্য কোথাও: এসটিএল ধারক ব্যবহার করে তার কোডটি কে চেষ্টা করে / ধরবে? তবুও, এই পাত্রে একটি ব্যতিক্রম পাঠাতে পারেন।

অবশ্যই, সি ++ এ কোনও ব্যতিক্রমকে কখনও ডেস্ট্রাক্টর থেকে বেরিয়ে আসতে দেবেন না।

ব্যতিক্রমগুলি হ'ল ... সুসংগত

আপনার থ্রেডটি তার হাঁটুতে আনার আগে তাদের ধরার বিষয়ে নিশ্চিত হন বা আপনার উইন্ডোজ বার্তার লুপের ভিতরে প্রচার করুন।

সমাধান তাদের মিশ্রিত করা যেতে পারে?

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

সুতরাং, একমাত্র প্রশ্ন "এমন কি এমন কিছু যা ঘটেছিল না?"

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

আরেকটি সমাধান হ'ল ত্রুটিটি দেখানো

কখনও কখনও, আপনার সমস্যা হ'ল আপনি ত্রুটি চান না। ব্যতিক্রম বা ত্রুটি রিটার্ন কোডগুলি ব্যবহার করা দুর্দান্ত তবে আপনি ... এটি সম্পর্কে জানতে চান।

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

  • ত্রুটি লগ
  • "আরে, আপনার সমস্যা আছে" দিয়ে একটি বার্তাবক্স খুলুন
  • "আরে, আপনার সমস্যা আছে, আপনি কি ডিবাগ করতে চান" দিয়ে একটি বার্তাবক্স খুলুন

উভয় বিকাশ এবং পরীক্ষায়, এটি ব্যবহারকারীকে সমস্যাটি সনাক্ত করার সময় ঠিক চিহ্নিত করতে সক্ষম করে, এবং তার পরে নয় (যখন কোনও কোড রিটার্ন মান সম্পর্কে বা কোনও ক্যাচের অভ্যন্তরে যত্ন করে)।

উত্তরাধিকারের কোডটিতে যুক্ত করা সহজ। উদাহরণ স্বরূপ:

void doSomething(CMyObject * p, int iRandomData)
{
   // etc.
}

এর মতো এক ধরণের কোড বাড়ে:

void doSomething(CMyObject * p, int iRandomData)
{
   if(iRandomData < 32)
   {
      MY_RAISE_ERROR("Hey, iRandomData " << iRandomData << " is lesser than 32. Aborting processing") ;
      return ;
   }

   if(p == NULL)
   {
      MY_RAISE_ERROR("Hey, p is NULL !\niRandomData is equal to " << iRandomData << ". Will throw.") ;
      throw std::some_exception() ;
   }

   if(! p.is Ok())
   {
      MY_RAISE_ERROR("Hey, p is NOT Ok!\np is equal to " << p->toString() << ". Will try to continue anyway") ;
   }

   // etc.
}

(আমার কাছে একই ধরণের ম্যাক্রো রয়েছে যা কেবলমাত্র ডিবাগ-এ সক্রিয় থাকে)।

মনে রাখবেন যে উত্পাদনে কনফিগারেশন ফাইলটি বিদ্যমান নেই, তাই ক্লায়েন্ট কখনও এই ম্যাক্রোর ফলাফল দেখতে পায় না ... তবে প্রয়োজনের পরে এটি সক্রিয় করা সহজ।

উপসংহার

আপনি যখন রিটার্ন কোডগুলি ব্যবহার করে কোড করেন, আপনি ব্যর্থতার জন্য নিজেকে প্রস্তুত করেন এবং আশা করেন আপনার পরীক্ষার দুর্গ যথেষ্ট নিরাপদ is

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

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


4
হ্যাঁ, তবে আপনার প্রথম উদাহরণ সম্পর্কে, যা সহজেই এইভাবে লেখা যেতে পারে: if( !doSomething() ) { puts( "ERROR - doSomething failed" ) ; return ; // or react to failure of doSomething } if( !doSomethingElse() ) { // react to failure of doSomethingElse() }
বোবোবো

কেন না ... তবে তারপরেও আমি doSomething(); doSomethingElse(); ...আরও ভাল খুঁজে পাচ্ছি কারণ যদি আমাকে / যখন / ইত্যাদি যুক্ত করতে হয়। সাধারণ সম্পাদনের উদ্দেশ্যে বিবৃতি, আমি চাই না যে সেগুলি / যখন / ইত্যাদির সাথে মিশ্রিত হয়। ব্যতিক্রমী উদ্দেশ্যে বয়ান যুক্ত করা হয়েছে ... এবং ব্যতিক্রমগুলি ব্যবহারের আসল নিয়মটি হ'ল নিক্ষেপ করা , ধরা না দেওয়া , চেষ্টা / ধরা বিবৃতি সাধারণত আক্রমণাত্মক হয় না।
পেরেসারবল

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

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

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

36

আমি উভয় ব্যবহার করি।

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

ব্যতিক্রমগুলি কেবলমাত্র সেই জিনিসগুলির জন্যই ব্যবহৃত হয় যা আমি প্রত্যাশা করি না।


খুব সহজ উপায়ের জন্য +1। এটি সংক্ষিপ্ত পর্যায়ে যথেষ্ট যাতে আমি এটি খুব দ্রুত পড়তে পারি। :-)
আশীষ গুপ্ত

4
" ব্যতিক্রমগুলি কেবলমাত্র সেই জিনিসগুলির জন্য ব্যবহৃত হয় যা আমি প্রত্যাশা করি না " "আপনি যদি সেগুলি প্রত্যাশা না করেন তবে কেন বা কীভাবে আপনি সেগুলি ব্যবহার করতে পারেন?
আনার খলিলভ

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

কোনও প্রতিক্রিয়াহীন এসকিউএল সার্ভারকে সহজেই "পরিচিত, সম্ভাব্য ত্রুটি" এর অধীনে শ্রেণিবদ্ধ করা হবে না?
tkburbidge

21

ফ্রেমওয়ার্ক ডিজাইনের গাইডলাইনস: কনভেনশন, আইডিয়ামস এবং পুনরায় ব্যবহারযোগ্য প্যাটার্নস-এ "ব্যাতিক্রম" শিরোনামের অধ্যায় 7 অনুসারে। নেট লাইব্রেরিগুলিতে ও ও ফ্রেমওয়ার্ক যেমন সি # এর জন্য কেন রিটার্ন ভ্যালুতে ব্যতিক্রম ব্যবহার করা প্রয়োজন তার জন্য অনেকগুলি যুক্তি দেওয়া হয়।

সম্ভবত এটি সবচেয়ে আকর্ষণীয় কারণ (পৃষ্ঠা 179):

"ব্যতিক্রমগুলি অবজেক্ট-ওরিয়েন্টেড ভাষাগুলির সাথে ভালভাবে সংহত করেছে Ob অবজেক্ট-ওরিয়েন্টেড ভাষাগুলি সদস্য স্বাক্ষরগুলিতে সীমাবদ্ধতা আরোপ করে যা অ-ওও ভাষায় ফাংশন দ্বারা আরোপিত হয় না example উদাহরণস্বরূপ, কনস্ট্রাক্টর, অপারেটর ওভারলোডস এবং বৈশিষ্ট্যগুলির ক্ষেত্রে বিকাশকারী রিটার্ন মানটিতে কোনও বিকল্প নেই this এই কারণে, অবজেক্ট-ওরিয়েন্টেড ফ্রেমওয়ার্কগুলির জন্য রিটার্ন-মান-ভিত্তিক ত্রুটি প্রতিবেদনের মানক করা সম্ভব নয় An একটি ত্রুটি প্রতিবেদন করার পদ্ধতি, যেমন ব্যতিক্রম যেমন পদ্ধতিটির স্বাক্ষরের ব্যান্ডের বাইরে থাকে which একমাত্র বিকল্প। "


10

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

আপনি যে কোডটি লিখছেন তা সময়-সমালোচনামূলক না হলে স্ট্যাকটি আনওয়াইন্ডিংয়ের সাথে যুক্ত ওভারহেডটি চিন্তার পক্ষে যথেষ্ট তাৎপর্যপূর্ণ নয়।


4
মনে রাখবেন যে ব্যতিক্রমগুলি ব্যবহার করা প্রোগ্রাম বিশ্লেষণকে আরও শক্ত করে তোলে।
পাওয়ে হাজদান

7

ব্যতিক্রমগুলি কেবল তখনই ফিরে আসতে হবে যেখানে এমন কিছু ঘটে যা আপনি প্রত্যাশা করেননি।

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

ব্যতিক্রমগুলি আরও অনেক তথ্য সরবরাহ করতে পারে এবং বিশেষত খুব ভাল বানান করতে পারে 'কিছু ভুল হয়েছে, এখানে কী, একটি স্ট্যাক ট্রেস এবং প্রসঙ্গের জন্য কিছু সহায়ক তথ্য'

বলা হচ্ছে, একটি ভাল গণনা করা রিটার্ন কোড কার্যকর ফলাফলগুলির ज्ञিত সেটগুলির জন্য কার্যকর হতে পারে, একটি সাধারণ 'ফাংশনটির ফলাফল হ'ল, এবং এটি কেবল এই পথে চলে'


6

জাভাতে, আমি ব্যবহার করি (নিম্নলিখিত ক্রমে):

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

  2. প্রক্রিয়াজাতকরণ (এবং প্রয়োজনে রোলব্যাক সম্পাদন করা) সহ ত্রুটি কোডগুলি ফিরিয়ে দেওয়া।

  3. ব্যতিক্রম, তবে এগুলি কেবল অপ্রত্যাশিত জিনিসের জন্য ব্যবহৃত হয় ।


4
চুক্তির জন্য দাবিগুলি ব্যবহার করা কি আরও সঠিক হবে না? চুক্তিটি যদি ভেঙে যায় তবে আপনাকে বাঁচানোর মতো কিছুই নেই।
পাওয়ে হাজদান

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

এবং আপনার প্রশ্নের জবাব বারো বছর। আমার একটি সহায়তা ডেস্ক চালানো উচিত :-)
প্যাক্সিডিয়াবলো

6

রিটার্ন কোডগুলি প্রায় প্রতিবার আমার জন্য " পিট অফ সাফল্য " পরীক্ষায় ব্যর্থ হয় ।

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

পারফরম্যান্স সম্পর্কিত:

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

4

প্রাগমেটিক প্রোগ্রামারটির কাছ থেকে আমি একটি দুর্দান্ত পরামর্শ পেয়েছি "" আপনার প্রোগ্রামটি ব্যতিক্রম কিছু না ব্যবহার করে এর মূল কার্যকারিতাটি সম্পাদন করতে সক্ষম হওয়া উচিত "এর ধারায় কিছু ছিল something


4
আপনি এটির ভুল ব্যাখ্যা দিচ্ছেন। এর অর্থ হ'ল "যদি আপনার প্রোগ্রামটি স্বাভাবিক প্রবাহে ব্যতিক্রম ছুঁড়ে মারে তবে ভুল"। অন্য কথায় "ব্যতিক্রমী জিনিসের জন্য কেবল ব্যতিক্রম ব্যবহার করুন"।
পাওয়ে হাজদান

4

আমি এই সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলাম কিছুক্ষণ আগে।

একটি ব্যতিক্রম নিক্ষেপ কর্মক্ষমতা ওভারহেড আপনার সিদ্ধান্তে কোন ভূমিকা পালন করা উচিত নয়। আপনি যদি এটি সঠিকভাবে করছেন তবে সর্বোপরি একটি ব্যতিক্রম ব্যতিক্রম


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

আমি পুরোপুরি একমত. দেখে মনে হচ্ছে আমি গত নয় বছরে একটি বা দুটি জিনিস শিখেছি;)
থমাস

4

আমি রিটার্ন কোডগুলি অপছন্দ করি কারণ তারা নিম্নলিখিত কোডগুলিকে আপনার কোড জুড়ে মাশরুম তৈরি করে

CRetType obReturn = CODE_SUCCESS;
obReturn = CallMyFunctionWhichReturnsCodes();
if (obReturn == CODE_BLOW_UP)
{
  // bail out
  goto FunctionExit;
}

শীঘ্রই 4 ফাংশন কলযুক্ত একটি পদ্ধতি কলটি 12 টি লাইন ত্রুটি পরিচালনার সাথে ব্লাট আপ হয়ে যায় .. যার কয়েকটি কখনও ঘটবে না। যদি এবং স্যুইচ কেস প্রচুর হয়।

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

কোনও পদ্ধতি কলের পরে যদি আপনার একাধিক রাজ্য থাকে যা আলাদাভাবে পরিচালনা করা উচিত (এবং ব্যতিক্রমী কেস নয়), ত্রুটি কোড বা আউট প্যারাম ব্যবহার করুন। যদিও পার্সোনালি আমি এটি বিরল বলে মনে করেছি ..

আমি 'পারফরম্যান্স পেনাল্টি' পাল্টা সম্পর্কে কিছুটা শিকার করেছি .. সি ++ / সিওএম বিশ্বে আরও নতুন ভাষায় তবে আমি মনে করি পার্থক্যটি তেমন কিছু নয়। যাই হোক না কেন, যখন কোনও কিছু ফুটে ওঠে, তখন পারফরম্যান্সের উদ্বেগগুলি ব্যাকবার্নারে ফিরে যায় :)


3

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


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

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

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

আমি একমত যে ব্যতিক্রমগুলির ডিবাগিং সুবিধাগুলি প্রায়শই পারফরম্যান্স ব্যয়ের জন্য প্রস্তুত হয়।
ডেরেক পার্ক 5

4
ডেরাক পার্ক, ব্যতিক্রম ব্যয়বহুল যখন তারা ঘটে। এ কারণেই তাদের অতিরিক্ত ব্যবহার করা উচিত নয়। কিন্তু যখন এগুলি হয় না, তাদের কার্যত কিছুই হয় না।
প্যার্সেবল

3

আমার নিয়মের একটি সহজ সেট রয়েছে:

1) আপনি অবিলম্বে কলারের প্রতিক্রিয়া প্রত্যাশা করেন এমন জিনিসের জন্য রিটার্ন কোডগুলি ব্যবহার করুন।

2) স্কোপগুলিতে বিস্তৃত ত্রুটিগুলির জন্য ব্যতিক্রমগুলি ব্যবহার করুন, এবং কলারের পক্ষে অনেক স্তরের উপরে এমন কিছু দ্বারা পরিচালনা করা যুক্তিসঙ্গত হতে পারে যাতে ত্রুটি সম্পর্কে সচেতনতা যাতে আরও স্তর তৈরি করে না, কোডকে আরও জটিল করে তোলে।

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


3

আমি ব্যতিক্রমী এবং অ-ব্যতিক্রমী উভয় পরিস্থিতিতেই পাইথনে ব্যতিক্রমগুলি ব্যবহার করি।

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

try:
    dataobj = datastore.fetch(obj_id)
except LookupError:
    # could not find object, create it.
    dataobj = datastore.create(....)

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

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

# wrong way:
if os.path.exists(directory_to_remove):
    # race condition is here.
    os.path.rmdir(directory_to_remove)

# right way:
try: 
    os.path.rmdir(directory_to_remove)
except OSError:
    # directory didn't exist, good.
    pass

দুটি পরিবর্তে একটি সিস্টেম কল, কোনও রেসের শর্ত নেই। এটি একটি দুর্বল উদাহরণ, কারণ স্পষ্টতই এটি OSError এর সাথে ডিরেক্টরিতে উপস্থিত থাকার চেয়ে বেশি পরিস্থিতিতে ব্যর্থ হবে, তবে অনেকগুলি দৃ tight়ভাবে নিয়ন্ত্রিত পরিস্থিতিতে এটি একটি 'যথেষ্ট যথেষ্ট' সমাধান।


দ্বিতীয় উদাহরণ বিভ্রান্তিকর। অনুমানযোগ্যভাবে ভুল উপায় ভুল কারণ os.path.rmdir কোড ব্যতিক্রম ছোঁড়ার জন্য ডিজাইন করা হয়েছে। রিটার্ন কোড প্রবাহে সঠিক বাস্তবায়ন হবে 'যদি rmdir (...) ==
ব্যর্থ

3

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

প্রতি লাইনে রিটার্ন কোডের জন্য একটি স্পষ্ট চেক থাকলে আমি পারফরম্যান্স তুলনা সম্পর্কে নিশ্চিত নই।


4
ব্যতিক্রমগুলি সমর্থন করে না এমন ভাষাগুলির দ্বারা ব্যবহারযোগ্য হওয়ার জন্য ডিজাইন করা COM wad।
কেভিন

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

আমি একমত নই: ভিবি 6 শুধুমাত্র শেষ ত্রুটিটি লগ করে। "পরবর্তী ত্রুটি পুনরায় শুরু করুন" এর সাথে কুখ্যাতদের সাথে একত্রিত হয়ে আপনি যখনই এটি দেখবেন ততক্ষণে আপনার সমস্যার উত্স পুরোপুরি মিস করবেন। নোট করুন যে এটি উইন 32 এপিআইআইয়ের ত্রুটি পরিচালনার ভিত্তি (গেটলাস্টআরার ফাংশন দেখুন)
প্যারাসেবল

2

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


2

বড় পার্থক্যগুলির মধ্যে একটি হ'ল ব্যতিক্রমগুলি আপনাকে একটি ত্রুটি পরিচালনা করতে বাধ্য করে, তবে ত্রুটি রিটার্ন কোডগুলি চেক করা যায় না।

ত্রুটি ফিরিয়ে দেওয়ার কোডগুলি, যদি ভারীভাবে ব্যবহৃত হয়, তবে এই ফর্মের মতো পরীক্ষাগুলির অনুরূপ যদি প্রচুর পরিমাণে কুৎসিত কোডও তৈরি করতে পারে:

if(function(call) != ERROR_CODE) {
    do_right_thing();
}
else {
    handle_error();
}

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


কমপক্ষে সি / সি ++ এবং জিসিসি তে আপনি কোনও ফাংশনকে এমন একটি বৈশিষ্ট্য দিতে পারেন যা তার ফেরতের মানটিকে অগ্রাহ্য করা হলে একটি সতর্কতা তৈরি করবে।
পাওয়ে হাজদান

phjr: যদিও আমি "রিটার্ন ত্রুটি কোড" প্যাটার্নের সাথে একমত নই, আপনার মন্তব্যটি সম্ভবত পুরো উত্তর হয়ে উঠবে। আমি এটি যথেষ্ট আকর্ষণীয় মনে করি। খুব কমপক্ষে, এটি আমাকে একটি দরকারী তথ্য দিয়েছে।
প্যারাসেবল

2

রিটার্ন কোডের চেয়ে ব্যতিক্রম পছন্দ করার অনেক কারণ রয়েছে:

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

2

ব্যতিক্রমগুলি ত্রুটি পরিচালনার জন্য নয়, আইএমও। ব্যতিক্রম শুধু যে; ব্যতিক্রমী ঘটনা যা আপনি প্রত্যাশা করেননি। আমি বলি সাবধানতার সাথে ব্যবহার করুন।

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

এছাড়াও; চেষ্টা-শেষ-প্যাটার্নটি আমার বইয়ের একটি অ্যান্টি-প্যাটার্ন। চেষ্টা-শেষ অবধি ভাল হতে পারে, চেষ্টা-ধরাও ভাল হতে পারে তবে চেষ্টা-ধরা-শেষ পর্যন্ত কখনও ভাল হয় না। চেষ্টা-অবশেষে প্রায়শই একটি "ব্যবহার" স্টেটমেন্ট (আইডিসপোজ প্যাটার্ন) দ্বারা প্রতিস্থাপন করা যেতে পারে, এটি আইএমও আরও ভাল। এবং যেখানে আপনি যে ব্যতিক্রমটি পরিচালনা করতে সক্ষম হচ্ছেন বাস্তবে তা চেষ্টা করুন বা আপনি যদি এটি করেন তবে:

try{
    db.UpdateAll(somevalue);
}
catch (Exception ex) {
    logger.Exception(ex, "UpdateAll method failed");
    throw;
}

সুতরাং যতক্ষণ আপনি ব্যতিক্রমটি বুদবুদ হতে থাকে ঠিক আছে। আর একটি উদাহরণ হ'ল:

try{
    dbHasBeenUpdated = db.UpdateAll(somevalue); // true/false
}
catch (ConnectionException ex) {
    logger.Exception(ex, "Connection failed");
    dbHasBeenUpdated = false;
}

এখানে আমি আসলে ব্যতিক্রমটি পরিচালনা করি; আপডেট পদ্ধতি ব্যর্থ হওয়ার পরে আমি চেষ্টা করার বাইরে যা করি তা অন্য গল্প, তবে আমি মনে করি আমার বক্তব্য তৈরি হয়েছে। :)

তাহলে কেন চেষ্টা করুন-অবশেষে একটি অ্যান্টি-প্যাটার্ন? কারণটা এখানে:

try{
    db.UpdateAll(somevalue);
}
catch (Exception ex) {
    logger.Exception(ex, "UpdateAll method failed");
    throw;
}
finally {
    db.Close();
}

ডিবি অবজেক্টটি ইতিমধ্যে বন্ধ হয়ে গেলে কী হবে? একটি নতুন ব্যতিক্রম নিক্ষেপ করা হয় এবং এটি পরিচালনা করতে হবে! ইহা ভাল:

try{
    using(IDatabase db = DatabaseFactory.CreateDatabase()) {
        db.UpdateAll(somevalue);
    }
}
catch (Exception ex) {
    logger.Exception(ex, "UpdateAll method failed");
    throw;
}

বা, যদি ডিবি অবজেক্ট আইডিস্পোজেবল বাস্তবায়ন না করে তবে এটি করুন:

try{
    try {
        IDatabase db = DatabaseFactory.CreateDatabase();
        db.UpdateAll(somevalue);
    }
    finally{
        db.Close();
    }
}
catch (DatabaseAlreadyClosedException dbClosedEx) {
    logger.Exception(dbClosedEx, "Database connection was closed already.");
}
catch (Exception ex) {
    logger.Exception(ex, "UpdateAll method failed");
    throw;
}

যাইহোক এটি আমার 2 সেন্ট! :)


কোনও অবজেক্ট থাকলে এটি আশ্চর্যজনক হবে lo বন্ধ করুন () তবে নেই। ডিসপোজ ()
অ্যাব্যাটিশচেভ

আমি উদাহরণ হিসাবে কেবল ক্লোজ () ব্যবহার করছি। এটিকে অন্য কিছু মনে করে নির্দ্বিধায়। আমি যেমন বলেছি; যদি পাওয়া যায় তবে ব্যবহারের প্যাটার্নটি ব্যবহার করতে হবে (দোহ!)। এটি অবশ্যই বোঝায় যে ক্লাসটি আইডিস্পোজেবল প্রয়োগ করে এবং যেমন আপনি ডিসপোজ কল করতে পারেন।
noocyte

1

আমি কেবল ব্যতিক্রম ব্যবহার করি, কোনও রিটার্ন কোড নেই। আমি এখানে জাভা সম্পর্কে কথা বলছি।

আমি যে সাধারণ নিয়ম অনুসরণ করি তা হ'ল যদি আমার কাছে কোনও পদ্ধতি বলা হয় doFoo()তবে এটি অনুসরণ করে যে এটি যদি "ফু" না করে, যেমনটি ছিল, তবে ব্যতিক্রমী কিছু ঘটেছে এবং একটি ব্যতিক্রম নিক্ষেপ করা উচিত।


1

ব্যতিক্রম সম্পর্কে আমি যে বিষয়টিকে ভয় করি তা হ'ল একটি ব্যতিক্রম ছুঁড়ে দেওয়া কোড প্রবাহকে পাতায় ফেলে। আপনি যদি উদাহরণস্বরূপ

void foo()
{
  MyPointer* p = NULL;
  try{
    p = new PointedStuff();
    //I'm a module user and  I'm doing stuff that might throw or not

  }
  catch(...)
  {
    //should I delete the pointer?
  }
}

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


<কোড> অবশেষে </ কোড> বিবৃতিটি এটির জন্য। তবে হায় আফসোস, এটি সি ++ স্ট্যান্ডার্ডে নেই ...
থমাস

C ++ আপনি চলতি রীতি থেকে "অর্জন সম্পদ construcotor মধ্যে থাকা উচিত এবং তাদের destrucotor মধ্যে মুক্তির জন্য এই বিশেষ ক্ষেত্রে auto_ptr শুধু prefectly চেষ্টা করতে
সার্জ

থমাস, আপনি ভুল বলেছেন। সি ++ শেষ পর্যন্ত এটির প্রয়োজন নেই কারণ এটির প্রয়োজন নেই। এটির পরিবর্তে আরএআইআই রয়েছে। সার্জের সমাধান হ'ল আরএআইআই ব্যবহার করে একটি সমাধান।
প্যার্সেবল

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

1

বনাম রিটার্ন কোড যুক্তি ব্যতীত আমার সাধারণ নিয়ম:

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

আপনি l10n / i18n করার সময় কোনও ব্যতিক্রম ব্যবহার করতে না পারার কোনও কারণ নেই। ব্যতিক্রমগুলিতে স্থানীয় তথ্যও থাকতে পারে।
গ্যাজেট

1

আমি ব্যতিক্রমগুলির তুলনায় রিটার্ন কোডগুলি কম কুশ্রী হতে পাই না। ব্যতিক্রম সঙ্গে, আপনি আছে try{} catch() {} finally {}আগমন কোড সঙ্গে যেমন আপনার আছে যেখানে if(){}। আমি পোস্টে দেওয়া কারণে ব্যতিক্রমগুলি ভয় করতাম; আপনি জানেন না যে পয়েন্টারটি সাফ করা দরকার, আপনার কী আছে। তবে আমি মনে করি যে রিটার্ন কোডগুলির ক্ষেত্রে এটি একই সমস্যা রয়েছে। প্রশ্নে ফাংশন / পদ্ধতি সম্পর্কে আপনি কিছু বিশদ না জানলে আপনি প্যারামিটারগুলির অবস্থা জানেন না।

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

আমি ফলাফলের জন্য কোনও মান (গণনা?) ফেরত দেওয়ার ধারণা এবং একটি ব্যতিক্রমী মামলার ব্যতিক্রম পছন্দ করি।


0

জাভার মতো ভাষার জন্য আমি ব্যতিক্রমের সাথে যাব কারণ ব্যতিক্রমগুলি পরিচালনা না করা হলে সংকলক সংকলন সময় ত্রুটি দেয় T এটি কলিং ফাংশনটিকে ব্যতিক্রমগুলি পরিচালনা / নিক্ষেপ করতে বাধ্য করে।

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


0

আমি সাধারণত রিটার্ন কোডগুলি পছন্দ করি কারণ কলর ব্যর্থতা ব্যতিক্রমী কিনা তা সিদ্ধান্ত নিতে দেয়

এই পদ্ধতিটি এলিক্সির ভাষায় সাধারণ।

# I care whether this succeeds. If it doesn't return :ok, raise an exception.
:ok = File.write(path, content)

# I don't care whether this succeeds. Don't check the return value.
File.write(path, content)

# This had better not succeed - the path should be read-only to me.
# If I get anything other than this error, raise an exception.
{:error, :erofs} = File.write(path, content)

# I want this to succeed but I can handle its failure
case File.write(path, content) do
  :ok => handle_success()
  error => handle_error(error)
end

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

with {:ok, content} <- get_content(),
  :ok <- File.write(path, content) do
    IO.puts "everything worked, happy path code goes here"
else
  # Here we can use a single catch-all failure clause
  # or match every kind of failure individually
  # or match subsets of them however we like
  _some_error => IO.puts "one of those steps failed"
  _other_error => IO.puts "one of those steps failed"
end

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

# Raises a generic MatchError because the return value isn't :ok
:ok = File.write(path, content)

# Raises a File.Error with a descriptive error message - eg, saying
# that the file is read-only
File.write!(path, content)

কলকারী হিসাবে আমি যদি জানি যে লেখাগুলি ব্যর্থ হয় তবে আমি ত্রুটি বাড়াতে চাই, আমি File.write!পরিবর্তে কল করতে পারি File.write। অথবা আমি File.writeব্যর্থতার সম্ভাব্য প্রতিটি কারণকে আলাদাভাবে কল করতে এবং পরিচালনা করতে বেছে নিতে পারি ।

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

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