আমি মনে করি আপনি একই ব্রুস একেল সাক্ষাত্কারটি পড়েছিলেন - এবং এটি আমাকে সর্বদা বগল করে তোলে। প্রকৃতপক্ষে, যুক্তিটি ইন্টারভিউওয়ালির দ্বারা করা হয়েছিল (এটি যদি আপনি প্রকৃতপক্ষে পোস্টের কথা বলছেন) আন্ডার হেজলসবার্গ, এমএসের প্রতিভা .NET এবং C # এর পিছনে।
http://www.artima.com/intv/handcuffs.html
অনুরাগী যদিও আমি হিজলসবার্গ এবং তার কাজের মধ্যে আছি, এই যুক্তি আমাকে সর্বদা বগু হিসাবে আঘাত করেছে। এটি মূলত:
"চেক করা ব্যতিক্রমগুলি খারাপ কারণ প্রোগ্রামাররা তাদের সর্বদা তাদের ধরে ফেলে এবং বরখাস্ত করার মাধ্যমে কেবল তাদের অপব্যবহার করে যা সমস্যাগুলি গোপনে এবং উপেক্ষা করার দিকে পরিচালিত করে যা অন্যথায় ব্যবহারকারীর সামনে উপস্থাপিত হবে"।
দ্বারা "অন্যথায় ব্যবহারকারীর কাছে উপস্থাপিত" আপনি একটি রানটাইম ব্যতিক্রম ব্যবহার আমি বলতে চাচ্ছি অলস প্রোগ্রামার শুধু উপেক্ষা করবে (একটি খালি ধরা ব্লক সঙ্গে এটি সংক্রামক বনাম) এবং ব্যবহারকারী এটিকে দেখতে হবে।
যুক্তির সারাংশ সারসংক্ষেপ যে "প্রোগ্রামাররা সঠিকভাবে এবং ব্যবহার করে সেগুলি সঠিকভাবে তাদের হচ্ছে না চেয়ে খারাপ তাদের ব্যবহার করবে না" ।
এই যুক্তিটির কিছু সত্যতা আছে এবং বাস্তবে আমি সন্দেহ করি জাভাতে অপারেটরকে ওভাররাইড না রাখার জন্য গোসলিংসের অনুপ্রেরণা অনুরূপ যুক্তি থেকে আসে - তারা প্রোগ্রামারকে বিভ্রান্ত করে কারণ তারা প্রায়শই নির্যাতিত হয়।
তবে শেষ পর্যন্ত, আমি এটি হিজলসবার্গের একটি বোগাস যুক্তি এবং সম্ভবত একটি উত্তরোত্তর খুঁজে পেয়েছি যা একটি সুচিন্তিত সিদ্ধান্তের চেয়ে অভাবকে ব্যাখ্যা করার জন্য তৈরি করা হয়েছিল।
আমি যুক্তি দিয়ে বলব যে চেক করা ব্যতিক্রমগুলির অত্যধিক ব্যবহার একটি খারাপ জিনিস এবং ব্যবহারকারীদের দ্বারা স্লোপি হ্যান্ডলিংয়ের দিকে ঝুঁকছে, তবে সেগুলির যথাযথ ব্যবহার এপিআই প্রোগ্রামারকে এপিআই ক্লায়েন্ট প্রোগ্রামারকে দুর্দান্ত সুবিধা দিতে দেয়।
এখন এপিআই প্রোগ্রামারকে সাবধান থাকতে হবে যে সমস্ত জায়গায় চেক করা ব্যতিক্রমগুলি ছুঁড়ে না ফেলে, বা তারা কেবল ক্লায়েন্ট প্রোগ্রামারকে বিরক্ত করবে। খুব অলস ক্লায়েন্ট প্রোগ্রামার (Exception) {}
হিজলসবার্গ সতর্ক করার সাথে সাথে ধরা পড়বে এবং সমস্ত সুবিধা হারাবে এবং নরকের পরিণতি হবে। তবে কিছু পরিস্থিতিতে, ভাল চেক করা ব্যতিক্রমের বিকল্প নেই।
আমার জন্য ক্লাসিক উদাহরণটি ফাইল-ওপেন এপিআই। ভাষার ইতিহাসের প্রতিটি প্রোগ্রামিং ভাষার (কমপক্ষে ফাইল সিস্টেমে) কোথাও একটি এপিআই থাকে যা আপনাকে একটি ফাইল খুলতে দেয়। এবং এই এপিআই ব্যবহার করে প্রতিটি ক্লায়েন্ট প্রোগ্রামার জানেন যে তারা যে ফাইলটি খোলার চেষ্টা করছেন তা বিদ্যমান নেই বলে তাদের মোকাবেলা করতে হবে। আমাকে এটিকে পুনরায় মন্তব্য করতে দাও: এই API ব্যবহার করে প্রতিটি ক্লায়েন্ট প্রোগ্রামারকে জানতে হবে যে তাদের এই কেসটি মোকাবেলা করতে হবে। এবং ঘষা আছে: এপিআই প্রোগ্রামার তাদের একা মন্তব্য করার মাধ্যমে এটি মোকাবেলা করা উচিত কিনা তা জানতে সহায়তা করতে পারে বা তারা সত্যই জোর দিতে পারে এটির সাথে ক্লায়েন্টের চুক্তির উপর দিতে পারে।
সি তে বুদ্ধিমান কিছু যায়
if (f = fopen("goodluckfindingthisfile")) { ... }
else { // file not found ...
যেখানে fopen
0 এবং সি ফিরে আসার ব্যর্থতা নির্দেশ করে (বোকামি) আপনাকে 0 কে বুলিয়ান হিসাবে আচরণ করতে দেয় এবং ... মূলত, আপনি এই প্রতিমাটি শিখেন এবং আপনি ঠিক আছেন। তবে আপনি যদি নূব হন এবং আপনি প্রতিমাটি শিখেন না তবে কী হবে। তারপরে, অবশ্যই, আপনি শুরু করে দিন
f = fopen("goodluckfindingthisfile");
f.read(); // BANG!
এবং হার্ড উপায় শিখুন।
মনে রাখবেন যে আমরা এখানে দৃ strongly়ভাবে টাইপ করা ভাষাগুলি সম্পর্কে কথা বলছি: একটি API টি দৃ strongly়ভাবে টাইপ করা ভাষায় কী তা সম্পর্কে একটি স্পষ্ট ধারণা রয়েছে: এটি প্রতিটিটির জন্য একটি স্পষ্টভাবে সংজ্ঞায়িত প্রোটোকল ব্যবহার করার জন্য এটি কার্যকারিতা (পদ্ধতি) এর স্মর্গাসর্ড।
যে পরিষ্কারভাবে সংজ্ঞায়িত প্রোটোকল সাধারণত একটি পদ্ধতি স্বাক্ষর দ্বারা সংজ্ঞায়িত করা হয়। এখানে ফোপেনের জন্য আপনার এটি স্ট্রিং (বা সি এর ক্ষেত্রে একটি চর *) পাস করার প্রয়োজন pass আপনি যদি এটি অন্য কিছু দেন তবে আপনি একটি সংকলন-সময় ত্রুটি পান। আপনি প্রোটোকলটি অনুসরণ করেননি - আপনি এপিআই সঠিকভাবে ব্যবহার করছেন না।
কিছু (অস্পষ্ট) ভাষায় রিটার্নের ধরণটি প্রোটোকলেরও একটি অংশ। যদি আপনি সমতুল্য কল করতে চেষ্টা করুনfopen()
কোনও ভেরিয়েবলকে না বরাদ্দ করে কিছু ভাষায় একটি সংকলন-সময় ত্রুটিও পাবেন (আপনি কেবল এটি শূন্য ফাংশন দিয়ে করতে পারেন)।
আমি যে বিষয়টি তৈরি করার চেষ্টা করছি তা হ'ল: বিষয়টিটি একটি স্ট্যাটিকালি টাইপ করা ভাষায় এপিআই প্রোগ্রামার ক্লায়েন্টকে যদি ক্লায়েন্টের কোডটি কোনও স্পষ্ট ভুল করে তবে সংকলন থেকে তাদের ক্লায়েন্ট কোডটি রোধ করে যথাযথভাবে এপিআই ব্যবহার করতে উত্সাহিত করে।
(রুবির মতো গতিসম্পন্ন টাইপিত ভাষায়, আপনি ফাইলের নাম হিসাবে কোনও ফ্লোট বলতে পারেন, এটি কোনও সংকেত দিতে পারেন - এবং এটি সংকলন করবে you're আপনি এমনকি যদি পদ্ধতিটির তর্কগুলি নিয়ন্ত্রণ নাও করেন তবে চেক করা ব্যতিক্রম কেন ব্যবহারকারীকে ঝামেলা করছেন The এখানে তৈরি আর্গুমেন্টগুলি কেবল স্ট্যাটিস্টিকাল-টাইপ করা ভাষাগুলিতেই প্রযোজ্য))
সুতরাং, চেক ব্যতিক্রম সম্পর্কে কি?
ঠিক আছে এখানে জাভা এপিআইগুলির মধ্যে একটি আপনি একটি ফাইল খোলার জন্য ব্যবহার করতে পারেন।
try {
f = new FileInputStream("goodluckfindingthisfile");
}
catch (FileNotFoundException e) {
// deal with it. No really, deal with it!
... // this is me dealing with it
}
সেই ধর দেখি? এখানে সেই এপিআই পদ্ধতির স্বাক্ষর রয়েছে:
public FileInputStream(String name)
throws FileNotFoundException
লক্ষ্য করুন FileNotFoundException
একটি হল চেক করা ব্যতিক্রম।
এপিআই প্রোগ্রামার আপনাকে এটি বলছে: "আপনি এই কনস্ট্রাক্টরটি একটি নতুন ফাইলআইপুট স্ট্রিম তৈরি করতে ব্যবহার করতে পারেন তবে আপনি
ক) ফাইলের নাম অবশ্যই স্ট্রিং হিসাবে পাস করতে হবে
খ) অবশ্যই রানটাইমের সময় ফাইলটি খুঁজে পাওয়া না যাওয়ার সম্ভাবনা গ্রহণ করতে হবে "
এবং এটি যতটা আমি উদ্বিগ্ন পুরো বিষয়টি।
মূলত প্রশ্নটি "প্রোগ্রামারের নিয়ন্ত্রণের বাইরে থাকা বিষয়গুলি" হিসাবে উল্লেখ করে। আমার প্রথম ধারণাটি হ'ল তিনি / তার অর্থ এমন জিনিস যা এপিআইয়ের বাইরে নেই প্রোগ্রামারদের নিয়ন্ত্রণের বাইরে থাকে। তবে প্রকৃতপক্ষে, সঠিকভাবে ব্যবহৃত হওয়ার সময় চেক করা ব্যতিক্রমগুলি সত্যই ক্লায়েন্ট প্রোগ্রামার এবং API প্রোগ্রামারের নিয়ন্ত্রণের বাইরে থাকা জিনিসগুলির জন্য হওয়া উচিত। আমি মনে করি এটি পরীক্ষিত ব্যতিক্রমগুলি অপব্যবহার না করার মূল বিষয়।
আমি মনে করি ফাইল-ওপেনটি বিন্দুটি সুন্দরভাবে ফুটিয়ে তুলেছে। এপিআই প্রোগ্রামার জানে যে আপনি তাদের এমন কোনও ফাইলের নাম দিতে পারেন যা এপিআই বলা হওয়ার সময় অস্তিত্বহীন হয়ে দাঁড়ায় এবং আপনি যা চান তা তারা আপনাকে ফিরিয়ে দিতে সক্ষম হবে না, তবে একটি ব্যতিক্রম ছুঁড়ে ফেলতে হবে। তারা আরও জানে যে এটি নিয়মিতভাবে ঘটবে এবং ক্লায়েন্ট প্রোগ্রামার কলটি লেখার সময় ফাইলটির নামটি সঠিক হওয়ার আশা করতে পারে, তবে তাদের নিয়ন্ত্রণের বাইরেও কারণে রানটাইমের সময় এটি ভুল হতে পারে।
সুতরাং এপিআই এটিকে স্পষ্ট করে তুলেছে: আপনি আমাকে ফোন করার সময় এই ফাইলটির অস্তিত্ব নেই এমন ঘটনাও ঘটবে এবং এর সাথে আপনি আরও ভাল ব্যবহার করতে পারেন।
এটি কাউন্টার-কেস দিয়ে পরিষ্কার হবে। ভাবুন আমি একটি টেবিল এপিআই লিখছি। আমার কাছে এই পদ্ধতি সহ একটি এপিআই সহ কোথাও টেবিলের মডেল রয়েছে:
public RowData getRowData(int row)
এখন আমি একটি এপিআই প্রোগ্রামার হিসাবে জানি যে কয়েকটি ক্ষেত্রে ক্লায়েন্ট সারণির বাইরে একটি সারি বা একটি সারি মানের জন্য নেতিবাচক মান পাস করে cases সুতরাং আমি একটি পরীক্ষিত ব্যতিক্রম ছুঁড়ে ফেলতে এবং ক্লায়েন্টকে এটি মোকাবেলা করতে বাধ্য করতে পারি:
public RowData getRowData(int row) throws CheckedInvalidRowNumberException
(আমি অবশ্যই এটি অবশ্যই "চেকড" বলব না))
এটি চেক করা ব্যতিক্রমগুলির খারাপ ব্যবহার। ক্লায়েন্ট কোডটি সারির ডেটা আনার জন্য কলগুলি পূর্ণ হতে চলেছে, যার প্রত্যেকটিরই চেষ্টা / ধর ব্যবহার করতে হবে এবং কীসের জন্য? তারা কি ব্যবহারকারীর কাছে রিপোর্ট করতে যাচ্ছে যে ভুল সারিটি চাওয়া হয়েছিল? সম্ভবত তা নয় - কারণ আমার টেবিল দৃশ্যের চারপাশের ইউআই যা-ই হোক না কেন, ব্যবহারকারীর এমন একটি অবস্থাতে প্রবেশ করতে দেওয়া উচিত নয় যেখানে একটি অবৈধ সারিটির জন্য অনুরোধ করা হচ্ছে। সুতরাং এটি ক্লায়েন্ট প্রোগ্রামারের অংশে একটি বাগ
এপিআই প্রোগ্রামারটি এখনও ভবিষ্যদ্বাণী করতে পারে যে ক্লায়েন্ট এই জাতীয় বাগগুলি কোড করবে এবং এটির মতো একটি রানটাইম ব্যতিক্রম সহ এটি পরিচালনা করা উচিত IllegalArgumentException
।
একটি পরীক্ষিত ব্যতিক্রম সহ getRowData
, এটি স্পষ্টভাবে একটি কেস যা হেজলসবার্গের অলস প্রোগ্রামারকে কেবল খালি ক্যাচগুলি যুক্ত করার দিকে পরিচালিত করে। যখন এটি ঘটে, অবৈধ সারি মানগুলি পরীক্ষক বা ক্লায়েন্ট বিকাশকারী ডিবাগিংয়ের কাছেও স্পষ্ট হবে না, বরং এর ত্রুটিগুলি ছুঁড়ে ফেলবে যার উত্সটি নির্দিষ্ট করা শক্ত। লঞ্চের পরে আরিয়ান রকেট উড়িয়ে দেবে।
ঠিক আছে, সুতরাং এখানে সমস্যাটি: আমি বলছি যে পরীক্ষিত ব্যতিক্রমটি FileNotFoundException
কেবল একটি ভাল জিনিস নয় তবে ক্লায়েন্ট প্রোগ্রামারটির জন্য সবচেয়ে কার্যকর উপায়ে এপিআই সংজ্ঞায়নের জন্য এপিআই প্রোগ্রামার সরঞ্জামবক্সের একটি প্রয়োজনীয় সরঞ্জাম। কিন্তুCheckedInvalidRowNumberException
একটি বড় অসুবিধা, খারাপ প্রোগ্রামিংয়ের দিকে পরিচালিত করে এবং এড়ানো উচিত। তবে কীভাবে পার্থক্য জানাবেন।
আমি অনুমান করি যে এটি কোনও সঠিক বিজ্ঞান নয় এবং আমি অনুমান করি যে সম্ভবত হিজলসবার্গের যুক্তিটি একটি নির্দিষ্ট পরিমাণে অন্তর্নিহিত এবং ন্যায়সঙ্গত হয়েছে। তবে আমি বাচ্চাকে এখানে স্নানের জল দিয়ে ছুঁড়ে ফেলার জন্য সন্তুষ্ট নই, সুতরাং ভাল যাচাই করা ব্যতিক্রমগুলি খারাপ থেকে আলাদা করার জন্য আমাকে এখানে কিছু বিধি নিষেধ করার অনুমতি দিন:
ক্লায়েন্টের নিয়ন্ত্রণের বাইরে বা ক্লোজড বনাম ওপেন:
পরীক্ষিত ব্যতিক্রমগুলি কেবল তখনই ব্যবহার করা উচিত যেখানে ত্রুটি কেস এপিআই এবং ক্লায়েন্ট প্রোগ্রামার উভয়ের নিয়ন্ত্রণের বাইরে থাকে । সিস্টেমটি কতটা উন্মুক্ত বা বন্ধ রয়েছে তা এটির সাথে সম্পর্কিত । একটি সবাধ UI 'তে যেখানে ক্লায়েন্ট প্রোগ্রামার নিয়ন্ত্রণ আছে, বলো, বোতাম, কীবোর্ড কমান্ড ইত্যাদি সর্বাঙ্গে যোগ করুন এবং টেবিল ভিউ (একটি বদ্ধ সিস্টেম), এটি একটি ক্লায়েন্ট প্রোগ্রামিং বাগ সংশোধন করা হয় থেকে মুছে দিন সারি যদি এটা থেকে ডেটা আনতে চেষ্টা যে একটি অস্তিত্ব সারি। একটি ফাইল-ভিত্তিক অপারেটিং সিস্টেমে যেখানে যে কোনও সংখ্যক ব্যবহারকারী / অ্যাপ্লিকেশন ফাইল যুক্ত করতে এবং মুছে ফেলতে পারে (একটি উন্মুক্ত সিস্টেম), এটি অনুধাবনযোগ্য যে ক্লায়েন্টের অনুরোধ করা ফাইলটি তাদের জ্ঞান ছাড়াই মুছে ফেলা হয়েছে সুতরাং তারা এটির সাথে কাজ করার আশা করা উচিত ।
সর্বব্যাপিতা:
চেক করা ব্যতিক্রমগুলি ক্লায়েন্টের দ্বারা প্রায়শই করা একটি API কলটিতে ব্যবহার করা উচিত নয়। ঘন ঘন আমি ক্লায়েন্ট কোডের অনেকগুলি স্থান থেকে বোঝাতে চাইছি - সময় মতো নয়। সুতরাং একটি ক্লায়েন্ট কোড একই ফাইলটি প্রচুর খোলার চেষ্টা করার ঝোঁক রাখে না, তবে আমার টেবিলের ভিউটি RowData
বিভিন্ন পদ্ধতি থেকে সমস্ত জায়গায় পেয়ে যায়। বিশেষত, আমি অনেক কোড লিখতে যাচ্ছি
if (model.getRowData().getCell(0).isEmpty())
এবং প্রতিবার চেষ্টা / ক্যাপচারের মধ্যে আবদ্ধ থাকা বেদনাদায়ক হবে।
ব্যবহারকারীকে অবহিত করা:
চেক করা ব্যতিক্রমগুলি এমন ক্ষেত্রে ব্যবহার করা উচিত যেখানে আপনি শেষ ব্যবহারকারীকে উপস্থাপিত করার জন্য দরকারী ত্রুটি বার্তাটি কল্পনা করতে পারেন। এটিই "এবং এটি হওয়ার পরে আপনি কী করবেন?" প্রশ্ন আমি উপরে উত্থাপিত। এটি আইটেম 1 এর সাথেও সম্পর্কিত Since
"Error: could not find the file 'goodluckfindingthisfile'"
যেহেতু আপনার অবৈধ সারি নম্বরটি কোনও অভ্যন্তরীণ বাগের কারণে এবং ব্যবহারকারীর কোনও দোষের কারণে নয়, তাই আপনি তাদের দিতে পারেন এমন কোনও কার্যকর তথ্য নেই। যদি আপনার অ্যাপ্লিকেশনটি রানটাইম ব্যতিক্রমগুলি কনসোলে পড়ে না দেয় তবে সম্ভবত তাদের কিছু কুৎসিত বার্তা দেওয়া শেষ হবে:
"Internal error occured: IllegalArgumentException in ...."
সংক্ষেপে, আপনি যদি মনে করেন না যে আপনার ক্লায়েন্ট প্রোগ্রামার আপনার ব্যতিক্রমটি এমনভাবে ব্যাখ্যা করতে পারে যা ব্যবহারকারীকে সহায়তা করে, তবে সম্ভবত আপনার চেক করা ব্যতিক্রম ব্যবহার করা উচিত নয়।
সুতরাং সেগুলি আমার নিয়ম। কিছুটা সংশ্লেষিত, এবং এতে নিঃসন্দেহে ব্যতিক্রম হবে (দয়া করে আমাকে সেগুলি পরিমার্জনে সহায়তা করুন)। তবে আমার মূল যুক্তিটি হ'ল এমন কিছু ক্ষেত্রে রয়েছে FileNotFoundException
যেখানে পরীক্ষিত ব্যতিক্রমগুলি প্যারামিটারের মতো এপিআই চুক্তির একটি অংশ হিসাবে গুরুত্বপূর্ণ এবং দরকারী। সুতরাং এটির অপব্যবহার করার কারণে আমাদের এটি সরবরাহ করা উচিত নয়।
দুঃখিত, এটিকে এত দীর্ঘ এবং হালকাভাবে তৈরি করার অর্থ নয় আমাকে দুটি পরামর্শ দিয়ে শেষ করুন:
উত্তর: এপিআই প্রোগ্রামারস: তাদের কার্যকারিতা সংরক্ষণের জন্য পরীক্ষিত ব্যতিক্রমগুলি অল্প পরিমাণে ব্যবহার করুন। সন্দেহ হলে একটি চেক করা ব্যতিক্রম ব্যবহার করুন।
বি: ক্লায়েন্ট প্রোগ্রামারস: আপনার বিকাশের প্রথম দিকে একটি মোড়ানো ব্যতিক্রম (গুগল এটি) তৈরি করার অভ্যাসটি গ্রহণ করুন। JDK 1.4 এবং পরবর্তীকালে এটির RuntimeException
জন্য একটি কনস্ট্রাক্টর সরবরাহ করুন , তবে আপনি খুব সহজেই নিজের তৈরি করতে পারেন। এখানে কনস্ট্রাক্টর:
public RuntimeException(Throwable cause)
তারপরে যখনই আপনাকে একটি চেক করা ব্যতিক্রম পরিচালনা করতে হবে এবং আপনি অলস বোধ করছেন (বা আপনি মনে করেন যে এপিআই প্রোগ্রামার প্রথমে চেক করা ব্যতিক্রমটি ব্যবহার করার ক্ষেত্রে অত্যধিক alousর্ষান্বিত হয়েছিল), কেবল ব্যতিক্রমটিকে গিলে ফেলবেন না, এটি মুড়ে ফেলুন এবং এটি পুনর্বিবেচনা।
try {
overzealousAPI(thisArgumentWontWork);
}
catch (OverzealousCheckedException exception) {
throw new RuntimeException(exception);
}
এটি আপনার আইডিইর একটি ছোট কোড টেম্পলেটগুলির মধ্যে রাখুন এবং যখন আপনি অলস বোধ করছেন তখন এটি ব্যবহার করুন। আপনি যদি সত্যিই চেক করা ব্যতিক্রমটি পরিচালনা করতে চান তবে আপনাকে রানটাইমে সমস্যাটি দেখার পরে ফিরে আসতে হবে এবং এটি মোকাবেলা করতে বাধ্য করা হবে। কারণ, আমাকে বিশ্বাস করুন (এবং অ্যান্ডারস হিজলসবার্গ), আপনি কখনই নিজের যে টডোতে ফিরে আসতে পারবেন না
catch (Exception e) { /* TODO deal with this at some point (yeah right) */}