আমি সি ++ এর দৃষ্টিকোণ থেকে উত্তর দেব। আমি নিশ্চিত যে সমস্ত মূল ধারণাটি সি # তে স্থানান্তরযোগ্য।
দেখে মনে হচ্ছে আপনার পছন্দসই স্টাইলটি "সর্বদা ব্যতিক্রম ছোঁড়া":
int CalculateArea(int x, int y) {
if (x < 0 || y < 0) {
throw Exception("negative side lengths");
}
return x * y;
}
এটি সি ++ কোডের জন্য সমস্যা হতে পারে কারণ ব্যতিক্রম হ্যান্ডলিং ভারী - এটি ব্যর্থতার কেসটি ধীরে ধীরে চালিত করে এবং ব্যর্থতার কেসটিকে মেমরি বরাদ্দ করে দেয় (যা কখনও কখনও এমনকি উপলব্ধ হয় না) এবং সাধারণত জিনিসগুলি কম অনুমানযোগ্য করে তোলে। "নিয়ন্ত্রণ প্রবাহের ক্ষেত্রে ব্যতিক্রমগুলি ব্যবহার করবেন না" এই জাতীয় কথা আপনি শুনতে পেয়েছেন এমন কারণ হ'ল ইএইচের ভারীতা ness
সুতরাং কিছু লাইব্রেরি (যেমন <filesystem>
) সি ++ কে "ডুয়াল এপিআই" বলে ডাকে বা সি # কী Try-Parse
প্যাটার্নটি কল করে তা ব্যবহার করে (ধন্যবাদ পিটার টিপটির জন্য!)
int CalculateArea(int x, int y) {
if (x < 0 || y < 0) {
throw Exception("negative side lengths");
}
return x * y;
}
bool TryCalculateArea(int x, int y, int& result) {
if (x < 0 || y < 0) {
return false;
}
result = x * y;
return true;
}
int a1 = CalculateArea(x, y);
int a2;
if (TryCalculateArea(x, y, a2)) {
// use a2
}
আপনি এখনই "দ্বৈত এপিআই" দিয়ে সমস্যাটি দেখতে পাচ্ছেন: প্রচুর কোড ডুপ্লিকেশন, ব্যবহারকারীদের জন্য কোনও গাইডলাইন নেই যে "এপিআই" সঠিকভাবে ব্যবহার করা উচিত এবং ব্যবহারকারীকে অবশ্যই দরকারী ত্রুটি বার্তাগুলির মধ্যে কঠোর পছন্দ করতে হবে ( CalculateArea
) এবং গতি ( TryCalculateArea
) কারণ দ্রুততম সংস্করণটি আমাদের দরকারী "negative side lengths"
ব্যতিক্রম নিয়ে যায় এবং এটিকে অকেজোতে পরিণত করে false
- "কিছু ভুল হয়েছে, আমাকে কী জিজ্ঞাসা করবেন না কোথায়"। (কিছু দ্বৈত API গুলি যেমন, আরো ভাবপূর্ণ ত্রুটি টাইপ ব্যবহার int errno
সি ++ এর বা std::error_code
, কিন্তু যে এখনও আপনাদের বলছি না যেখানে ত্রুটি ঘটেছে - শুধু এটা করেনি কোথাও দেখা যায়।)
আপনার কোডটি কীভাবে আচরণ করা উচিত তা যদি আপনি সিদ্ধান্ত নিতে না পারেন তবে আপনি সর্বদা কলারের কাছে সিদ্ধান্তটিকে লাথি মারতে পারেন!
template<class F>
int CalculateArea(int x, int y, F errorCallback) {
if (x < 0 || y < 0) {
return errorCallback(x, y, "negative side lengths");
}
return x * y;
}
int a1 = CalculateArea(x, y, [](auto...) { return 0; });
int a2 = CalculateArea(x, y, [](int, int, auto msg) { throw Exception(msg); });
int a3 = CalculateArea(x, y, [](int, int, auto) { return x * y; });
এটি আপনার সহকর্মী মূলত যা করছে; ব্যতীত তিনি "ত্রুটি হ্যান্ডলার" কে বৈশ্বিক পরিবর্তনশীল হিসাবে চিহ্নিত করছেন:
std::function<int(const char *)> g_errorCallback;
int CalculateArea(int x, int y) {
if (x < 0 || y < 0) {
return g_errorCallback("negative side lengths");
}
return x * y;
}
g_errorCallback = [](auto) { return 0; };
int a1 = CalculateArea(x, y);
g_errorCallback = [](const char *msg) { throw Exception(msg); };
int a2 = CalculateArea(x, y);
সুস্পষ্ট ফাংশন পরামিতিগুলি থেকে বিশ্ব পজিশনে গুরুত্বপূর্ণ পরামিতিগুলি স্থানান্তর করা প্রায়শই একটি খারাপ ধারণা। আমি এটা সুপারিশ করতে পারিনা. (এটি সত্য যে এটি আপনার ক্ষেত্রে বৈশ্বিক রাষ্ট্র নয় তবে কেবল উদাহরণস্বরূপ সদস্য রাষ্ট্রের অবস্থা খারাপকে কিছুটা প্রশমিত করেছে, তবে বেশি নয়))
তদুপরি, আপনার সহকর্মী অকারণে সম্ভাব্য ত্রুটি পরিচালনার আচরণের সংখ্যা সীমিত করছেন। লাম্বদা যে কোনও ত্রুটি-হ্যান্ডলিংয়ের অনুমতি দেওয়ার পরিবর্তে , তিনি মাত্র দুটি বিষয়ে সিদ্ধান্ত নিয়েছেন:
bool g_errorViaException;
int CalculateArea(int x, int y) {
if (x < 0 || y < 0) {
return g_errorViaException ? throw Exception("negative side lengths") : 0;
}
return x * y;
}
g_errorViaException = false;
int a1 = CalculateArea(x, y);
g_errorViaException = true;
int a2 = CalculateArea(x, y);
এই সম্ভাব্য কৌশলগুলির মধ্যে এটি সম্ভবত "টক স্পট"। আপনার শেষ দুটি ব্যবহারকারীর কাছ থেকে আপনার ঠিক দুটি ত্রুটি-পরিচালনার কলব্যাকগুলির মধ্যে একটি ব্যবহার করতে বাধ্য করে আপনি সমস্ত নমনীয়তা সরিয়ে নিয়েছেন ; এবং আপনি ভাগ করা বিশ্বব্যাপী রাষ্ট্রের সমস্ত সমস্যা পেয়েছেন; এবং আপনি এখনও এই শর্তাধীন শাখার জন্য সর্বত্র অর্থ প্রদান করছেন।
শেষ অবধি, সি ++ (বা শর্তসাপেক্ষ সংকলনযুক্ত যে কোনও ভাষা) এর সাধারণ সমাধানটি হ'ল সংক্ষেপণ সময়ে বিশ্বব্যাপী তাদের পুরো প্রোগ্রামের জন্য সিদ্ধান্ত নিতে ব্যবহারকারীকে বাধ্য করা হবে, যাতে অন-গৃহীত কোডপথটি সম্পূর্ণরূপে অনুকূলিত করা যায়:
int CalculateArea(int x, int y) {
if (x < 0 || y < 0) {
#ifdef NEXCEPTIONS
return 0;
#else
throw Exception("negative side lengths");
#endif
}
return x * y;
}
// Now these two function calls *must* have the same behavior,
// which is a nice property for a program to have.
// Improves understandability.
//
int a1 = CalculateArea(x, y);
int a2 = CalculateArea(x, y);
যেভাবে এইভাবে কাজ করে তার উদাহরণ হ'ল সি এবং সি ++ এর assert
ম্যাক্রো যা প্রিপ্রসেসর ম্যাক্রোর উপর এর আচরণকে শর্ত করে NDEBUG
।