কার্যনির্বাহী প্রোগ্রামিং নির্ভরতা ইনজেকশন নিদর্শনগুলির একটি কার্যকর বিকল্প?


21

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

যদি আমি উভয় পদ্ধতির সাথে অভিজ্ঞতা সম্পন্ন কেউ প্রাথমিক প্রশ্নের উত্তর দেওয়ার জন্য তাদের চিন্তাভাবনা এবং অভিজ্ঞতা ভাগ করে নিতে পারে তবে আমি প্রশংসা করব: কার্যকারিতা প্রোগ্রামিং নির্ভরতা ইনজেকশন নিদর্শনগুলির একটি কার্যকর বিকল্প কি?


10
এটি আমার কাছে খুব একটা বোঝায় না, অপরিবর্তনশীলতা নির্ভরতাগুলি সরিয়ে দেয় না।
তেলস্তিন

আমি সম্মত হই যে এটি নির্ভরতা অপসারণ করে না। এটি সম্ভবত আমার বোঝাপড়াটি ভুল, তবে আমি সেই অনুভূতিটি তৈরি করেছি কারণ যদি আমি মূল বস্তুটি পরিবর্তন করতে না পারি তবে এটি অবশ্যই এটি ব্যবহার করে এমন কোনও ক্রিয়াকলাপের সাথে (এটি ইনজেকশন) প্রেরণ করা প্রয়োজন।
ম্যাট ক্যাস্যাট


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

1
এই প্রশ্নটি, এর সাথে নিবন্ধগুলি লিঙ্ক করেছে এবং স্বীকৃত উত্তরটিও কার্যকর হতে পারে: stackoverflow.com/questions/11276319/… ভীতিজনক মোনাড শব্দটি উপেক্ষা করুন। রুনার তার উত্তরে যেমন উল্লেখ করেছেন, এটি এই ক্ষেত্রে কোনও জটিল ধারণা নয় (কেবল একটি ফাংশন)।
itbruce

উত্তর:


27

নিম্নলিখিত দুটি কারণে ওওপিতে নির্ভরতা পরিচালনা একটি বড় সমস্যা:

  • ডেটা এবং কোডের আঁটসাঁট মিলন।
  • পার্শ্ব প্রতিক্রিয়া সর্বব্যাপী ব্যবহার।

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

পার্শ্ব প্রতিক্রিয়া ব্যবহার অনুরূপ অসুবিধা সৃষ্টি করে। আপনি যদি কিছু কার্যকারিতার জন্য পার্শ্ব প্রতিক্রিয়া ব্যবহার করেন তবে এর বাস্তবায়নটি অদলবদল করতে সক্ষম হতে চান তবে সেই নির্ভরতা ইনজেকশন ছাড়া আপনার কাছে অন্য কোনও বিকল্প নেই।

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

  • কোনও ওয়েব পৃষ্ঠার ঠিকানা ইনপুট করুন, সেই পৃষ্ঠার পাঠ্যটিকে আউটপুট দিন।
  • কোনও পৃষ্ঠার পাঠ্য ইনপুট করুন, সেই পৃষ্ঠা থেকে লিঙ্কগুলির একটি তালিকা আউটপুট করুন।
  • কোনও পৃষ্ঠার পাঠ্য ইনপুট করুন, সেই পৃষ্ঠায় ইমেল ঠিকানাগুলির একটি তালিকা আউটপুট করুন।
  • ইমেল ঠিকানাগুলির একটি তালিকা ইনপুট করুন, নকল মুছে ফেলা সহ ইমেল ঠিকানার একটি তালিকা আউটপুট করুন।
  • একটি ইমেল ঠিকানা ইনপুট করুন, সেই ঠিকানার জন্য একটি স্প্যাম ইমেল আউটপুট করুন।
  • একটি স্প্যাম ইমেল ইনপুট করুন, এই ইমেলটি প্রেরণের জন্য SMTP কমান্ডগুলি আউটপুট করুন।

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

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

মনে রাখবেন যে এটি নির্ভরশীলতা নয় যা সমস্যাযুক্ত। এটি নির্ভরতা যা ভুল পথে নির্দেশ করে। পরবর্তী স্তরটির মতো একটি ফাংশন থাকতে পারে:

processText = spamToSMTP . emailAddressToSpam . removeEmailDups . textToEmailAddresses

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

processTextFancy = spamToSMTP . emailAddressToFancySpam . removeEmailDups . textToEmailAddresses

পার্শ্ব প্রতিক্রিয়াগুলির অভাবের ফলে এই সহজ পুনরায় সাজানো সম্ভব হয়েছে। নিম্ন স্তরের ফাংশন একে অপরের থেকে সম্পূর্ণ স্বতন্ত্র। পরবর্তী স্তর আপ চয়ন করতে পারে processTextআসলে কিছু ব্যবহারকারীর কনফিগারেশনের উপর ভিত্তি করে ব্যবহৃত হয়:

actuallyUsedProcessText = if (config == "Fancy") then processTextFancy else processText

আবার কোনও সমস্যা নয় কারণ সমস্ত নির্ভরতা এক দিক নির্দেশ করে। সেগুলি একইভাবে নির্দেশ করার জন্য আমাদের কিছু নির্ভরতা উল্টে দেওয়ার দরকার নেই, কারণ খাঁটি ফাংশনগুলি ইতিমধ্যে আমাদের তা করতে বাধ্য করেছিল।

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


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

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

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

@ ম্যাথেজপ্যাট্রিকক্যাশট এটি স্টাইল বা দৃষ্টান্তের বিষয় নয়, ভাষা বৈশিষ্ট্যের বিষয়। যদি ভাষাটি প্রথম শ্রেণীর জিনিস হিসাবে মডিউলগুলি সমর্থন করে না, আপনি বাস্তবায়ন অদলবদল করতে কিছু ফর্ম গতিশীল প্রেরণ এবং নির্ভরতা ইনজেকশন করতে হবে, কারণ স্থিতিশীলভাবে নির্ভরতা প্রকাশ করার উপায় নেই। এটিকে কিছুটা আলাদাভাবে বলতে গেলে, যদি আপনার সি # প্রোগ্রামে স্ট্রিং ব্যবহার করা হয় তবে এটির উপর হার্ড কোডিং নির্ভরতা রয়েছে System.String। একটি মডিউল সিস্টেম আপনাকে System.Stringভেরিয়েবলের সাথে প্রতিস্থাপন করতে দেবে যাতে স্ট্রিং বাস্তবায়নের পছন্দটি হার্ড-কোডড না হয় তবে সংকলনের সময়ে সমাধান করা যায়।
ডোভাল

8

কার্যনির্বাহী প্রোগ্রামিং নির্ভরতা ইনজেকশন নিদর্শনগুলির একটি কার্যকর বিকল্প কি?

এটি আমাকে একটি বিজোড় প্রশ্ন হিসাবে আঘাত করে। কার্যক্ষম প্রোগ্রামিং পদ্ধতির নির্ভরতা ইনজেকশনের ক্ষেত্রে বেশিরভাগ ক্ষেত্রেই স্পর্শকাতর।

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

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

যদি কিছু হয় তবে প্রোগ্রামাররা খুব কমই ভাবেন তার চেয়ে ওও কোড কীভাবে অন্তর্নিহিত নির্ভরতা তৈরি করতে পারে তা তারা আপনাকে দেখিয়েছে।


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

(উপর থেকে অবিরত) । .হোক যাইহোক এটি আমার বর্তমান বোঝাপড়া। আমি চিহ্নটি মিস করছি কিনা দয়া করে আমাকে জানান। আমি এখানে দানবীয়দের মধ্যে একমাত্র নশ্বর মানুষ তা স্বীকার করতে আমার আপত্তি নেই!
ম্যাট ক্যাস্যাট

@ ম্যাথেজপ্যাট্রিকক্যাশট - ডিআই অবশ্যই রানটাইম নির্ভরতা ইস্যু বোঝায় না, যা আপনারা লক্ষ্য করেছেন, ভয়াবহ।
টেলাস্টিন

7

আপনার প্রশ্নের দ্রুত উত্তরটি হ'ল: না

অন্যরা যেমন দৃ have়ভাবে বলেছেন, প্রশ্নটি দুটি, কিছুটা সম্পর্কযুক্ত ধারণা থেকে বিবাহ করে।

আসুন এই ধাপে ধাপে।

ডিআই-এর ফলাফল অ-কার্যকরী শৈলীতে

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

ডিআই এর অর্থ সাধারণত আপনার ইউনিট আর খাঁটি থাকে না কারণ ইনজেকশনের উপর নির্ভর করে আউটপুট পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, নিম্নলিখিত ফাংশনে:

const bookSeats = ( seatCount, getBookedSeatCount ) => { ... }

getBookedSeatCount(একটি ফাংশন) একই প্রদত্ত ইনপুটটির জন্য বিভিন্ন ফলাফল প্রদানের ক্ষেত্রে পৃথক হতে পারে। এটি bookSeatsপাশাপাশি অপবিত্র করে তোলে ।

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

একটি সিস্টেম বিশুদ্ধ হতে পারে না

কোনও সিস্টেম শুদ্ধ হতে পারে না এই বিষয়টি কার্যকরী প্রোগ্রামিং উত্সগুলিতে দৃ .়তার সাথে সমানভাবে উপেক্ষা করা হয়।

একটি সিস্টেমের স্পষ্ট উদাহরণগুলির সাথে পার্শ্ব প্রতিক্রিয়া থাকতে হবে:

  • UI 'তে
  • ডেটাবেস
  • এপিআই (ক্লায়েন্ট-সার্ভার আর্কিটেকচারে)

সুতরাং আপনার সিস্টেমের কিছু অংশ অবশ্যই পার্শ্ব প্রতিক্রিয়াগুলিকে জড়িত করতে পারে এবং সেই অংশটিতে অবশ্যই আবশ্যক শৈলী বা ওও শৈলী জড়িত থাকতে পারে।

শেল-কোর দৃষ্টান্ত

গিরি বার্নহার্টের সীমানা সম্পর্কে দুর্দান্ত আলোচনা থেকে শর্তাদি নেওয়া , একটি ভাল সিস্টেম (বা মডিউল) আর্কিটেকচারে এই দুটি স্তর অন্তর্ভুক্ত থাকবে:

  • মূল
    • খাঁটি ফাংশন
    • শাখাবিন্যাস
    • কোনও নির্ভরতা নেই
  • খোল
    • অশুদ্ধ (পার্শ্ব প্রতিক্রিয়া)
    • কোন শাখা নেই
    • নির্ভরতা
    • অপরিহার্য হতে পারে, OO স্টাইল জড়িত ইত্যাদি

মূল গ্রহণটি হ'ল সিস্টেমটিকে শুদ্ধ অংশ (মূল) এবং অপবিত্র অংশ (শেল) এর মধ্যে বিভক্ত করা।

যদিও কিছুটা ত্রুটিযুক্ত সমাধান (এবং উপসংহার) সরবরাহ করা হচ্ছে, এই মার্ক সিমনের নিবন্ধটি একই ধারণাটির প্রস্তাব দেয়। হাস্কেল বাস্তবায়ন বিশেষত অন্তর্দৃষ্টিযুক্ত কারণ এটি দেখায় যে এফপি ব্যবহার করে এটি সবই করা যায়।

ডিআই এবং এফপি

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

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

উপসংহার

সুতরাং এফপি এবং ডিআই হুবহু বিকল্প নয়। আপনার সিস্টেমে আপনার উভয়ই থাকতে পারে এবং পরামর্শটি হ'ল সিস্টেমের খাঁটি এবং অপরিষ্কার অংশের মধ্যে পৃথকীকরণ নিশ্চিত করা, যেখানে যথাক্রমে এফপি এবং ডিআই থাকে।


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

@ জারহালি দয়া করে বিশদের জন্য গ্যারি বার্নহার্টের টকটি দেখুন (উত্তরে লিঙ্কিত)।
ইজাকি


1

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

ইন্টারফেস একটি ফাংশন চেয়ে শক্তিশালী চুক্তি।

আপনি যদি একটি কার্যকরী পদ্ধতির ব্যবহার করে থাকেন এবং প্রচুর ডিআই করেন তবে একটি ওওপি পদ্ধতির ব্যবহারের তুলনায় আপনি প্রতিটি নির্ভরতার জন্য আরও প্রার্থী পাবেন।

void DoStuff(Func<DateTime> getDateTime) {}; //Anything that satisfies the signature can be injected.

বনাম

void DoStuff(IDateTimeProvider dateTimeProvider) {}; //Only types implementing the interface can be injected.

3
ইন্টারফেস বাস্তবায়নের জন্য যে কোনও শ্রেণি মোড়ানো যায় যাতে "শক্তিশালী চুক্তি" বেশি শক্তিশালী না হয়। আরও গুরুত্বপূর্ণভাবে প্রতিটি ফাংশনকে আলাদা ধরণের দেওয়া ফাংশন রচনাটি করা অসম্ভব করে তোলে।
ডোভাল

ক্রিয়ামূলক প্রোগ্রামিং এর অর্থ "উচ্চতর ক্রম ফাংশন সহ প্রোগ্রামিং" নয়, এটি একটি আরও বিস্তৃত ধারণা বোঝায়, উচ্চতর অর্ডার ফাংশনগুলি দৃষ্টান্তে দরকারী একটি কৌশল।
জিমি হোফা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.