কেন এমন একটি পদ্ধতি আছে যা একটি বুল / ইনট রিটার্ন দেয় এবং আউটপুট প্যারামিটার হিসাবে আসল অবজেক্ট থাকে?


12

আমি আমার সংস্থার কোডবাসে (.NET 3.5 অ্যাপ্লিকেশন) সমস্ত জায়গায় নীচের কোড প্যাটার্নটি দেখতে পাচ্ছি:

bool Foo(int barID, out Baz bazObject) { 
    try { 
            // do stuff
            bazObject = someResponseObject;

            return true;
    }
    catch (Exception ex) { 
        // log error
        return false;
    }
}

// calling code
BazObject baz = new BazObject();
fooObject.Foo(barID, out baz);

if (baz != null) { 
    // do stuff with baz
}

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

এই কোডিং শৈলীর কোনও গোপন সুবিধা রয়েছে যা আমি মিস করছি?



আপনার উদাহরণে, bazহচ্ছে nullএবং ফিরে boolহচ্ছে falseহয় না সমতুল্য। new BazObject()না হয় nullতাই যদি না, bazObjectআগে আপডেট করা হয় Exceptionফেলে দেওয়া হয় Fooযখন, falseফিরিয়ে দেওয়া হয় bazহবে না null। এটা তোলে এইসা সাহায্য করবে বৈশিষ্ট জন্য Fooউপলব্ধ ছিল। আসলে, এই কোডটি প্রদর্শিত সম্ভবত এটি সবচেয়ে গুরুতর সমস্যা।
স্টিভ পাওয়েল

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

উত্তর:


11

আপনি সাধারণত সেই প্যাটার্নটি ব্যবহার করেন যাতে আপনি কোডটি লিখতে পারেন:

if (Foo(barId, out bazObject))
{
  //DoStuff with bazobject
}

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


1
+1, এ কারণেই আমি বুলিয়ান এবং অবজেক্ট উভয়কে আলাদা আলাদা করে ফিরিয়ে দেওয়ার পরিবর্তে কোনও বস্তুর প্রত্যাবর্তনের দিকে ঝোঁক
পিডিআর

কারণটির ব্যাখ্যা দেয় বলে এটিকে উত্তর হিসাবে চিহ্নিত করা, যদিও sensক্যমত্যটি নির্দিষ্ট পরিস্থিতিতে বাদে এটি বেশ পুরানো বলে মনে হচ্ছে।
ওয়েইন মোলিনা

এই উত্তরটি এই প্যাটার্নটির ব্যবহারকে ন্যায়সঙ্গত করে। তবে এটি যদি আপনার কোডবেস এর ওপরে থাকে তবে এটি সম্ভবত শন পাশের মতো খারাপ অভ্যাস।
কোডিজম

11

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

.Net এ আমরা সেই উদ্দেশ্যে ব্যতিক্রম। এই প্যাটার্নটি অনুসরণ করার কোনও কারণ থাকতে হবে না।

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


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

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

হ্যাঁ, এটি প্রধানত এমন পদ্ধতিগুলিতে ব্যবহৃত হয় যা ডাটাবেস থেকে ডেটা লোড করে যেমন উদাহরণস্বরূপ if (baz.Select())তবে প্রায়শই না ফেরার মানটি কেবল ফেলে দেওয়া হয় এবং মানটি নাল বা কিছু সংখ্যার বিরুদ্ধে পরীক্ষা করা হয়।
ওয়েইন মোলিনা

@ সিয়ান, আপনি কী বলছেন তা দেখুন, আমি কেবল "ইন। নেট এ উদ্দেশ্যে আমাদের ব্যতিক্রম আছে the" এই বাক্যটিতে আপত্তি জানায়। ব্যতিক্রমগুলি আমার জন্য সম্পূর্ণ ভিন্ন উদ্দেশ্যে পরিবেশন করে
পিডিআর

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

2

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

// calling code
BazObject baz = new BazObject();
bool result = fooObject.Foo(barID, out baz);

if (result) { 
    // do stuff with baz
    // where baz may be 
    // null without a 
    // thrown exception
}

এটি এইভাবে এটি করতে আমার আরও অর্থবোধ করবে। আপনি গ্যারান্টি দেওয়ার আগে ব্যবহার করার আগে সম্ভবত এটি এমন একটি পদ্ধতি যার মাধ্যমে বাজ রেফারেন্স দিয়ে পাস হচ্ছে কীভাবে অবজেক্টের পরামিতিগুলি সি # তে কাজ করে understanding


আমার মনে হয় এটি দলের বর্তমান সদস্য লিখেছেন। সম্ভবত ও-ওও সম্পর্কে আমার এই চিন্তিত হওয়া উচিত
ওয়েন মোলিনা

@ ওয়াইন এম: সম্ভাব্য প্রশিক্ষণের সুযোগের তুলনায় উদ্বেগের পরিমাণ কম :)
জোয়েল ইথারটন

1

কখনও কখনও এই প্যাটার্নটি কার্যকর হয় যখন আপনি, আহ্বানকারী, ফেরত টাইপটি কোনও রেফারেন্স বা মান ধরণের কিনা সেদিকে খেয়াল রাখবেন না। আপনি যদি কোনও মান ধরণের পুনরুদ্ধার করতে এই জাতীয় পদ্ধতিটি কল করে থাকেন তবে সেই মান টাইপের জন্য হয় একটি প্রতিষ্ঠিত অবৈধ মান (যেমন ডাবল.এনএএন) প্রয়োজন হবে, অথবা আপনার সাফল্য নির্ধারণের জন্য অন্য কোনও উপায়ের প্রয়োজন।


এটা বোধগম্য. কিছুটা অদ্ভুত লাগছে, তবে এটি একটি বৈধ কারণ বলে মনে হচ্ছে।
ওয়েইন মোলিনা

0

ধারণাটি এমন কোনও মান ফিরিয়ে দেবে যা নির্দেশ করে যে প্রক্রিয়াটি সফল হয়েছিল কিনা, এই জাতীয় কোডটি মঞ্জুর করে:

Baz b;
if (fooObject.foo(id, out b)) {
   // do something with b
}
else {
   Error.screamAndRun("object lookup/whatever failed! AAaAAAH!");
}

যদি বস্তুটি শূন্য না হতে পারে (যা আপনার উদাহরণে সঠিক প্রদর্শিত হয়), তবে নিম্নলিখিত হিসাবে এটি আরও ভালভাবে করা হয়েছে:

Baz b = fooObject.foo(id);
if (b != null) {
   // do something with b
}
else {
   Error.screamAndRun("object lookup/whatever failed! AAaAAAH!");
}

যদি বস্তুটি শূন্য হতে পারে তবে ব্যতিক্রমগুলি হ'ল উপায়:

try {
   Baz b = fooObject.foo(id);
}
catch (BazException e) {
   Error.screamAndRun("object lookup/whatever failed! AAaAAAH!");
}

এটি সিতে ব্যবহৃত একটি সাধারণ প্যাটার্ন, যেখানে কোনও ব্যতিক্রম নেই। এটি ফাংশনটিকে ত্রুটির শর্তটি ফিরিয়ে আনতে অনুমতি দেয়। ব্যতিক্রমগুলি সাধারণত অনেক ক্লিনার সমাধান are


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