সেরা অনুশীলন - ফাংশন কলের চারপাশে যদি মোড়ানো হয় বনাম ফাংশনে প্রহরী থাকলে প্রারম্ভিক প্রস্থান যোগ করা


9

আমি জানি এটি খুব ব্যবহারের ক্ষেত্রে সুনির্দিষ্ট হতে পারে তবে আমি নিজেকে এটি প্রায়শই ভাবছি ering একটি সাধারণত পছন্দসই বাক্য গঠন আছে?

আমি কোনও ফাংশনে যখন সবচেয়ে ভাল পন্থাটি জিজ্ঞাসা করছি না, আমি জিজ্ঞাসা করছি আমার তাড়াতাড়ি প্রস্থান করা উচিত বা আমি কেবল ফাংশনটি কল না করা উচিত।

ফাংশন কল কাছাকাছি যদি মোড়ানো


if (shouldThisRun) {
  runFunction();
}

আছে যদি ( গার্ড ) ফাংশনে

runFunction() {
  if (!shouldThisRun) return;
}

এই ফাংশনটিকে একাধিকবার বলা হয়ে থাকলে অবশ্যই পরবর্তী বিকল্পটিতে কোড ডুপ্লিকেশন হ্রাস করার সম্ভাবনা রয়েছে তবে কখনও কখনও আপনি এখানে ফাংশনটির একক-দায়িত্ব-নেস হারাতে পারেন বলে এটি এখানে যুক্ত করা ভুল মনে করে।


এখানে একটি উদাহরণ

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

আমি নিশ্চিত যে এটি কেবল আমার কিনা তবে আমি এই ফাংশনটিকে যথাসম্ভব খাঁটি রাখতে চাইলে এই অভ্যন্তরীণ ফাংশনটি পরীক্ষা করতে কিছুটা নোংরা লাগে - যদি আমি এটি কল করি তবে আমি স্থিতিটি আপডেট হওয়ার প্রত্যাশা করব। তবে আমি জানাতে পারছি না যে কয়েকটি জায়গা যেখানে আমি জানি যে এটির পরিবর্তিত না হওয়ার সম্ভাবনা রয়েছে সেখানে চেক করে কলটি लपेटানোর চেয়ে আরও ভাল।



3
@ জাগান না, এই প্রশ্নটি মূলত 'প্রারম্ভিক প্রস্থানে পছন্দসই বাক্য গঠন কী' তবে আমার 'আমার কি খুব তাড়াতাড়ি প্রস্থান করা উচিত বা আমাকে কেবল ফাংশনটি কল করা উচিত নয়'
ম্যাথু মুলিন

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

"আমি কেবল তখনই স্ট্যাটাসটি আপডেট করতে চাই যদি স্ট্যাটাসটি পরিবর্তিত হয়" - আপনি কি একই স্ট্যাটাসটি পরিবর্তিত হলে কোনও স্ট্যাটাস আপডেট (= পরিবর্তিত) চান? বেশ চমকপ্রদ মনে হচ্ছে। আপনি দয়া করে এটির অর্থ কী তা বোঝাতে পারেন, তাই আমি এই সম্পর্কে আমার উত্তরে একটি অর্থবহ উদাহরণ যুক্ত করতে পারি?
ডক ব্রাউন

উদাহরণস্বরূপ @ ডকব্রাউন লেটস বলুন আমি দুটি পৃথক বস্তুর স্থিতির বৈশিষ্ট্য সিঙ্কে রাখতে চাই। উভয় বস্তুর পরিবর্তন হলে আমি সিঙ্ক স্ট্যাটাসগুলিকে কল করি () - তবে এটি বিভিন্ন ক্ষেত্রের পরিবর্তনের জন্য (কেবলমাত্র স্থিতি ক্ষেত্র নয়) ট্রিগার হতে পারে।
ম্যাথু মুলিন

উত্তর:


15

কোনও ফাংশন কলকে ঘিরে যদি একটি মোড়ানো:
এটি ফাংশনটি আদৌ বলা উচিত কিনা তা সিদ্ধান্ত নেওয়া এবং এটি আপনার প্রোগ্রামের সিদ্ধান্ত গ্রহণের প্রক্রিয়ার অংশ।

ফাংশনে গার্ড ক্লজ (প্রারম্ভিক রিটার্ন):
এটি অবৈধ পরামিতিগুলির সাথে ডাকা থেকে রক্ষা করা

এইভাবে ব্যবহৃত একটি গার্ডের ধারাটি "খাঁটি" (আপনার শব্দ) ফাংশনটি রাখে। এটি কেবলমাত্র তা নিশ্চিত করার জন্যই বিদ্যমান যে ভুল কাজটি ইনপুট ডেটা দিয়ে ফাংশনটি ভেঙে যায় না।

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

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

এই বিচ্ছিন্ন রেখে, আপনি নিশ্চিত হন যে আপনার কোডটি লেখা, পড়া এবং বজায় রাখা সহজ হবে be


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

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

7

আপনার উভয় থাকতে পারে - এমন একটি ফাংশন যা প্যারামিটারগুলি পরীক্ষা করে না এবং অন্যটি যা এইগুলি করে (সম্ভবত কলটি হয়েছে কিনা সে সম্পর্কে কিছু তথ্য ফেরত পাঠানো হবে):

bool tryRunFunction(...)
{
    bool shouldThisRun = /* some logic using data not available inside "runFunction"*/;
    if (shouldThisRun)
        runFunction();
    return shouldThisRun;
}

এইভাবে, আপনি পুনঃব্যবহারযোগ্য সরবরাহ করে ডুপ্লিকেট যুক্তি এড়াতে পারেন tryRunFunctionএবং এখনও আপনার মূল (সম্ভবত বিশুদ্ধ) ফাংশন থাকতে পারে যা চেকটি ভিতরে না করে।

মনে রাখবেন যে কখনও কখনও আপনার tryRunFunctionএকচেটিয়াভাবে একীভূত চেকের মতো ফাংশন প্রয়োজন হয়, যাতে আপনি চেকটি সংহত করতে পারেন runFunction। অথবা আপনার প্রোগ্রামে আবার কোথাও চেকটি পুনরায় ব্যবহার করার দরকার নেই, সেক্ষেত্রে আপনি এটিকে কলিং ফাংশনে থাকতে দিতে পারেন।

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


1
স্বীকার করতে হবে, "ট্রাইএক্সএক্সএক্সএক্সএক্স ()" প্রতিবাদটি সর্বদা কিছুটা দূরে মনে হয়েছিল এবং এটি এখানে অনুপযুক্ত। আপনি সম্ভাব্য ত্রুটির প্রত্যাশায় কিছু করার চেষ্টা করছেন না। নোংরা হলে আপনি আপডেট করছেন।
ব্যবহারকারী949300

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

"ড্রাইআরুন" নামে কিছু নেই? কমবেশি পার্শ্ব প্রতিক্রিয়া ছাড়াই নিয়মিত কার্যকর হতে চলেছে। পার্শ্ব প্রতিক্রিয়াগুলি কীভাবে অক্ষম করা যায় তা অন্য গল্প
লাইভ

3

কে দৌড়াতে হবে কিনা সে সম্পর্কে সিদ্ধান্তটি উত্তর, জিআরএসপি থেকে , "তথ্য বিশেষজ্ঞ" কে জানেন।

একবার আপনি এটি স্থির করার পরে, স্পষ্টতার জন্য ফাংশনটির নামকরণের বিষয়টি বিবেচনা করুন।

ফাংশনটি যদি সিদ্ধান্ত নেয়:

 ensureUpdated()
 updateIfDirty()

বা, যদি কলার সিদ্ধান্ত নেওয়ার কথা বলে:

 writeStatus()

2

আমি @ বাল্ড্রিকের উত্তরটি প্রসারিত করতে চাই।

আপনার প্রশ্নের কোনও সাধারণ উত্তর নেই। এটি কল করা ফাংশনের অর্থ (চুক্তি) এবং শর্তের প্রকৃতির উপর নির্ভর করে।

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

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

updateStatus()ফাংশনের অভ্যন্তরে এমন পরিস্থিতি থাকতে পারে যেখানে এই ফাংশনটি সনাক্ত করতে পারে (এর ডোমেন দিগন্তের অভ্যন্তরের ডেটা থেকে) যা করার মতো কিছুই নেই এবং সেখানেই এটি ফিরে আসা উচিত।

সুতরাং, প্রশ্নগুলি হ'ল:

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

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


2

অনেক ভাল ব্যাখ্যা আছে। তবে আমি অস্বাভাবিক উপায়ে দেখতে চাই: ধরে নিন যে আপনি এইভাবে ব্যবহার করেছেন:

if (shouldThisRun) {
   runFunction();
}

runFunction() {
   if (!shouldThisRun) return;
}

এবং আপনাকে runFunctionএই পদ্ধতিতে অন্য ফাংশনটি কল করতে হবে :

runFunction() {
   if (!shouldThisRun) return;
   someOtherfunction();
}

তুমি কি করবে? আপনি কি সমস্ত বৈধতা উপর থেকে নীচে অনুলিপি করেন?

someOtherfunction() {
   if (!shouldThisRun) return;
}

আমি তাই মনে করি না. সুতরাং, আমি সাধারণত একই পদ্ধতি করি: পদ্ধতিতে ইনপুটগুলিকে বৈধতা দিন এবং শর্তগুলি পরীক্ষা করুন public পাবলিক পদ্ধতিগুলির নিজস্ব বৈধতাগুলি করা উচিত এবং প্রয়োজনীয় শর্তগুলি এমনকি কলকারীরাও পরীক্ষা করে। তবে ব্যক্তিগত পদ্ধতিগুলি কেবল তার নিজস্ব ব্যবসা করতে দিন । অন্য কোনও ফাংশন runFunctionকোনও শর্ত যাচাই বা পরীক্ষা না করে কল করতে পারে ।

public someFunction() {
   if (shouldThisRun) {
      runFunction();
   }
}

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