একই ফাংশন / পদ্ধতিতে ব্যতিক্রম ছোঁড়া এবং ধরা


10

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

অন্যান্য বিকাশকারীরা এ সম্পর্কে কী ভাবছেন তা অবাক করি। আমি সম্ভবত ফাংশন ব্যতিক্রম অপব্যবহার করছি। জাভাতে কোডটি এখানে:

private static int sideInput()
{
    int side = 0;
    String input;
    Scanner scanner = new Scanner(System.in);

    do {
        System.out.print("Side length: ");
        input = scanner.nextLine();
        try {
            side = Integer.parseInt(input);
            if (side <= 0) {
                // probably a misuse of exceptions
                throw new NumberFormatException();
            }
        }
        catch (NumberFormatException numFormExc) {
            System.out.println("Invalid input. Enter a natural number.");
        }
    } while (side <= 0);

    return side;
}

আমি দুটি বিষয়ে আগ্রহী:

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

জিনিসটি আমি প্রায়শই একটি পৃথক ইনপুট ফাংশন লিখি। যদি ব্যবহারকারীকে একাধিকবার ইনপুট করতে হয় তবে আমি ইনপুটটির জন্য একটি পৃথক ফাংশন তৈরি করি যা সমস্ত ফর্ম্যাটিং ব্যতিক্রম এবং সীমাবদ্ধতাগুলি পরিচালনা করে।


উচ্চতর ভাষার উপর নির্ভর করে। কিছু ভাষাগুলি অন্যদের চেয়ে অবাধে ব্যতিক্রম ব্যবহার করে।
মার্টিন ইয়র্ক

উত্তর:


11

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

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


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

1
@ অ্যাসার: এই উত্তরটি সিস্টেমের বাকি অংশগুলি কীভাবে একসাথে কাজ করার জন্য বোঝানো হয়েছে তার উপর অনেক বেশি নির্ভর করে। ব্যতিক্রমগুলি কোনও সময়ে পরিচালনা করা দরকার। আপনি এটি সংগঠিত করতে কয়েকটি ভিন্ন উপায় রয়েছে এবং এটি তাদের মধ্যে একটি of যা আমাদের কাছে নেই অন্যান্য তথ্যের উপর সবচেয়ে ভাল যা নির্ভর করে।
আনহোলিস্যাম্পলার

4

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

কেন একেবারেই ব্যতিক্রম ব্যবহার করবেন? কোন ইনপুটটি অনুমোদিত নয় তা যদি আপনি জানেন তবে ব্যবহারকারীর কাছ থেকে বৈধ ইনপুট না পাওয়া পর্যন্ত কেবল লুপটি ভেঙে ফেলবেন না, নীচের মতো কিছু:

while (true)
{
   // Get user input.
   String input = scanner.nextLine();

   try
   {
      side = Integer.parseInt(input);

      break;
   }
   catch (NumberFormatException ex)
   {
      // Inform user of invalid input.
      System.out.println("Invalid input. Enter a natural number.");
   }
}

Integer.intParse একটি ফর্ম্যাট ব্যতিক্রম ছুঁড়ে ফেলেছে তাই ক্যাচ স্টেটমেন্ট ব্যবহার করা পুরোপুরি বৈধ। আমি মূলত জানতে চাই যে কোনও ফাংশনে লুপে ক্যাচ স্টেটমেন্টটি ব্যবহার করা ঠিক আছে বা আমি ফাংশনটির কলকারীকে হ্যান্ডেল ফর্ম্যাটটি ব্যতিক্রম করতে দেওয়া উচিত।
usr

Integer.parseInt()NumberFormatExceptionএটি সরবরাহিত স্ট্রিং আর্গুমেন্টটিকে পার্স করতে না পারলে একটি ছুড়ে ফেলে । ব্যতিক্রমটি নিজেই ফেলে দেওয়ার দরকার নেই (এবং আপনি সক্ষম হবেন না)।
বার্নার্ড

আমি কোডের উদাহরণটি আরও স্পষ্ট করার জন্য সম্পাদনা করেছি।
বার্নার্ড

"এবং আপনি নিজেই ব্যতিক্রমটি ছুঁড়ে ফেলতে পারবেন না" - সেখানে আপনি কী বোঝাতে চাইছেন?
মাইকেল বর্গওয়ার্ট

@ মিশেল বার্গওয়ার্ট: আমি বলতে চাইছি যেহেতু Integer.parseInt()পদ্ধতিটি যদি আপনার জন্য ব্যতিক্রম ঘটায় তবে তা এহেতু নিক্ষেপ করা হওয়ায় আপনি এটি পরে ছুঁড়ে ফেলতে পারবেন না।
বার্নার্ড

1

যদি আপনি বর্তমান পদ্ধতি কলের সাথে প্রাসঙ্গিক কোনও কিছু করতে চান তবে কেবল ব্যতিক্রমগুলি ধরুন; অর্থাত্ ক্লিনআপ, ব্যর্থতার যুক্তি ইত্যাদি this এই ক্ষেত্রে, ধরাটি কেবল কনসোলে একটি বার্তা প্রেরণ করছে, এটি সাইড ইনপুট পদ্ধতির সাথে প্রাসঙ্গিক নয়, সুতরাং এটি কল চেইন / স্ট্যাককে আরও সামলানো যেতে পারে।

এখানে চেষ্টা / ধরার হাত থেকে মুক্তি পেতে পারেন এবং কেবল পদ্ধতি কলটি নথিভুক্ত করতে পারেন:

//Throws NumberFormatException if read input is less than 0
private static int sideInput()

একটি এখনও কল চেইন / স্ট্যাক আপ যে ব্যতিক্রম পরিচালনা করতে হবে!


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

1

কোনও পদ্ধতিতে আপনার একই ব্যতিক্রম দুটি ছুঁড়ে ফেলা উচিত নয়, এমনকি আমি মনে করি যে ক্যাচ ব্লকটি আপনি ছুঁড়ে ফেলছেন একই ব্যতিক্রমটি ধরবে, তাই আপনি সত্যিই এটি ছুঁড়ে ফেলছেন না।

যদি parseIntসফল হয়, তবে এটি একটি নয় NumberFormatException

যদি পাশটি শূন্যের চেয়ে কম হয় তবে আপনার একটি নিক্ষেপ করা উচিত NegativeSideLengthException;

নামে একটি কাস্টম / বসসনেস ব্যতিক্রম তৈরি করুন NegativeSideLengthException

public class NegativeSideLengthException extends Exception
{


    public NegativeSideLengthException(Integer i)
    {
        super("Invalid negative side length "+i);        
    }

}

তারপরে sideInputNegativeSideLengthException নিক্ষেপ করুন

private static int sideInput() throws NegativeSideLengthException
{
    int side = 0;
    String input;
    Scanner scanner = new Scanner(System.in);

    do {
        System.out.print("Side length: ");
        input = scanner.nextLine();
        try {
            side = Integer.parseInt(input);
            if (side <= 0) {
                throw new NegativeSideLengthException(side);
            }
        }
        catch (NumberFormatException numFormExc) {
            System.out.println("Invalid input. Enter a natural number.");
        }
    } while (side <= 0);

    return side;
}

এমনকি আপনি (যদি আপনি চান) ধরতে অন্য ক্যাচ ব্লক যুক্ত করতে NegativeSideLengthExceptionপারেন এবং পদ্ধতিটি নিক্ষেপ না করে।

do {
    System.out.print("Side length: ");
    input = scanner.nextLine();
    try {
        side = Integer.parseInt(input);
        if (side <= 0) {
            throw new NegativeSideLengthException(side);
        }
    }
    catch (NumberFormatException numFormExc) {
        System.out.println("Invalid input. Enter a natural number.");
    } catch (NegativeSideLengthException e){
        System.out.println("Invalid input. Enter a non-negative number.");
    }
} while (side <= 0);

পতাকা ব্যতিক্রমগুলি হ্যান্ডেল করার ভাল উপায় নয়।


-1

ব্যতিক্রমগুলি বেশ দুঃস্বপ্নের জিনিস, তারা সমাধানের চেয়ে জটিলতা এনে দেয়।

প্রথমত, আপনি যদি নিজের ব্যতিক্রমগুলি না ধরেন তবে কলকারী কেবলমাত্র on error resume nextএক সপ্তাহের পরে তা করতে পারে, এমনকি আপনার ফাংশনটি কী ফেলতে পারে এবং এটি দিয়ে কী করতে হবে তা আপনি জানতে পারবেন না:

{
    ...
}
catch(OutOfMemory, CorruptedMemory, BadData, DanglingPointers, UnfinishedCommit)
{
    Console.WriteLine("Nothing to see here, move on.");
    Console.WriteLine("The app is very stable, see, no crashing!");
}

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

এছাড়াও, মজার বিষয়টি হ'ল যদি আপনার যদি সত্যিই ব্যতিক্রমগুলি পরিচালনা করার কোনও সুযোগ থাকে তবে আপনার আসল RAII ভাষা দরকার, যা জাভা এবং .NET ব্যতিক্রম সম্পর্কে সমস্ত কিছু ...

আরও একবার এই পুনরাবৃত্তি, কিন্তু ...:

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html


4
-1 অন্তত প্রসঙ্গ / ভাষার নির্ভরশীল এ সীমান্তরেখা গলাবাজি না বেশ সঠিক -অথবা পূর্ণ পোস্ট করার জন্য - বিবৃতি, পরিবর্তে ওপি প্রকৃত প্রশ্নের উত্তর।
পিয়েটার টারিক

@ পেটারট্রিক: "একজনকে একটি মাছ দিন এবং আপনি তাকে একদিনের জন্য খাওয়ান a একজন মানুষকে মাছ ধরতে শেখান এবং আপনি আজীবন তাকে খাওয়ান" " ব্যতিক্রমগুলির পিছনে খুব গুরুতর সমস্যা রয়েছে এবং লোকেরা তাদের জানা উচিত -1000 / + 1, আমি সত্যিই যত্ন করি না।
কোডার

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

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

2
ঠিক আছে, সুতরাং কিভাবে কোড ব্যতিক্রম ব্যবহার না করে? জি, আপনি প্রতিটি একক লাইনটি পরীক্ষা করে দেখতে কোডটির মাধ্যমে ক্রল করতে হবে তা দেখতে যে রিটার্নের মানগুলি সঠিকভাবে পরিচালনা করা হয় বা উপেক্ষা করা হয়। এবং যখন কোনও ফেরতের মান অগ্রাহ্য করা হয়, আপনার অ্যাপ্লিকেশন কয়েক হাজার লাইন পরে ক্র্যাশ না করা পর্যন্ত কোনও নোট বিজ্ঞপ্তি দেয়। ব্যতিক্রমগুলি অন্তত আপনাকে নোটিশ নিতে বাধ্য করে । হ্যাঁ, আপনি এগুলি গ্রাস করতে পারেন - তবে কেবল স্পষ্টতই catch। যখন উপেক্ষা করা ফেরতের মান অদম্য হয় - এটি কেবল লাইন বাই লাইন কোড পর্যালোচনার মাধ্যমে সনাক্তযোগ্য। সর্বশেষে তবে অন্তত নয়, নির্মাতাদের কোনও রিটার্ন মান নেই, ব্যতিক্রমগুলি ব্যবহার করার এটিই সর্বাধিক কারণ।
প্যাটার টারিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.