সমস্যাটি:
দীর্ঘদিন থেকে, আমি এই exceptions
প্রক্রিয়াটি সম্পর্কে উদ্বিগ্ন , কারণ আমি অনুভব করি যে এটির কী হওয়া উচিত তা সত্যিই সমাধান করে না।
দাবি: এই বিষয় সম্পর্কে বাইরে দীর্ঘ বিতর্ক রয়েছে এবং তাদের বেশিরভাগ exceptions
একটি ত্রুটি কোড ফেরত বনাম তুলনা করতে লড়াই করে । এটি এখানে অবশ্যই বিষয় নয়।
একটি ত্রুটি সংজ্ঞায়িত করার চেষ্টা করে, আমি সিজনপোরের গাইডলাইনগুলির সাথে সম্মত হব, বজর্ন স্ট্রস্ট্রপ এবং হার্ব সটার থেকে
একটি ত্রুটির অর্থ হল যে ফাংশনটি তার বিজ্ঞাপনিত উদ্দেশ্য অর্জন করতে পারে না
দাবি: exception
প্রক্রিয়াটি হ'ল ত্রুটিগুলি পরিচালনা করার জন্য একটি ভাষা অর্থসূচক।
দাবি: আমার কাছে কোনও কাজ অর্জন না করার জন্য কোনও ফাংশনের "অজুহাত" নেই: হয় আমরা পূর্বের / পোস্টের শর্তগুলি ভুলভাবে সংজ্ঞায়িত করি যাতে ফাংশন ফলাফল নিশ্চিত করতে পারে না, বা কিছু নির্দিষ্ট ব্যতিক্রমী ক্ষেত্রে বিকাশে সময় ব্যয় করার পক্ষে যথেষ্ট গুরুত্বপূর্ণ বলে বিবেচিত হয় না একটি সমাধান. আইএমও বিবেচনা করে, সাধারণ কোড এবং ত্রুটি কোড হ্যান্ডলিংয়ের মধ্যে পার্থক্যটি (বাস্তবায়নের আগে) খুব সাবজেক্টিভ লাইন।
দাবি: প্রাক বা পোস্ট শর্তটি যখন রক্ষণ না করা হয় তা নির্দেশ করার জন্য ব্যতিক্রমগুলি ব্যবহার করা exception
মূলত ডিবাগিংয়ের উদ্দেশ্যে, প্রক্রিয়াটির অন্য একটি উদ্দেশ্য। আমি exceptions
এখানে এই ব্যবহার লক্ষ্যবস্তু না ।
অনেক বই, টিউটোরিয়াল এবং অন্যান্য উত্সগুলিতে এগুলি বেশ উদ্দেশ্যমূলক বিজ্ঞান হিসাবে ত্রুটি পরিচালনার ঝোঁক দেখায়, এটি সমাধান করা হয় exceptions
এবং catch
কোনও পরিস্থিতি থেকে পুনরুদ্ধার করতে সক্ষম একটি শক্তিশালী সফ্টওয়্যার থাকার জন্য আপনার কেবল তাদের প্রয়োজন । তবে বিকাশকারী হিসাবে আমার বেশ কয়েক বছর আমাকে সমস্যাটি একটি ভিন্ন পদ্ধতির থেকে দেখতে দেয়:
- নির্দিষ্ট কেসটি সাবধানতার সাথে প্রয়োগ করা খুব বিরল বলে মনে হয় তখন প্রোগ্রামাররা ব্যতিক্রম ছুঁড়ে দিয়ে তাদের কাজটি সহজ করার প্রবণতা দেখায়। এর সাধারণ বিষয়গুলি হ'ল: মেমরি সমস্যা, ডিস্ক পূর্ণ সমস্যা, দূষিত ফাইল সমস্যা ইত্যাদি This এটি যথেষ্ট হতে পারে তবে স্থির স্তর থেকে সর্বদা সিদ্ধান্ত নেওয়া হয় না।
- প্রোগ্রামারগুলি গ্রন্থাগারগুলিতে ব্যতিক্রমগুলি সম্পর্কে সাবধানতার সাথে ডকুমেন্টেশন পড়ার প্রবণতা রাখে না এবং কোন ফাংশন কোনটি ছুড়ে দেয় সে সম্পর্কে সাধারণত সচেতন থাকে না। তদতিরিক্ত, এমনকি যখন তারা জানে তখনও তারা এগুলি সত্যই পরিচালনা করে না।
- প্রোগ্রামাররা খুব তাড়াতাড়ি পর্যায়ে ব্যতিক্রমগুলি ধরতে পারে না এবং যখন তারা তা করে তখন বেশিরভাগ ক্ষেত্রে লগইন করা এবং আরও ছুঁড়ে ফেলা হয়। (প্রথম পয়েন্ট দেখুন)।
এর দুটি পরিণতি রয়েছে:
- ঘন ঘন ঘটে যাওয়া ত্রুটিগুলি বিকাশের প্রথম দিকে সনাক্ত হয় এবং ডিবাগ হয় (যা ভাল)।
- বিরল ব্যতিক্রমগুলি পরিচালনা করা হয় না এবং ব্যবহারকারীর বাড়িতে সিস্টেমটি ক্র্যাশে পরিণত হয় (একটি দুর্দান্ত লগ বার্তা সহ)। কিছু সময় ত্রুটি রিপোর্ট করা হয়, এমনকি না।
এটি বিবেচনা করে, আইএমও ত্রুটি ব্যবস্থার মূল উদ্দেশ্যটি হওয়া উচিত:
- কোডে দৃশ্যমান করুন যেখানে কিছু নির্দিষ্ট কেস পরিচালিত হয় না।
- এই পরিস্থিতিটি ঘটলে সম্পর্কিত রানটাইমটি সম্পর্কিত কোডে যোগাযোগ করুন (কমপক্ষে কলার)।
- পুনরুদ্ধার প্রক্রিয়া সরবরাহ করে
exception
ত্রুটি পরিচালনার প্রক্রিয়া হিসাবে শব্দার্থের মূল ত্রুটি আইএমও: throw
সোর্স কোডটিতে একটি কোথায় রয়েছে তা সহজেই দেখা যায়, তবে ঘোষণাপত্রটি দেখে কোনও নির্দিষ্ট ফাংশন ছুঁড়ে ফেলতে পারে কিনা তা একেবারেই স্পষ্ট নয়। এটি সমস্ত সমস্যা নিয়ে আসে যা আমি উপরে উপস্থাপন করেছি।
ভাষাটি তত্ক্ষণাত কোডের প্রয়োগ যেমন তত্ক্ষণাত্ ভাষাটির অন্যান্য দিকগুলির (যেমন শক্তিশালী প্রকারের ভেরিয়েবল) হিসাবে করা হয় না
সমাধানের জন্য চেষ্টা
এটির উন্নতি করার অভিপ্রায়ে আমি একটি খুব সাধারণ ত্রুটি পরিচালনার ব্যবস্থা তৈরি করেছি, যা ত্রুটিটি পরিচালনা করার বিষয়টি স্বাভাবিক কোডের চেয়ে একই স্তরে গুরুত্বের চেষ্টা করে।
ধারণাটি হ'ল:
- প্রতিটি (প্রাসঙ্গিক) ফাংশন একটি
success
খুব হালকা অবজেক্টের জন্য একটি রেফারেন্স গ্রহণ করে এবং এটি ক্ষেত্রে ত্রুটির স্থিতিতে সেট করতে পারে। পাঠ্য সহ একটি ত্রুটি সংরক্ষণ না হওয়া অবধি অবজেক্টটি খুব হালকা। - প্রদত্ত বস্তুটিতে ইতিমধ্যে কোনও ত্রুটি থাকলে কোনও ফাংশনটি তার কাজটি এড়াতে উত্সাহিত করা হয়।
- কোনও ত্রুটি কখনই ওভাররাইড করা উচিত নয়।
সম্পূর্ণ নকশা স্পষ্টতই প্রতিটি দিককে (প্রায় 10 পৃষ্ঠা) পুরোপুরি বিবেচনা করবে, কীভাবে এটি ওওপিতে প্রয়োগ করা যায়।
Success
শ্রেণীর উদাহরণ :
class Success
{
public:
enum SuccessStatus
{
ok = 0, // All is fine
error = 1, // Any error has been reached
uninitialized = 2, // Initialization is required
finished = 3, // This object already performed its task and is not useful anymore
unimplemented = 4, // This feature is not implemented already
};
Success(){}
Success( const Success& v);
virtual ~Success() = default;
virtual Success& operator= (const Success& v);
// Comparators
virtual bool operator==( const Success& s)const { return (this->status==s.status && this->stateStr==s.stateStr);}
virtual bool operator!=( const Success& s)const { return (this->status!=s.status || this->stateStr==s.stateStr);}
// Retrieve if the status is not "ok"
virtual bool operator!() const { return status!=ok;}
// Retrieve if the status is "ok"
operator bool() const { return status==ok;}
// Set a new status
virtual Success& set( SuccessStatus status, std::string msg="");
virtual void reset();
virtual std::string toString() const{ return stateStr;}
virtual SuccessStatus getStatus() const { return status; }
virtual operator SuccessStatus() const { return status; }
private:
std::string stateStr;
SuccessStatus status = Success::ok;
};
ব্যবহার:
double mySqrt( Success& s, double v)
{
double result = 0.0;
if (!s) ; // do nothing
else if (v<0.0) s.set(Error, "Square root require non-negative input.");
else result = std::sqrt(v);
return result;
}
Success s;
mySqrt(s, 144.0);
otherStuff(s);
saveStuff(s);
if (s) /*All is good*/;
else cout << s << endl;
আমি এটি আমার (নিজস্ব) কোডটিতে ব্যবহার করেছি এবং এটি প্রোগ্রামারকে (আমাকে) সম্ভাব্য ব্যতিক্রমী মামলাগুলি এবং কীভাবে সেগুলি সমাধান করতে হবে (ভাল) সম্পর্কে আরও চিন্তা করতে বাধ্য করে। তবে এটির একটি শেখার বক্ররেখা রয়েছে এবং কোডটি এখন এটি ব্যবহার করে এমনভাবে ভালভাবে সংহত করে না।
প্রশ্নটি
আমি একটি প্রকল্পে যেমন একটি দৃষ্টান্ত ব্যবহারের প্রভাব আরও ভাল বুঝতে চাই:
- সমস্যার ভিত্তিটি কি সঠিক? বা আমি কি প্রাসঙ্গিক কিছু মিস করেছি?
- সমাধানটি কি একটি ভাল স্থাপত্যের ধারণা? নাকি দাম খুব বেশি?
সম্পাদনা করুন:
পদ্ধতির মধ্যে তুলনা:
//Exceptions:
// Incorrect
File f = open("text.txt"); // Could throw but nothing tell it! Will crash
save(f);
// Correct
File f;
try
{
f = open("text.txt");
save(f);
}
catch( ... )
{
// do something
}
//Error code (mixed):
// Incorrect
File f = open("text.txt"); //Nothing tell you it may fail! Will crash
save(f);
// Correct
File f = open("text.txt");
if (f) save(f);
//Error code (pure);
// Incorrect
File f;
open(f, "text.txt"); //Easy to forget the return value! will crash
save(f);
//Correct
File f;
Error er = open(f, "text.txt");
if (!er) save(f);
//Success mechanism:
Success s;
File f;
open(s, "text.txt");
save(s, f); //s cannot be avoided, will never crash.
if (s) ... //optional. If you created s, you probably don't forget it.