ক্রিয়াকলাপ সত্য / মিথ্যা বনাম ফিরে আসা অকার্যকর যখন সফল হয় এবং ব্যর্থ হওয়ার সময় একটি ব্যতিক্রম ছুঁড়ে


22

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

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

এটি কি একটি ভাল অনুশীলন বা কোনও বস্তুটি ভালভাবে ফিরিয়ে দেওয়া (ভিতরে বুলিয়ান, একটি anচ্ছিক ত্রুটি বার্তা এবং ত্রুটির জন্য এনাম) দিয়ে দেওয়া ভাল?



59
সত্য এবং মিথ্যা ভাল একসাথে যেতে। অকার্যকর এবং ব্যতিক্রম একসাথে ভাল যেতে। সত্য এবং ব্যতিক্রম বিড়াল এবং করের মতো একসাথে যায়। কোনও দিন আমি আপনার কোডটি পড়ছি। দয়া করে আমার সাথে এটি করবেন না
candied_orange

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

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

4
@ ড্যানপ্যান্ট্রি জাভাতে, কল স্ট্যাকটি ব্যতিক্রম তৈরি করার সময় পরীক্ষা করা হয় , নিক্ষেপ করার সময় নয়। fillInStackTrace();ক্লাসে সুপার কনস্ট্রাক্টর নামে ডাকা হয়Throwable
সাইমন ফোরসবার্গ

উত্তর:


35

একটি ব্যতিক্রম নিক্ষেপ করা কোনও পদ্ধতির কোনও মূল্য ফেরত দেওয়ার সহজ উপায়। কলার একটি ব্যতিক্রম ধরা ঠিক তত সহজে রিটার্নের মানটি পরীক্ষা করে দেখতে পারে check সুতরাং, মধ্যে সিদ্ধান্ত নেওয়া throwএবং returnঅন্যান্য মানদণ্ড প্রয়োজন।

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

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


7
যদি ফাইল আপলোডের অনুরোধটি ব্যর্থ হওয়ার প্রত্যাশিত ফলাফল হয় তবে আমি আমার মুখে ফেলে দেওয়া একটি ব্যতিক্রম দেখে অবাক হয়ে যাব (বিশেষত যদি পদ্ধতিটির স্বাক্ষরে কোনও ফেরতের মান থাকে)।
হাফমেল

1
নোট করুন যে এটি একটি স্ট্যান্ডার্ড ব্যতিক্রম বাড়ানোর কারণ হ'ল অনেক (সম্ভবত বেশিরভাগ) কলার সমস্যা সমাধানের চেষ্টা করার জন্য কোড লিখবেন না । ফলস্বরূপ, বেশিরভাগ কলকারীরা তাদের স্পষ্টভাবে সমস্ত তালিকাভুক্ত না করেই একটি সহজ, "ব্যাতিক্রমের এই বড় দলটি ধরুন" চাইবেন।
jpmc26

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

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

10
নোট করুন যে একটি ফাংশন যা আপনাকে জানায় যে কোনও ফাইল উপস্থিত রয়েছে কিনা এবং এমন একটি ফাংশন যা কোনও ফাইল উপস্থিত রয়েছে তা দৃ .়ভাবে জানায়, ফাইলটি বিদ্যমান নেই বা না তা ব্যতিক্রমী। লোকেরা মাঝে মাঝে এমন কথা বলে যে এটি "ব্যতিক্রমী" কিনা তা ত্রুটির শর্তের সম্পত্তি। এটি ত্রুটি শর্তের সম্পত্তি নয়, এটি ত্রুটি শর্তের সংযুক্ত সম্পত্তি এবং এটি ঘটে যাওয়া ফাংশনের উদ্দেশ্য Otherwise অন্যথায় আমরা কখনই ব্যতিক্রমগুলি ধরতে চাই না।
স্টিভ জেসোপ

31

trueযদি আপনি falseব্যর্থতায় ফিরে না যান তবে সাফল্যে ফিরে আসার কোনও কারণ নেই । ক্লায়েন্ট কোড দেখতে কেমন হবে?

if (result = tryMyAPICall()) {
    // business logic
}
else {
    // this will *never* happen anyways
}

এই ক্ষেত্রে, কলারের যেভাবেই হোক ট্রাই-ক্যাচ ব্লক প্রয়োজন, তবে তারপরে তিনি আরও ভাল করে লিখতে পারেন:

try {
    result = tryMyAPICall();
    // business logic
    // will only reach this line when no exception
    // no reason to use an if-condition
} catch (SomeException se) { }

সুতরাং trueরিটার্ন মান কলারের জন্য সম্পূর্ণ বেআইনী। সুতরাং শুধু পদ্ধতি রাখুন void


সাধারণভাবে, ব্যর্থ মোডগুলি ডিজাইন করার জন্য তিনটি উপায় রয়েছে।

  1. সত্য / মিথ্যা প্রত্যাবর্তন
  2. ব্যবহারের void, থ্রো (চেক করা) ব্যতিক্রম
  3. একটি মধ্যবর্তী ফলাফল অবজেক্ট ফিরে ।

ফিরে true/false

এটি বেশ কয়েকটি পুরানো, বেশিরভাগ সি স্টাইলের এপিআইতে ব্যবহৃত হয়। ডাউনসাইডগুলি ওভিভিউস, কী ভুল হয়েছে তা আপনার কোনও ধারণা নেই। পিএইচপি বেশিরভাগ ক্ষেত্রে এটি করে, এর ফলে কোড তৈরি হয়:

if (xyz_parse($data) === FALSE)
   $error = xyz_last_error();

বহু-থ্রেডযুক্ত প্রসঙ্গে, এটি আরও খারাপ।

ব্যতিক্রম ছোঁড়া (চেক করা)

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

রিটার্ন রেজাল্ট অবজেক্ট

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

ValidationResult result = parser.validate(data);
if (result.isValid())
    // business logic
else
    error = result.getvalidationError();

কলার জন্য ভাল, পরিষ্কার যুক্তি।

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

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


5

এটি ব্যর্থতা ব্যতিক্রমী বা প্রত্যাশিত কিনা তা সত্যই নেমে আসে ।

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

অন্যদিকে ত্রুটিগুলি যদি সাধারণ হয় তবে আপনার বিকাশকারী যারা তাদের জন্য যাচাই করছেন তাদের জন্য আপনার অনুকূলিত হওয়া উচিত, এবং try-catchধারাগুলি একটি if/elifবা switchসিরিজের চেয়ে কিছুটা জটিল umbers

যিনি ব্যবহার করছেন তার মানসিকতায় সর্বদা একটি এপিআই ডিজাইন করুন।


1
আমার ক্ষেত্রে, যেমন কেউ কারও ইশারা করেছে, ব্যতিক্রমী ব্যর্থতা হওয়া উচিত যা এপিআই ব্যবহারকারী ফাইল আপলোড করতে পারে না।
একল্লাটিভো

4

আপনি কখনই ফেরার ইচ্ছা না রাখলে কোনও বুলিয়ান ফিরিয়ে দেবেন না false। কেবল পদ্ধতি voidএবং নথিটি তৈরি করুন যা এটি IOExceptionব্যর্থতার ক্ষেত্রে একটি ব্যতিক্রম ( উপযুক্ত) ফেলে দেবে ।

এর কারণ হ'ল আপনি যদি কোনও বুলিয়ান ফিরিয়ে দেন তবে আপনার এপিআই এর ব্যবহারকারী সিদ্ধান্ত নিতে পারে যে সে এই কাজটি করতে পারে:

if (fileUpload(file) == false) {
    // Handle failure.
}

এটি অবশ্যই কাজ করবে না; এটি হ'ল আপনার পদ্ধতির চুক্তি এবং এর আচরণের মধ্যে একটি অসামঞ্জস্যতা রয়েছে। যদি আপনি একটি চেক করা ব্যতিক্রম নিক্ষেপ করেন তবে পদ্ধতির ব্যবহারকারীর ব্যর্থতাটি পরিচালনা করতে হবে:

try {
    fileUpload(file);
} catch (IOException e) {
    // Handle failure.
}

3

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

কোনও পদ্ধতির চূড়ান্ত পদক্ষেপ না হলে কোনও পদ্ধতি নিক্ষেপ ব্যতিক্রমী হওয়াও বিরক্তিকর। একটি ক্রিচ-ক্যাচ লিখতে এবং নিয়ন্ত্রণের প্রবাহকে ক্যাচ ব্লকে ডাইভার্ট করা স্প্যাগেটির জন্য একটি ভাল রেসিপি এবং এড়ানো উচিত।

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


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