একটি ব্যতিক্রম নিক্ষেপ করা বা নাল - ভাল অনুশীলন ফেলা হবে কিনা তা নিয়ন্ত্রণ করার জন্য প্যারামিটার?


24

আমি প্রায়শই এমন পদ্ধতি / ফাংশনগুলি নিয়ে আসি যার অতিরিক্ত বুলিয়ান প্যারামিটার থাকে যা ব্যতিক্রম ব্যর্থতার উপরে ফেলে দেওয়া হয় বা নাল ফিরে আসে কিনা তা নিয়ন্ত্রণ করে।

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

আসুন পরিবর্তে আমাদের ধরে নেওয়া যাক যে আমরা উভয় উপায়ে সমর্থন করতে চাওয়ার একটি ভাল কারণ রয়েছে।

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

সুতরাং, যা ভাল?

উত্তর: $exception_on_failureপ্যারামিটার সহ একটি পদ্ধতি ।

/**
 * @param int $id
 * @param bool $exception_on_failure
 *
 * @return Item|null
 *   The item, or null if not found and $exception_on_failure is false.
 * @throws NoSuchItemException
 *   Thrown if item not found, and $exception_on_failure is true.
 */
function loadItem(int $id, bool $exception_on_failure): ?Item;

বি: দুটি স্বতন্ত্র পদ্ধতি।

/**
 * @param int $id
 *
 * @return Item|null
 *   The item, or null if not found.
 */
function loadItemOrNull(int $id): ?Item;

/**
 * @param int $id
 *
 * @return Item
 *   The item, if found (exception otherwise).
 *
 * @throws NoSuchItemException
 *   Thrown if item not found.
 */
function loadItem(int $id): Item;

সম্পাদনা: সি: অন্য কিছু?

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

নোট

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


5
যদিও আমাকে পিএইচপি-তে কাজ করতে হবে এবং আমি বেশ দক্ষ, যদিও এটি কেবল একটি খারাপ ভাষা এবং এর মানক পাঠাগারটি পুরো জায়গা জুড়ে রয়েছে। পড়ুন eev.ee/blog/2012/04/09/php-a-fractal-of-bad- রেফারেন্সের জন্য ডিজাইন । সুতরাং এটি সত্যিই অবাক হওয়ার কিছু নয় যে কিছু পিএইচপি বিকাশকারীরা খারাপ অভ্যাসগুলি গ্রহণ করে। তবে আমি এখনও এই বিশেষ ডিজাইনের গন্ধ দেখতে পাইনি।
বহুভোজ করুন

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


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

4
একটি পরামর্শ: পরিবর্তে loadItemOrNull(id), loadItemOr(id, defaultItem)আপনার জন্য অর্থবোধ করে কিনা তা বিবেচনা করুন । আইটেমটি একটি স্ট্রিং বা সংখ্যা হলে এটি প্রায়শই হয়।
user949300

উত্তর:


35

আপনি সঠিক: বেশ কয়েকটি কারণে তার জন্য দুটি পদ্ধতি আরও ভাল:

  1. জাভাতে, সম্ভাব্যভাবে কোনও ব্যতিক্রম ছোঁড়ে এমন পদ্ধতির স্বাক্ষরটিতে এই ব্যতিক্রম অন্তর্ভুক্ত হবে; অন্য পদ্ধতি না। এটি এক এবং অন্যের কাছ থেকে কী প্রত্যাশা করবে তা বিশেষ করে পরিষ্কার করে দেয়।

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

    আপনার উদাহরণটি নিখুঁত: দ্বিতীয় ভাগের কোডের মন্তব্যগুলি আরও পরিষ্কার দেখাচ্ছে এবং আমি এমনকি "আইটেমটি পাওয়া গেলে (অন্যথায় ব্যতীত)" সংক্ষিপ্তও করব down "আইটেমটি" -র নীচে - সম্ভাব্য ব্যতিক্রমের উপস্থিতি এবং আপনি যে বর্ণনাটি দিয়েছেন তা স্ব-ব্যাখ্যামূলক।

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

  4. কিছু ফ্রেমওয়ার্ক যেমন, নেট ফ্রেমওয়ার্ক এই পরিস্থিতিতে কনভেনশন স্থাপন করেছে এবং আপনার পরামর্শ অনুসারে তারা দুটি পদ্ধতিতে এটি সমাধান করে। পার্থক্যটি হ'ল তারা তার উত্তরে ইভান দ্বারা ব্যাখ্যা করা একটি প্যাটার্ন ব্যবহার করে , তাই int.Parse(string): intএকটি ব্যতিক্রম ছুঁড়ে দেয়, যদিও int.TryParse(string, out int): boolনা। এই নেট নামকরণ কনভেনশন। নেট এর সম্প্রদায়ে খুব শক্তিশালী এবং যখনই কোডটি আপনার বর্ণনার সাথে মেলে তখনই অনুসরণ করা উচিত।


1
ধন্যবাদ, আমি এই উত্তরটি খুঁজছিলাম! উদ্দেশ্যটি ছিল আমি ড্রুপাল সিএমএস, drupal.org/project/drupal/issues/2932772 এর জন্য এই সম্পর্কে একটি আলোচনা শুরু করেছি এবং আমি এটি আমার ব্যক্তিগত পছন্দ সম্পর্কে চাই না, তবে অন্যের প্রতিক্রিয়া নিয়ে এটি ব্যাক আপ করব।
ডনকিক্সোট

4
কমপক্ষে। নেট জন্য দীর্ঘস্থায়ী traditionতিহ্য হ'ল দুটি পদ্ধতি ব্যবহার করা নয়, পরিবর্তে সঠিক কাজের জন্য সঠিক পছন্দটি বেছে নেওয়া। ব্যতিক্রমগুলি ব্যতিক্রমী পরিস্থিতিতে, প্রত্যাশিত নিয়ন্ত্রণ প্রবাহকে পরিচালনা করতে নয়। একটি পূর্ণসংখ্যার মধ্যে একটি স্ট্রিং পার্স করতে ব্যর্থ? খুব অপ্রত্যাশিত বা ব্যতিক্রমী পরিস্থিতি নয়। int.Parse()সত্যিই খারাপ ডিজাইনের সিদ্ধান্ত হিসাবে বিবেচিত হয়, ঠিক এই কারণেই। নেট দল এগিয়ে গিয়ে বাস্তবায়ন করেছিল TryParse
ভু

1
আমরা কী ধরণের ব্যবহারের ক্ষেত্রে মোকাবিলা করছি সে সম্পর্কে চিন্তাভাবনা না করে দুটি পদ্ধতি সরবরাহ করা সহজ উপায়: আপনি কী করছেন তা নিয়ে ভাববেন না, পরিবর্তে আপনার এপিআইয়ের সমস্ত ব্যবহারকারীর উপর দায় চাপান। অবশ্যই এটি কাজ করে, কিন্তু যে ভাল এপিআই নকশা হলমার্ক (অথবা বিষয়টি জন্য কোনো নকশা নয় পড়ুন যেমন। এই Joel এর নিতে
Voo

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

1
কারণ 1 বি: কিছু ভাষাগুলির (হাস্কেল, সুইফ্ট) স্বাক্ষরে উপস্থিত থাকার জন্য ন্যূনযোগ্যতা প্রয়োজন। বিশেষত, হ্যাস্কেলের নালযোগ্য মানগুলির জন্য সম্পূর্ণ ভিন্ন ধরণের ( data Maybe a = Just a | Nothing) থাকে।
জন ডিভোরাক

9

একটি আকর্ষণীয় প্রকরণটি হ'ল সুইফ্ট ভাষা। সুইফ্টে, আপনি একটি ফাংশনটিকে "নিক্ষেপ" হিসাবে ঘোষণা করেন, এর ফলে এটি ত্রুটি নিক্ষেপ করার অনুমতি পায় (জাভা ব্যতিক্রমগুলি বলার মতো তবে একই রকম নয়)। কলকারী চারটি উপায়ে এই ফাংশনটি কল করতে পারেন:

ক। একটি চেষ্টা / ধরা বিবৃতিতে ব্যতিক্রম ধরা এবং পরিচালনা করে।

খ। যদি কলার নিজেই নিক্ষেপ হিসাবে ঘোষিত হয় তবে কেবল এটি কল করুন এবং কোনও ত্রুটি নিক্ষেপকারী কলকারী দ্বারা নিক্ষিপ্ত ত্রুটিতে পরিণত হয়।

গ। ফাংশন কলটি চিহ্নিত করে try!যার অর্থ "আমি নিশ্চিত যে এই কলটি ফেলবে না"। যদি ডাকা ফাংশন নিক্ষেপ করে তবে অ্যাপ্লিকেশনটি ক্রাশের গ্যারান্টিযুক্ত।

ঘ। ফাংশন কলটি চিহ্নিত করার try?অর্থ যার অর্থ "আমি জানি যে ফাংশনটি নিক্ষেপ করতে পারে তবে কোন ত্রুটিটি ঠিক নিক্ষেপ করা হবে সে সম্পর্কে আমি পাত্তা দিই না"। এটি " T" টাইপ " " থেকে " " টাইপ করে ফাংশনের রিটার্নের মান পরিবর্তন করে optional<T>এবং একটি ব্যতিক্রম নিক্ষেপণ শূন্যে পরিণত হয়।

(ক) এবং (ডি) হল আপনি যে কেসগুলির বিষয়ে জিজ্ঞাসা করছেন। যদি ফাংশনটি শূন্য করতে পারে এবং ব্যতিক্রম ছুঁড়ে ফেলতে পারে? সেক্ষেত্রে রিটার্ন মানটির ধরণটি optional<R>কিছু ধরণের আর এর জন্য " " হবে এবং (ডি) এটিকে " optional<optional<R>>" এ পরিবর্তন করবে যা কিছুটা রহস্যজনক এবং বোঝা শক্ত কিন্তু সম্পূর্ণ সূক্ষ্ম। এবং একটি সুইফ্ট ফাংশন ফিরে আসতে পারে optional<Void>, তাই (d) শূন্যস্থান ফিরে ফাংশন নিক্ষেপের জন্য ব্যবহার করা যেতে পারে।


2

আমি bool TryMethodName(out returnValue)পদ্ধতির পছন্দ।

এটি আপনাকে পদ্ধতিটি সফল হয়েছে কিনা এবং এর একটি ব্যয়বহুল ইঙ্গিত দেয় যে নামকরণের ম্যাচগুলি ব্যতিক্রমী ছোঁড়া পদ্ধতিটিকে একটি ট্র্যাচ ক্যাচ ব্লকে মোড়ানো।

যদি আপনি কেবল নালার দিকে ফিরে যান, আপনি জানেন না যে এটি ব্যর্থ হয়েছে কিনা বা রিটার্নের মানটি বৈধভাবে নাল ছিল।

উদাহরণ:

//throws exceptions when error occurs
Item LoadItem(int id);

//returns false when error occurs
bool TryLoadItem(int id, out Item item)

উদাহরণস্বরূপ ব্যবহার (বাহ্যিক বিন্যাস ছাড়াই উত্তরণ)

Item i;
if(TryLoadItem(3, i))
{
    Print(i.Name);
}
else
{
    Print("unable to load item :(");
}

দুঃখিত, আপনি আমাকে এখানে হারিয়েছেন আপনার " bool TryMethodName(out returnValue)অ্যাপ্রোচ "টি মূল উদাহরণটিতে কীভাবে দেখবে?
ডনকিক্সোট

উদাহরণ যোগ করার জন্য সম্পাদিত
ইয়ান

1
সুতরাং আপনি কোনও রিটার্ন মানের পরিবর্তে একটি বাই-রেফারেন্স প্যারামিটার ব্যবহার করেন, সুতরাং আপনার কাছে বুল সাফল্যের জন্য ফিরতি মানটি নিখরচায় রয়েছে? এমন কোনও প্রোগ্রামিং ভাষা রয়েছে যা এই "আউট" কীওয়ার্ডটিকে সমর্থন করে?
ডনকিক্সোট

2
হ্যাঁ, দুঃখিত, বুঝতে পারিনি 'আউট' c #
ইওয়ান

1
সর্বদা না কিন্তু আইটেম 3 যদি নাল হয়? আপনি যদি জানতেন যে কোনও ত্রুটি হয়েছে কি না
Ewan

2

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


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

@ জেরার্ড আপনি আমাকে একটি উদাহরণ দিতে পারেন দয়া করে?
সর্বোচ্চ

@ ম্যাক্স যখন আপনার বুলিয়ান ভেরিয়েবল রয়েছে b: কল করার পরিবর্তে foo(…, b);আপনাকে if (b) then foo_x(…) else foo_y(…);অন্য যুক্তিগুলি লিখতে হবে এবং পুনরাবৃত্তি করতে হবে, বা ((b) ? foo_x : foo_y)(…)ভাষার কোনও তিনটি অপারেটর এবং প্রথম শ্রেণির ক্রিয়াকলাপ / পদ্ধতি রয়েছে বলে মনে হয়। এবং এটি এমনকি প্রোগ্রামে বিভিন্ন জায়গা থেকে পুনরাবৃত্তি।
ব্ল্যাকজ্যাক 18

@ ব্ল্যাকজ্যাক ভাল হ্যাঁ আমি আপনার সাথে একমত হতে পারি। আমি উদাহরণটি ভেবেছিলাম, if (myGrandmaMadeCookies) eatThem() else makeFood()কোনটি হ্যাঁ আমি এই জাতীয় কোনও কার্যে জড়িয়ে রাখতে পারি checkIfShouldCook(myGrandmaMadeCookies)। আমি অবাক হয়েছি যে আপনি উল্লিখিত সংক্ষিপ্তসারটির সাথে যদি আমাদের বুলিয়ানটিতে পাস করতে হয় তবে কীভাবে আমরা ফাংশনটি আচরণ করতে চাই, মূল প্রশ্ন যেমন, বনাম, আমরা আমাদের মডেল সম্পর্কে কিছু তথ্য দিয়ে যাচ্ছি যেমন দাদীর উদাহরণ আমি সবেমাত্র দিয়েছি।
সর্বোচ্চ

1
আমার মন্তব্যে উল্লেখিত উপদ্রবটি "আপনার সর্বদা উচিত" বোঝায়। সম্ভবত এটি "যদি ক, খ এবং সি প্রযোজ্য হয় তবে [...]" হিসাবে এটি পুনরায় লিখুন। আপনি যে "নিয়ম" উল্লেখ করেছেন তা দুর্দান্ত দৃষ্টান্ত, তবে ব্যবহারের ক্ষেত্রে খুব বৈকল্পিক।
জেরার্ড 20

1

ক্লিন কোড বুলিয়ান ফ্ল্যাগ আর্গুমেন্টগুলি এড়াতে পরামর্শ দেয়, কারণ কল সাইটে তাদের অর্থ অস্বচ্ছ:

loadItem(id, true) // does this throw or not? We need to check the docs ...

যদিও পৃথক পদ্ধতিতে অভিব্যক্তিপূর্ণ নাম ব্যবহার করা যেতে পারে:

loadItemOrNull(id); // meaning is obvious; no need to refer to docs

1

যদি আমাকে A বা B ব্যবহার করতে হয় তবে আমি বি, দুটি পৃথক পদ্ধতি ব্যবহার করব, আরসেনি মরজেনকোস উত্তরে বর্ণিত কারণে ।

তবে আরও একটি পদ্ধতি রয়েছে 1 : জাভাতে একে বলা হয় Optional, তবে ভাষাটি ইতিমধ্যে কোনও অনুরূপ শ্রেণীর ব্যবস্থা না করা থাকলে আপনি অন্যান্য ভাষাগুলিতেও একই ধারণা প্রয়োগ করতে পারেন যেখানে আপনি নিজের ধরণের সংজ্ঞা দিতে পারেন।

আপনি আপনার পদ্ধতিটি এইভাবে সংজ্ঞায়িত করুন:

Optional<Item> loadItem(int id);

আপনার পদ্ধতিতে আপনি Optional.of(item)যদি আইটেমটি খুঁজে পান তবে আপনি ফিরে আসবেন বা আপনি যদি না পেয়ে থাকেন তবে ফিরে আসুন Optional.empty()। আপনি কখনও 2 নিক্ষেপ করেন না এবং কখনই ফিরে আসবেন না null

আপনার পদ্ধতির ক্লায়েন্টের জন্য এটি এমন কিছু null, তবে বড় পার্থক্যের সাথে এটি আইটেমগুলি হারিয়ে যাওয়ার বিষয়টি নিয়ে ভাবতে বাধ্য করে। ব্যবহারকারী কেবল কোনও ফল হতে পারে না তা এই সত্যটি উপেক্ষা করতে পারবেন না। আইটেমটি Optionalএকটি সুস্পষ্ট ক্রিয়াকলাপ থেকে বেরিয়ে আসার জন্য প্রয়োজনীয়:

  • loadItem(1).get()একটি নিক্ষেপ NoSuchElementExceptionবা পাওয়া আইটেম ফিরে আসবে।
  • এছাড়াও রয়েছে loadItem(1).orElseThrow(() -> new MyException("No item 1"))যদি ফিরে একটি কাস্টম ব্যতিক্রম ব্যবহার করতে Optionalখালি।
  • loadItem(1).orElse(defaultItem)ব্যতিক্রম ছুঁড়ে না ফেলে পাওয়া আইটেম বা পাস defaultItem(যা হতে পারে null)টিকে ফেরত দেয় ।
  • loadItem(1).map(Item::getName)আবার Optionalউপস্থিত থাকলে আইটেমের নাম সহ একটি ফিরিয়ে দেয়।
  • আরও কিছু পদ্ধতি রয়েছে, জাভাদোকের জন্য দেখুনOptional

সুবিধাটি হ'ল এখন এটি ক্লায়েন্ট কোডের উপর নির্ভর করে যদি কোনও আইটেম না থাকে তবে কী ঘটতে হবে এবং এখনও আপনার কেবল একটি একক পদ্ধতি সরবরাহ করতে হবে


1 আমি এটা ভালো কিছু হয় অনুমান try?মধ্যে gnasher729s উত্তর কিন্তু এটি সম্পূর্ণরূপে আমাকে পরিষ্কার করা হয় না হিসাবে আমি সুইফট জানি না এবং এটি তাই এটি সুইফট নির্দিষ্ট একটি ভাষা বৈশিষ্ট্য বলে মনে হয়।

2 আপনি অন্যান্য কারণেও ব্যতিক্রম ছুঁড়ে ফেলতে পারেন, উদাহরণস্বরূপ, কোনও আইটেম আছে কিনা তা আপনি যদি জানেন না বা আপনার ডাটাবেসের সাথে যোগাযোগের ক্ষেত্রে সমস্যা ছিল কারণ।


0

আরেকটি বিষয় দুটি পদ্ধতি ব্যবহারের সাথে একমত হওয়ায় এটি কার্যকর করা খুব সহজ হতে পারে। আমি সি # তে আমার উদাহরণটি লিখব, যেহেতু আমি পিএইচপি-র সিনট্যাক্স জানি না।

public Widget GetWidgetOrNull(int id) {
    // All the lines to get your item, returning null if not found
}

public Widget GetWidget(int id) {
    var widget = GetWidgetOrNull(id);

    if (widget == null) {
        throw new WidgetNotFoundException();
    }

    return widget;
}

0

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

public int GetValue(); // If you can't get the value, you'll throw me an exception
public int GetValueOrDefault(); // If you can't get the value, you'll return me 0, since it's the default for ints

ট্রাইডোসোমথিং () কোনও খারাপ প্যাটার্নও নয়।

public bool TryParse(string value, out int parsedValue); // If you return me false, I won't bother checking parsedValue.

পূর্ববর্তীটি পার্স স্টাফের ক্ষেত্রে বেশি ব্যবহৃত হয়, তবে আমি ডাটাবেস ইন্টারঅ্যাকশনগুলিতে প্রাক্তনটিকে দেখতে বেশি ব্যবহৃত হয়।

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


-1

অন্য লোকেরা অন্যথায় পরামর্শ দিলে আমি পরামর্শ দিচ্ছি যে ত্রুটিগুলি কীভাবে পরিচালনা করা উচিত তা বোঝানোর জন্য প্যারামিটার সহ একটি পদ্ধতি থাকা দুটি ব্যবহারের পরিস্থিতিতে পৃথক পদ্ধতি ব্যবহারের চেয়ে প্রয়োজনীয়। এটা কাম্য হতে পারে জন্য এছাড়াও জন্য স্বতন্ত্র এন্ট্রি পয়েন্ট আছে বনাম "ত্রুটি রিটার্ন ত্রুটি ইঙ্গিত" ব্যবহারগুলির "ত্রুটি ছোঁড়া", একটি এন্ট্রি পয়েন্ট উভয় ব্যবহার নিদর্শন পরিবেশন করা মোড়কের পদ্ধতিতে কোড অনুলিপি এড়াতে হবে পারেন না। একটি সাধারণ উদাহরণ হিসাবে, যদি কারও কারও কার্যাবলী থাকে:

Thing getThing(string x);
Thing tryGetThing (string x);

এবং একজন এমন ক্রিয়াকলাপ চায় যা একইভাবে আচরণ করে তবে এক্স বন্ধনীতে আবৃত দ্বারা, দুটি সেট র‌্যাপার ফাংশন লিখতে হবে:

Thing getThingWithBrackets(string x)
{
  getThing("["+x+"]");
}
Thing tryGetThingWithBrackets (string x);
{
  return tryGetThing("["+x+"]");
}

কীভাবে ত্রুটিগুলি পরিচালনা করতে পারে তার পক্ষে যুক্তি থাকলে কেবল একটি র‌্যাপারের প্রয়োজন হবে:

Thing getThingWithBrackets(string x, bool returnNullIfFailure)
{
  return getThing("["+x+"]", returnNullIfFailure);
}

যদি মোড়কটি যথেষ্ট সহজ হয় তবে কোড ডুপ্লিকেশন খুব খারাপ নাও হতে পারে, তবে যদি কখনও এটি পরিবর্তন করার প্রয়োজন হয় তবে কোডটিকে নকল করার জন্য কোনও পরিবর্তনকে নকল করতে হবে। এমনকি যদি কোনও ব্যক্তি অতিরিক্ত যুক্তি ব্যবহার না করে এমন এন্ট্রি পয়েন্টগুলি যুক্ত করতে পছন্দ করে:

Thing getThingWithBrackets(string x)
{
   return getThingWithBrackets(x, false);
}
Thing tryGetThingWithBrackets(string x)
{
   return tryGetThingWithBrackets(x, true);
}

একটি সমস্ত পদ্ধতিতে "ব্যবসায় যুক্তি" রাখতে পারে - ব্যর্থতার ক্ষেত্রে কী করা উচিত তা নির্দেশ করে এমন যুক্তি গ্রহণ করে।


আপনি ঠিক বলেছেন: দুটি পদ্ধতি ব্যবহার করার সময় সজ্জক এবং মোড়ক এমনকি নিয়মিত প্রয়োগকরণের কিছু কোড ডুপ্লিকেশন থাকবে।
ডনকিক্সোট

অবশ্যই পৃথক প্যাকেজগুলিতে ব্যতিক্রম ছাড়াই সংস্করণগুলি রাখুন এবং মোড়কে জেনেরিক করুন?
উইল ক্রফোর্ড

-1

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

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

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

আমার জন্য বাস্তব জীবনের উদাহরণ: একটি গণিতের পাঠাগার। যদি আপনার গণিত গ্রন্থাগারের কোনও Vectorশ্রেণি থাকে যা একই দিকের ইউনিট ভেক্টর পাওয়ার পক্ষে সমর্থন করে তবে আপনাকে প্রস্থ দ্বারা বিভাজন করতে সক্ষম হতে হবে। দৈর্ঘ্য যদি 0 হয় তবে আপনার শূন্য পরিস্থিতিতে বিভাজন রয়েছে। বিকাশে আপনি এগুলি ধরতে চান । আপনি 0 টি প্রায় ফাঁসি দিয়ে আশ্চর্যজনক বিভাজন চান না। একটি ব্যতিক্রম নিক্ষেপ এর জন্য খুব জনপ্রিয় সমাধান। এটি প্রায়শই ঘটে না (এটি সত্যই ব্যতিক্রমী আচরণ) তবে এটি যখন ঘটে তখন আপনি এটি জানতে চান।

এম্বেড থাকা প্ল্যাটফর্মে আপনি এই ব্যতিক্রমগুলি চান না। এটি একটি চেক করতে আরও বুদ্ধিমান হবে if (this->mag() == 0) return Vector(0, 0, 0);। আসলে, আমি এটি বাস্তব কোডে দেখছি।

এখন ব্যবসায়ের দৃষ্টিকোণ থেকে চিন্তা করুন। আপনি এপিআই ব্যবহারের দুটি ভিন্ন উপায় শেখানোর চেষ্টা করতে পারেন:

// Development version - exceptions        // Embeded version - return 0s
Vector right = forward.cross(up);          Vector right = forward.cross(up);
Vector localUp = right.cross(forward);     Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit();        Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit();            Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit()         Vector localUpHat = localUp.tryUnit();

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

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

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.