রিটার্ন খারাপ স্টাইল / বিপজ্জনক পরে কাজ করার জন্য শেষ অবধি ব্যবহার কি?


30

একজন আইট্রেটার লেখার অংশ হিসাবে, আমি নিজেকে নীচের কোডের টুকরা (স্ট্রিপিং ত্রুটি পরিচালনার ক্ষেত্রে) লিখতে দেখলাম

public T next() {
  try {
    return next;
  } finally {
    next = fetcher.fetchNext(next);
  }
}

এটি পড়ার চেয়ে কিছুটা সহজ খুঁজে পেয়েছি

public T next() {
  T tmp = next;
  next = fetcher.fetchNext(next);
  return tmp;
}

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

যদি খারাপ হয়: কেন? স্টাইল, পারফরম্যান্স, দুর্যোগ, ...?

উপসংহার আপনার সমস্ত উত্তর ধন্যবাদ! আমি উপসংহারটি অনুমান করি (কমপক্ষে আমার জন্য) এটি হ'ল প্রথম উদাহরণটি যদি সাধারণ প্যাটার্ন হয় তবে এটি আরও বেশি পাঠযোগ্য হতে পারে তবে এটি তা নয় isn't সুতরাং এটির উদ্দেশ্য ব্যতীত কোনও কনস্ট্রাক্ট ব্যবহার করে যে বিভ্রান্তি সংঘটিত হয়েছে তা সম্ভবত অস্পষ্ট ব্যতিক্রম প্রবাহের সাথে যেকোন সরলকরণকে ছাড়িয়ে যাবে।


10
আমি ব্যক্তিগতভাবে প্রথমটির চেয়ে দ্বিতীয়টিকে আরও বুঝতে সক্ষম হব, তবে আমি খুব কমই finallyব্লক ব্যবহার করি ।
খ্রিস্টান মান

2
রিটার্ন কারেন্ট = fetcher.fetchNext (বর্তমান); // এটি কীভাবে, ওরফে আপনার সত্যিই প্রিফেচিং দরকার?
স্কার্ফ্রিজ

1
@scarfridge উদাহরণ বাস্তবায়ন সম্পর্কে Iterator, যেখানে আপনাকে hasNext()কাজ করার জন্য প্রকৃতপক্ষে প্রেফেচিংয়ের প্রয়োজন । এটি নিজে চেষ্টা করো.
মার্টিনাস

1
@ মাআর্টিনাস আমি এটি সম্পর্কে অবহিত। কখনও কখনও হ্যাশেক্সট () কেবল সত্য উদাহরণ দেয় যেমন শিলাবৃত্তির ক্রম এবং কখনও কখনও পরবর্তী উপাদানগুলি আনতে নিষেধাত্মক ব্যয় হয়। পরবর্তী ক্ষেত্রে আপনার অলস প্রারম্ভিকরণের অনুরূপ চাহিদা অনুযায়ী উপাদান আনতে অবলম্বন করা উচিত।
স্কার্ফ্রিজে

1
@scarfridge এর সাধারণ ব্যবহারের ক্ষেত্রে সমস্যাটি Iteratorহ'ল আপনাকে মানটি hasNext()আনতে হবে ('এটি আনার কারণ এটি প্রায়শই একমাত্র উপায় এটি বিদ্যমান কিনা তা খুঁজে বের করতে পারে) এবং ওপি'র মতোই এটি ফিরিয়ে আনতে হবে next()
মার্টিনাস

উত্তর:


18

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

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

সুতরাং, আপনি যদি অ্যাক্সেসর কলগুলি থেকে রাষ্ট্রীয় রূপান্তরকে আলাদা করেন? আপনি যে পাঠযোগ্যতার বিষয়টি নিয়ে উদ্বিগ্ন তা ভাববাদী হয়ে উঠতে পারে তা আমি কল্পনা করব তবে কীভাবে এটি আপনার বিস্তৃত বিমূর্তিকে প্রভাবিত করে তা আমি জানি না। কিছু বিবেচনা করার জন্য, যাইহোক।


1
"চালাক" মন্তব্যের জন্য +1। এটি খুব নির্ভুলভাবে এই উদাহরণটি ধারণ করে।

2
পরবর্তী () এর 'রিটার্ন এবং অগ্রিম' ক্রিয়াটি অপ্রতিরোধ্য জাভা পুনরায় ইন্টারফেসের মাধ্যমে ওপিকে চাপিয়ে দেওয়া হয়।
কেভিন cline

37

বিশুদ্ধরূপে একটি স্টাইলের দৃষ্টিকোণ থেকে, আমি এই তিনটি লাইন মনে করি:

T current = next;
next = fetcher.getNext();
return current;

... চেষ্টা / শেষ অবরুদ্ধের চেয়ে দু'টিই আরও সুস্পষ্ট এবং খাটো। যেহেতু আপনি কোনও ব্যতিক্রম নিক্ষেপ হওয়ার প্রত্যাশা করছেন না, তাই tryব্লক ব্যবহার করা মানুষকে বিভ্রান্ত করছে।


2
একটি চেষ্টা / ধরা / অবশেষে ব্লকটি অতিরিক্ত ওভারহেড যুক্ত করতে পারে, আমি নিশ্চিত নই যে জাভাক বা জেআইটি সংকলক এগুলি ছিনিয়ে নেবে এমনকি আপনি কোনও ব্যতিক্রম ছোঁড়াচ্ছেন না।
মার্টিজ ভার্বার্গ

2
@ মার্তিজনভের্গবার্গ হ্যাঁ, জাভাক এখনও ব্যতিক্রম টেবিলটিতে একটি এন্ট্রি যুক্ত করে এবং চেষ্টা ব্লকটি ফাঁকা থাকলেও শেষ পর্যন্ত কোডটি নকল করে।
ড্যানিয়েল লুবারভ

@ ড্যানিয়েল - ধন্যবাদ জাভাপ সম্পাদনা করতে আমি খুব অলস ছিলাম :-)
মার্তিজান ভারবার্গ

@ মার্তিজান ভার্বার্গ: এএফআইএইচ, একটি চেষ্টা-ধরা-ফিনাল্ট ব্লক যতক্ষণ না প্রকৃত ব্যতিক্রম ততক্ষণ অবধি মুক্ত। এখানে জাভ্যাক চেষ্টা করে না এবং জেআইটি এটির যত্ন নেবে বলে কোনও কিছুই অপ্টিমাইজ করার দরকার নেই।
maaartinus

@ মাআরটিইনস - ধন্যবাদ যে এটি উপলব্ধি করে - আবার
ওপেনজেডিকে

6

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

"সেখানে কোনও ব্যতিক্রম জড়িত নেই" যখন আমি এটি ব্যবহার করতে কোনও সমস্যা দেখি না। কোডটি কেবল ছুঁড়ে ফেলতে পারে এবং আপনি এগুলি পরিচালনা করার পরিকল্পনা করেন না তা try...finallyছাড়া এটি ব্যবহার করা খুব সাধারণ । কখনও কখনও, শেষ অবধি কেবল একটি সুরক্ষাকারী এবং আপনি জানেন যে আপনার প্রোগ্রামের যুক্তির জন্য যে কোনও ব্যতিক্রম কখনও ছুঁড়ে দেওয়া হবে না (ক্লাসিক "এটি কখনই ঘটবে না" শর্ত)।catchRuntimeException

অসুবিধাগুলি: tryব্লকের অভ্যন্তরে উত্থাপিত কোনও ব্যতিক্রম finallyবকটিকে চালিয়ে দেবে। এটি আপনাকে একটি বেমানান অবস্থায় ফেলতে পারে। সুতরাং, যদি আপনার ফেরতের বিবৃতিটি এমন কিছু ছিল:

return preProcess(next);

এবং এই কোডটি একটি ব্যতিক্রম উত্থাপন করেছে, fetchNextএখনও চলবে। আপনি যদি এটিকে কোড করে থাকেন তবে:

T ret = preProcess(next);
next = fetcher.fetchNext(next);
return ret;

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

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


আপনি আসলে এইভাবে ব্যবহার এড়াতে খুব ভাল কারণ সরবরাহ করছেন finallyনা, তাহলে? আমার অর্থ, আপনি যেমনটি বলেছেন, কোডটি অযাচিত ফলাফলগুলি শেষ করে; আরও খারাপ, আপনি সম্ভবত ব্যতিক্রমগুলি নিয়ে ভাবছেন না।
Andres F.

2
সাধারণ নিয়ন্ত্রণ প্রবাহের গতি ব্যতিক্রম-হ্যান্ডলিং নির্মাণগুলি দ্বারা উল্লেখযোগ্যভাবে প্রভাবিত হয় না। পারফরম্যান্স পেনাল্টি কেবল তখনই ব্যতিক্রম ছুঁড়ে ফেলা এবং ধরা দেওয়ার সময় প্রদান করা হয়, যখন কোনও ট্রাই ব্লকে প্রবেশ করার সময় বা স্বাভাবিক ক্রিয়ায় শেষ অবধি প্রবেশের সময় নয়।
yfeldblum

1
@AndresF। সত্য, তবে এটি কোনও ক্লিনআপ কোডের জন্যও বৈধ । উদাহরণস্বরূপ, ধরুন nullকোনও বগি কোড দ্বারা একটি মুক্ত স্ট্রিমের রেফারেন্স সেট করা আছে ; এটি থেকে পড়ার চেষ্টা করা একটি ব্যতিক্রম উত্থাপন করবে, finallyব্লকে এটি বন্ধ করার চেষ্টা করলে অন্য একটি ব্যতিক্রম বাড়ে । তদ্ব্যতীত, এটি এমন একটি পরিস্থিতি যেখানে গণনার অবস্থা গুরুত্বপূর্ণ নয়, আপনি কোনও ব্যতিক্রম ঘটেছে কিনা তা প্রবাহ বন্ধ করতে চান। সেই মতো অন্যান্য পরিস্থিতিও থাকতে পারে। এই কারণে আমি এটিকে কখনই ব্যবহার না করার জন্য ক্ষতিপূরণ হিসাবে বৈধ ব্যবহারের জন্য একটি ক্ষতি হিসাবে বিবেচনা করছি।
এমজিবিসনব্রব

এ ছাড়াও সমস্যাটি রয়েছে যে চেষ্টা এবং অবশেষে উভয়ই ব্যতিক্রম একটি ব্যতিক্রম ছুঁড়ে মারলে, চেষ্টা ব্যতিক্রমটি কখনই কারও কাছে দেখা যায় না, তবে সম্ভবত এটি সমস্যার কারণ the
হ্যান্স-পিটার স্টার

3

শিরোনামের বিবৃতি: "... অবশেষে ফিরে আসার পরে কাজ করার ধারা ..." মিথ্যা। ফাংশন ফিরে আসার আগে অবশেষে ব্লকটি ঘটে। এটি আসলে অবশেষে পুরো পয়েন্ট।

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

অবশেষে ব্লকগুলির উদ্দেশ্যমূলক ব্যবহার ব্যতিক্রম হ্যান্ডলিংয়ের জন্য যেখানে ব্যতিক্রম ছোঁড়া ছাড়াই কিছু পরিণতি ঘটতে হবে যেমন কিছু সংস্থান সাফ করা, ডিবি সংযোগ বন্ধ করা, একটি ফাইল / সকেট বন্ধ করা ইত্যাদি must


+1, আমি যোগ করব যে ভাষা স্পেস যদি গ্যারান্টি দেয় যে মানটি ফিরে আসার আগে এটি সংরক্ষণ করা হয় তবে এটি পাঠকের প্রত্যাশার বিরুদ্ধে যায় এবং যুক্তিযুক্তভাবে সম্ভব হলে এড়ানো উচিত। ডিবাগিং কোডিংয়ের চেয়ে দ্বিগুণ শক্ত ...
jmoreno

0

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

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

এগুলির কারণে, যে কেউ এটি পড়ছে তাদের অবশ্যই এই সমস্যাগুলি সম্পর্কে ভাবতে হবে, তাই এটি বোঝা শক্ত।

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