কোনও ইন্টারফেসের পুরো বিন্দুটি কী নয় যে একাধিক শ্রেণি নিয়ম এবং প্রয়োগের সেটকে মেনে চলে?
কোনও ইন্টারফেসের পুরো বিন্দুটি কী নয় যে একাধিক শ্রেণি নিয়ম এবং প্রয়োগের সেটকে মেনে চলে?
উত্তর:
কঠোরভাবে বলতে, না তুমি, তাই না YAGNI প্রযোজ্য। এটি বলেছে, আপনি ইন্টারফেসটি তৈরি করতে ব্যয় করা সময়টি ন্যূনতম, বিশেষত যদি আপনার হাতে বেশিরভাগ কাজ করার একটি সহজ কোড জেনারেশন সরঞ্জাম থাকে। আপনার যদি ইন্টারফেসের প্রয়োজন হয় কিনা তা নিয়ে আপনি যদি অনিশ্চিত থাকেন তবে আমি বলতে চাই যে কোনও ইন্টারফেসের সংজ্ঞা সমর্থন করার পক্ষে দিক থেকে ভুল করা ভাল।
তদুপরি, এমনকি একটি একক শ্রেণীর জন্য ইন্টারফেস ব্যবহার করা আপনাকে ইউনিট পরীক্ষার জন্য আরও একটি মক প্রয়োগ প্রদান করবে, যা উত্পাদন হয় না। অব্নার শাহর-কাশনের উত্তর এই পয়েন্টে প্রসারিত হয়।
আমি উত্তর দিতে হবে যে আপনি একটি ইন্টারফেস না প্রয়োজন অথবা কিনা নেই না কত শ্রেণীর এটা বাস্তবায়ন করবে উপর নির্ভর করে। ইন্টারফেসগুলি আপনার অ্যাপ্লিকেশনটির একাধিক সাব সিস্টেমের মধ্যে চুক্তিগুলি সংজ্ঞায়নের জন্য একটি সরঞ্জাম ; সুতরাং আসলে কীভাবে গুরুত্বপূর্ণ তা হল আপনার অ্যাপ্লিকেশনটি কীভাবে সাবসিস্টিমে বিভক্ত হয়। এনপ্যাপুলেটেড সাবসিস্টেমগুলির ফ্রন্ট-এন্ড হিসাবে ইন্টারফেস থাকতে হবে, যতগুলি ক্লাসই তাদের বাস্তবায়ন করে।
এখানে থাম্বের একটি খুব কার্যকর নিয়ম:
Foo
ক্লাসটিকে সরাসরি ক্লাসে উল্লেখ করেন তবে আপনি প্রতিবার BarImpl
পরিবর্তন করার Foo
সময় নিজেকে দৃ change়ভাবে প্রতিশ্রুতি দিচ্ছেন BarImpl
। আপনি মূলত তাদেরকে কোডের একক হিসাবে আচরণ করছেন যা দুটি শ্রেণিতে বিভক্ত।Foo
উল্লেখ করেন তবে আপনি যখন পরিবর্তন করবেন তখন পরিবর্তন এড়াতে আপনি নিজেকে প্রতিশ্রুতিবদ্ধ করছেন । Bar
Foo
BarImpl
আপনি যদি আপনার অ্যাপ্লিকেশনটির মূল পয়েন্টগুলিতে ইন্টারফেসগুলি সংজ্ঞায়িত করেন, তবে তাদের যে পদ্ধতিগুলি সমর্থন করা উচিত এবং কোনটি না করা উচিত সে সম্পর্কে আপনি যত্ন সহকারে চিন্তাভাবনা করেন এবং কোনও প্রয়োগকরণ কীভাবে আচরণ করা উচিত (এবং কীভাবে নয়) তা বর্ণনা করার জন্য আপনি ইন্টারফেসগুলিতে স্পষ্ট মন্তব্য করেছিলেন, আপনার আবেদন বুঝতে কারণ এই মন্তব্য ইন্টারফেসগুলি কেমন প্রদান করবে অনেক সহজ হবে স্পেসিফিকেশন অ্যাপ্লিকেশন-একটি কিভাবে এটা সে সম্পর্কে বর্ণনার উদ্দেশ্যে আচরণ করে। এটি কোডটি পড়া খুব সহজ করে তোলে ("এই কোডটি হ্যাকটি কী করার কথা বলে তা জিজ্ঞাসা করার পরিবর্তে" আপনি জিজ্ঞাসা করতে পারেন "এই কোডটি কী করার কথা বলে তা কী করে")।
এগুলি (বা আসলে এটির কারণে) এর পাশাপাশি ইন্টারফেসগুলি পৃথক সংকলন প্রচার করে। যেহেতু ইন্টারফেসগুলি সংকলনের জন্য তুচ্ছ এবং তাদের প্রয়োগের তুলনায় কম নির্ভরতা থাকে, এর অর্থ হ'ল আপনি যদি Foo
ইন্টারফেসটি ব্যবহারের জন্য ক্লাস লিখেন তবে আপনি Bar
সাধারণত পুনরায় সংকলনের BarImpl
প্রয়োজন ছাড়াই পুনরায় সংযোগ করতে পারেন Foo
। বড় অ্যাপ্লিকেশনগুলিতে এটি অনেক সময় বাঁচাতে পারে।
Foo
ইন্টারফেসের উপর নির্ভর করে Bar
তবে BarImpl
পুনরায় কম্পাইল না করেই সংশোধন করা যেতে পারে Foo
। ৪. সরকারী / বেসরকারী অফারগুলির তুলনায় সূক্ষ্ম দানযুক্ত অ্যাক্সেস নিয়ন্ত্রণ (একই ক্লাসটি দুটি ক্লায়েন্টকে বিভিন্ন ইন্টারফেসের মাধ্যমে প্রকাশ করা)।
If you make class Foo refer directly to class BarImpl, you're strongly committing yourself to change Foo every time you change BarImpl
পরিবর্তন করার সময়, ফুগুলি ব্যবহার করে interface Bar
কী কী পরিবর্তন এড়ানো যেতে পারে ? যেহেতু একটি পদ্ধতির স্বাক্ষর এবং কার্যকারিতা যতক্ষণ না বারিম্পলটিতে পরিবর্তিত হয়, ফু এর ইন্টারফেস ছাড়াও কোনও পরিবর্তন প্রয়োজন হবে না (ইন্টারফেসের পুরো উদ্দেশ্য)। আমি সেই দৃশ্যের কথা বলছি যেখানে কেবল একটি ক্লাস অর্থাত্ BarImpl
বার প্রয়োগ করে। একাধিক শ্রেণীর দৃশ্যের জন্য, আমি নির্ভরশীলতা ইনভার্সন নীতি এবং এটি ইন্টারফেসটি কীভাবে সহায়ক তা বুঝতে পারি understand
ইন্টারফেসগুলি কোনও আচরণকে সংজ্ঞায়িত করার জন্য মনোনীত করা হয়, অর্থাৎ ফাংশন / পদ্ধতির প্রোটোটাইপের একটি সেট। ইন্টারফেস প্রয়োগকারী ধরণগুলি সেই আচরণটি বাস্তবায়ন করবে, সুতরাং আপনি যখন এই জাতীয় ধরণের মোকাবেলা করেন তখন আপনি জানেন (আংশিক) এটির কী আচরণ রয়েছে।
ইন্টারফেসটি সংজ্ঞায়িত করার দরকার নেই যদি আপনি জানেন যে এটির দ্বারা নির্ধারিত আচরণটি কেবল একবার ব্যবহার করা হবে। KISS (এটি সহজ, বোকা রাখুন)
তত্ত্ব অনুসারে আপনার কেবল ইন্টারফেসের জন্য ইন্টারফেস থাকা উচিত নয়, ইন্নিস রিজসের উত্তর আরও জটিলতার দিকে ইঙ্গিত দেয়:
যখন আপনি ইউনিট পরীক্ষা লিখছেন এবং মক বা ফেকআইটেসির মতো মক ফ্রেমওয়ার্কগুলি ব্যবহার করুন (আমি যে দুটি সাম্প্রতিক ব্যবহার করেছি তার নামকরণ করতে), আপনি স্পষ্টভাবে ইন্টারফেসটি প্রয়োগ করে এমন একটি শ্রেণি তৈরি করছেন। কোড বা স্থির বিশ্লেষণটি দাবি করতে পারে যে কেবলমাত্র একটি বাস্তবায়ন রয়েছে, তবে বাস্তবে অভ্যন্তরীণ মক প্রয়োগ রয়েছে। আপনি যখনই বিদ্রূপ লেখা শুরু করবেন, আপনি দেখতে পাবেন যে ইন্টারফেসগুলি নিষ্কাশন করা অর্থপূর্ণ makes
তবে অপেক্ষা করুন, আরও কিছু আছে। আরও দৃশ্যাবলী রয়েছে যেখানে অন্তর্নিহিত ইন্টারফেস বাস্তবায়ন রয়েছে। .NET এর ডাব্লুসিএফ যোগাযোগ স্ট্যাক ব্যবহার করে উদাহরণস্বরূপ, একটি রিমোট সার্ভিসে একটি প্রক্সি তৈরি করে, যা আবার ইন্টারফেস প্রয়োগ করে।
একটি পরিষ্কার কোড পরিবেশে, আমি এখানে বাকি উত্তরগুলির সাথে একমত। তবে আপনার যে কোনও ফ্রেমওয়ার্ক, নিদর্শন বা নির্ভরতা যা ইন্টারফেসের ব্যবহার করতে পারে তাতে মনোযোগ দিন।
না, আপনার এগুলির দরকার নেই এবং আমি প্রতিটি শ্রেণীর রেফারেন্সের জন্য স্বয়ংক্রিয়ভাবে ইন্টারফেসগুলি তৈরি করার জন্য এটি একটি অ্যান্টি-প্যাটার্ন হিসাবে বিবেচনা করি।
প্রতিটি কিছুর জন্য Foo / FooImpl তৈরি করার জন্য একটি আসল ব্যয় আছে। আইডিই ইন্টারফেস / বাস্তবায়ন নিখরচায় তৈরি করতে পারে তবে আপনি যখন কোড নেভিগেট করছেন তখন আপনাকে foo.doSomething()
ইন্টারফেসের স্বাক্ষরে নিয়ে যাওয়ার ক্ষেত্রে F3 / F12 থেকে অতিরিক্ত জ্ঞানীয় বোঝা থাকবে এবং আপনি যে প্রকৃত বাস্তবায়ন চান তা নয়। এছাড়াও আপনার কাছে সমস্ত কিছুর পরিবর্তে দুটি ফাইলের নড়বড়ে।
সুতরাং আপনার যখন কেবল কোনও কিছুর জন্য প্রয়োজন হয় তখনই আপনার এটি করা উচিত।
এখন পাল্টা বক্তব্য:
নির্ভরতা ইনজেকশন ফ্রেমওয়ার্কের জন্য আমার ইন্টারফেস দরকার
ফ্রেমওয়ার্কগুলি সমর্থন করার জন্য ইন্টারফেসগুলি উত্তরাধিকার। জাভাতে, ইন্টারফেসগুলি গতিশীল প্রক্সিগুলির জন্য প্রি-সিজিএলআইবি প্রয়োজন। আজ, আপনার সাধারণত এটির প্রয়োজন হয় না। এটি বিকাশকারী উত্পাদনশীলতার জন্য অগ্রগতি এবং একটি वरদান হিসাবে বিবেচিত যা আপনাকে এজেবি 3, স্প্রিং ইত্যাদিতে আর প্রয়োজন হয় না
ইউনিট পরীক্ষার জন্য আমার বিদ্রূপ দরকার
যদি আপনি নিজের বিদ্রূপ লিখে থাকেন এবং দুটি বাস্তব বাস্তবায়ন থাকে, তবে একটি ইন্টারফেস উপযুক্ত। আপনার কোডবেজে যদি একটি FooImpl এবং টেস্টফু উভয় থাকে তবে আমরা সম্ভবত প্রথম দিকে এই আলোচনা করব না।
তবে আপনি যদি মক, ইজিমক বা মকিতো এর মতো একটি উপহাসের কাঠামো ব্যবহার করছেন তবে আপনি ক্লাসগুলি উপহাস করতে পারেন এবং আপনার ইন্টারফেসের প্রয়োজন হবে না। এটি foo.method = mockImplementation
একটি গতিময় ভাষায় সেট করার অনুরূপ যেখানে পদ্ধতিগুলি নির্ধারিত হতে পারে।
নির্ভরতা বিপরীতমুখী মূলনীতি (ডিআইপি) অনুসরণ করতে আমাদের ইন্টারফেসের প্রয়োজন
ডিআইপি বলছে আপনি চুক্তি (ইন্টারফেস) এবং বাস্তবায়নের উপর নির্ভর করে না। তবে একটি শ্রেণি ইতিমধ্যে একটি চুক্তি এবং বিমূর্ততা। এটি সর্বজনীন / ব্যক্তিগত কীওয়ার্ডগুলির জন্য। বিশ্ববিদ্যালয়ে ক্যানোনিকাল উদাহরণটি ম্যাট্রিক্স বা পলিনোমিয়াল বর্গের মতো কিছু ছিল - গ্রাহকরা ম্যাট্রিক্স তৈরি করতে, তাদের যুক্ত করতে ইত্যাদির জন্য একটি পাবলিক এপিআই রেখেছিলেন তবে ম্যাট্রিক্সটি স্পার বা ঘন আকারে প্রয়োগ করা হয় কিনা তা যত্ন নেওয়ার অনুমতি নেই। সেই পয়েন্টটি প্রমাণ করার জন্য কোনও ইমেট্রিক্স বা ম্যাট্রিক্সআইএমপিএল প্রয়োজন ছিল না।
এছাড়াও, ডিআইপি প্রায়শই প্রতিটি শ্রেণি / পদ্ধতি কল স্তরে কেবলমাত্র বড় মডিউল সীমানায় নয় over আপনি ডিআইপি-কে অতিরিক্ত প্রয়োগ করছেন এমন একটি চিহ্ন হ'ল লক-স্টেপে আপনার ইন্টারফেস এবং প্রয়োগের পরিবর্তন যেমন একের পরিবর্তে আপনাকে দুটি ফাইল স্পর্শ করতে হবে। যদি ডিআইপি যথাযথভাবে প্রয়োগ করা হয় তবে এর অর্থ হল আপনার ইন্টারফেসটি প্রায়শই পরিবর্তন করা উচিত নয়। এছাড়াও, অন্য চিহ্নটি হ'ল আপনার ইন্টারফেসটির কেবলমাত্র একটি প্রকৃত গ্রাহক রয়েছে (এর নিজস্ব প্রয়োগ)। আপনি বিভিন্ন অ্যাপ্লিকেশনগুলিতে গ্রাহকতার জন্য শ্রেণিবদ্ধ লাইব্রেরি তৈরি করে থাকলে ভিন্ন গল্প।
এটি মশকরা সম্পর্কে চাচা বব মার্টিনের বক্তব্যটির একটি ছদ্মরূপ - আপনার কেবলমাত্র প্রধান স্থাপত্য সীমানায় উপহাস করা উচিত। একটি ওয়েবঅ্যাপে এইচটিটিপি এবং ডিবি অ্যাক্সেস প্রধান সীমানা। এর মধ্যে থাকা সমস্ত শ্রেণি / পদ্ধতি কলগুলি নেই। ডিআইপি-তেও যায়।
আরো দেখুন:
new Mockup<YourClass>() {}
এবং এর নির্মাতারা সহ পুরো ক্লাসকে বিদ্রূপ করা হয়েছে, এটি কোনও ইন্টারফেস, অ্যাবস্ট্রাক্ট শ্রেণি বা কংক্রিট শ্রেণীর হোক না কেন। আপনি যদি এটি করতে চান তবে আপনি নির্মাণকারীর আচরণকে "ওভাররাইড" করতে পারেন। আমি মনে করি মকিতো বা পাওয়ারমক এ সমান উপায় আছে ways
দেখে মনে হচ্ছে বেড়ার উভয় পক্ষের উত্তরগুলি এখানে সংক্ষিপ্ত করা যেতে পারে:
ভাল ডিজাইন করুন, এবং ইন্টারফেসগুলি রাখুন যেখানে ইন্টারফেসের প্রয়োজন।
যেমন আমি ইয়ানির উত্তরের প্রতিক্রিয়ায় উল্লেখ করেছি , আমি মনে করি না যে আপনার ইন্টারফেসগুলি সম্পর্কে কখনও কঠোর এবং দ্রুত নিয়ম থাকতে পারে। বিধিটি সংজ্ঞা অনুসারে, নমনীয় হওয়া দরকার। ইন্টারফেসের ক্ষেত্রে আমার নিয়মটি হ'ল আপনি যে কোনও এপিআই তৈরি করছেন সেদিকেই কোনও ইন্টারফেস ব্যবহার করা উচিত। এবং দায়িত্বের এক ডোমেন থেকে অন্য সীমানা পেরিয়ে আপনি যে কোনও জায়গায় এপিআই তৈরি করতে হবে।
(ভয়াবহভাবে অবদানযুক্ত) উদাহরণের জন্য, ধরা যাক আপনি একটি Car
শ্রেণী তৈরি করছেন। আপনার ক্লাসে আপনার অবশ্যই একটি ইউআই স্তর প্রয়োজন। এই বিশেষ উদাহরণ, এটি একটি এর আকারে IginitionSwitch
, SteeringWheel
, GearShift
, GasPedal
, এবং BrakePedal
। যেহেতু এই গাড়িতে একটি রয়েছে AutomaticTransmission
, আপনার কোনও দরকার নেই ClutchPedal
। (এবং যেহেতু এটি একটি ভয়াবহ গাড়ি, কোনও এ / সি, রেডিও বা আসন নেই fact সত্য হিসাবে, মেঝে বোর্ডগুলিও নিখোঁজ রয়েছে - আপনাকে কেবল সেই স্টিয়ারিং হুইলে আটকাতে হবে এবং সেরাটির জন্য আশা করতে হবে!)
তাহলে এই শ্রেণীর কোনটির ইন্টারফেসের প্রয়োজন? আপনার নকশার উপর নির্ভর করে উত্তরটি তাদের সমস্ত হতে পারে বা তাদের মধ্যে কোনওটিই হতে পারে না।
আপনার মত একটি ইন্টারফেস থাকতে পারে:
Interface ICabin
Event IgnitionSwitchTurnedOn()
Event IgnitionSwitchTurnedOff()
Event BrakePedalPositionChanged(int percent)
Event GasPedalPositionChanged(int percent)
Event GearShiftGearChanged(int gearNum)
Event SteeringWheelTurned(float degree)
End Interface
এই মুহুর্তে, এই শ্রেণীর আচরণ আইসিবিন ইন্টারফেস / এপিআইয়ের অংশ হয়ে যায়। এই উদাহরণে ক্লাসগুলি (যদি কিছু থাকে তবে) কয়েকটি বৈশিষ্ট্য এবং দুটি বা দুটি ফাংশন সহ সম্ভবত সহজ। এবং আপনি আপনার নকশার সাথে যা স্পষ্টভাবে উল্লেখ করছেন তা হ'ল এই ক্লাসগুলি কেবলমাত্র আপনার আইসিবিনের যাবতীয় কংক্রিট বাস্তবায়নকে সমর্থন করার জন্য উপস্থিত রয়েছে এবং সেগুলি তাদের নিজেরাই বিদ্যমান থাকতে পারে না, বা তারা আইসিবিন প্রসঙ্গে বাইরে অর্থহীন।
এটি একই কারণে যে আপনি ব্যক্তিগত সদস্যদের ইউনিট-টেস্ট করেন না - এগুলি কেবল সর্বজনীন এপিআই সমর্থন করার জন্য বিদ্যমান , এবং এইভাবে তাদের আচরণটি এপিআই পরীক্ষার মাধ্যমে পরীক্ষা করা উচিত।
সুতরাং যদি আপনার শ্রেণিটি কেবলমাত্র অন্য শ্রেণিকে সমর্থন করার জন্য উপস্থিত থাকে এবং ধারণাগতভাবে আপনি এটিকে সত্যই নিজস্ব ডোমেন না হিসাবে দেখেন তবে ইন্টারফেসটি বাদ দেওয়া ভাল। তবে যদি আপনার শ্রেণিটি যথেষ্ট গুরুত্বপূর্ণ যে আপনি নিজের ডোমেইন পাওয়ার পক্ষে এটি যথেষ্ট বেড়ে ওঠার বিষয়টি বিবেচনা করেন, তবে এগিয়ে যান এবং একটি ইন্টারফেস দিন।
সম্পাদনা করুন:
প্রায়শই (এই উত্তর সহ) আপনি 'ডোমেন', 'নির্ভরতা' (ঘন ঘন 'ইনজেকশন' যুক্ত) এর মতো জিনিসগুলি পড়বেন যা আপনি প্রোগ্রাম শুরু করার সময় আপনার কাছে কোনও অর্থ নয় (তারা নিশ্চিত না যে আমার কাছে কিছু বোঝানো)। ডোমেনের জন্য, এর অর্থ হ'ল ঠিক কী মনে হচ্ছে:
যে অঞ্চলটির উপর কর্তৃত্ব বা কর্তৃত্ব প্রয়োগ করা হয়; একটি সার্বভৌম বা কমনওয়েলথ বা এর মতো সম্পত্তি। রূপকভাবে ব্যবহার করা হয়। [ওয়ার্ডনেট ইন্দ্রিয় 2] [1913 ওয়েবস্টার]
আমার উদাহরণের শর্তাবলী - আসুন বিবেচনা করুন IgnitionSwitch
। একটি মিটস্পেস গাড়িতে, ইগনিশন সুইচ এর জন্য দায়ী:
এই বৈশিষ্ট্যগুলি ডোমেনটি তৈরি করে IgnitionSwitch
বা অন্য কথায়, এটি কী জানে এবং এর জন্য দায়ী।
এর IgnitionSwitch
জন্য দায়ী নয় GasPedal
। ইগনিশন স্যুইচ প্রতিটিভাবেই গ্যাসের প্যাডেল সম্পর্কে সম্পূর্ণ অজ্ঞ। তারা উভয় একে অপরের থেকে সম্পূর্ণ স্বাধীন পরিচালনা করে (যদিও একটি গাড়ি উভয় ছাড়াই মোটামুটি মূল্যহীন!)।
আমি যেমনটি বলেছি, এটি আপনার নকশার উপর নির্ভর করে। আপনি IgnitionSwitch
এমন দুটি ডিজাইন করতে পারেন যার দুটি মান রয়েছে: চালু ( True
) এবং অফ ( False
)। অথবা আপনি এটির জন্য সরবরাহিত কী এবং অন্যান্য ক্রিয়াকলাপের হোস্টকে অনুমোদনের জন্য এটি ডিজাইন করতে পারেন। এটি বিকাশের লাইনগুলি কোথায় আঁকতে হবে - এবং সত্যই বেশিরভাগ সময় এটি সম্পূর্ণ আপেক্ষিকভাবে বিকাশকারী হওয়ার শক্ত অংশ। বালির সেই লাইনগুলি গুরুত্বপূর্ণ - যদিও এটিই আপনার এপিআই, এবং এইভাবে যেখানে আপনার ইন্টারফেসগুলি হওয়া উচিত।
এমএসডিএন থেকে :
ইন্টারফেসগুলি এমন পরিস্থিতিতে উপযুক্ত যা আপনার অ্যাপ্লিকেশনগুলিতে নির্দিষ্ট কার্যকারিতা সরবরাহ করার জন্য অনেকগুলি সম্ভবত সম্পর্কিত নয় এমন অবজেক্টের ধরণের প্রয়োজন।
ইন্টারফেসগুলি বেস ক্লাসগুলির চেয়ে আরও নমনীয় কারণ আপনি একক বাস্তবায়ন সংজ্ঞায়িত করতে পারেন যা একাধিক ইন্টারফেস প্রয়োগ করতে পারে।
ইন্টারফেসগুলি এমন পরিস্থিতিতে উন্নত হয় যেখানে আপনাকে বেস বর্গ থেকে বাস্তবায়নের উত্তরাধিকারের প্রয়োজন হয় না।
আপনি শ্রেণীর উত্তরাধিকার ব্যবহার করতে পারবেন না সে ক্ষেত্রে ইন্টারফেসগুলি কার্যকর। উদাহরণস্বরূপ, কাঠামোগুলি ক্লাস থেকে উত্তরাধিকারী হতে পারে না তবে তারা ইন্টারফেস প্রয়োগ করতে পারে।
সাধারণত একটি একক শ্রেণীর ক্ষেত্রে, কোনও ইন্টারফেস বাস্তবায়নের প্রয়োজন হবে না, তবে আপনার প্রকল্পের ভবিষ্যতের কথা বিবেচনা করে ক্লাসগুলির প্রয়োজনীয় আচরণকে আনুষ্ঠানিকভাবে সংজ্ঞায়িত করতে এটি কার্যকর হতে পারে।
প্রশ্নের উত্তর দিতে: এর চেয়ে আরও অনেক কিছু আছে।
একটি ইন্টারফেসের একটি গুরুত্বপূর্ণ বিষয় হ'ল অভিপ্রায়।
একটি ইন্টারফেস হ'ল "একটি বিমূর্ত প্রকার যা কোনও ডেটা ধারণ করে না, তবে আচরণগুলি প্রকাশ করে" - ইন্টারফেস (কম্পিউটিং) সুতরাং যদি এটি কোনও আচরণ, বা আচরণগুলির একটি সেট, যা শ্রেণি সমর্থন করে, তবে ইন্টারফেসের চেয়ে সম্ভবত সঠিক প্যাটার্নটি হয়। তবে, যদি আচরণ (গুলি) শ্রেণীর দ্বারা সংশ্লেষিত ধারণার অন্তর্নিহিত হয় তবে আপনি সম্ভবত কোনও ইন্টারফেস চান না।
প্রথমে জিজ্ঞাসা করা প্রশ্নটি হ'ল আপনি প্রতিনিধিত্ব করার চেষ্টা করছেন এমন জিনিস বা প্রক্রিয়াটির প্রকৃতি কী। তারপরে একটি নির্দিষ্ট উপায়ে সেই প্রকৃতি বাস্তবায়নের ব্যবহারিক কারণগুলি অনুসরণ করুন।
আপনি যেহেতু এই প্রশ্নটি জিজ্ঞাসা করেছেন, আমি মনে করি আপনি ইতিমধ্যে একাধিক বাস্তবায়ন গোপন করার ইন্টারফেসের আগ্রহ দেখেছেন। নির্ভরতা বিপরীত নীতি দ্বারা এটি প্রকাশ করা যেতে পারে।
তবে একটি ইন্টারফেস থাকা বা না হওয়া প্রয়োজনীয়তা এর বাস্তবায়নের সংখ্যার উপর নির্ভর করে না। একটি ইন্টারফেসের আসল ভূমিকাটি হ'ল এটি একটি চুক্তি সংজ্ঞায়িত করে যাতে কীভাবে পরিষেবা প্রয়োগ করা উচিত তার পরিবর্তে কী পরিষেবা সরবরাহ করা উচিত।
চুক্তিটি সংজ্ঞায়িত হয়ে গেলে, দু'জন বা তার বেশি দল স্বতন্ত্রভাবে কাজ করতে পারে। বলুন যে আপনি একটি মডিউল এ নিয়ে কাজ করছেন এবং এটি মডিউল বি নির্ভর করে, বিতে একটি ইন্টারফেস তৈরি করার বিষয়টি খ এর বাস্তবায়ন সম্পর্কে চিন্তা না করে আপনার কাজ চালিয়ে যেতে দেয় কারণ সমস্ত বিবরণ ইন্টারফেসের মাধ্যমে গোপন রয়েছে। সুতরাং, বিতরণ প্রোগ্রামিং সম্ভব হয়।
যদিও মডিউল বি এর ইন্টারফেসটির একটি মাত্র প্রয়োগ রয়েছে, তবে ইন্টারফেসটি এখনও প্রয়োজনীয়।
উপসংহারে, একটি ইন্টারফেস তার ব্যবহারকারীর কাছ থেকে প্রয়োগের বিবরণ গোপন করে। ইন্টারফেসে প্রোগ্রামিং আরও ডকুমেন্ট লিখতে সহায়তা করে কারণ চুক্তিটি সংজ্ঞায়িত করতে হবে, আরও মডুলার সফ্টওয়্যার লিখতে হবে, ইউনিট পরীক্ষাগুলি প্রচার করতে এবং বিকাশের গতি ত্বরান্বিত করতে হবে।
এখানে সমস্ত উত্তর খুব ভাল। প্রকৃতপক্ষে বেশিরভাগ সময় আপনার আলাদা ইন্টারফেস প্রয়োগ করার দরকার নেই । তবে এমন কেস রয়েছে যেখানে আপনি যেভাবেই এটি করতে চান want এখানে আমি এটি করি এমন কিছু ক্ষেত্রে রয়েছে:
ক্লাসটি অন্য একটি ইন্টারফেস প্রয়োগ করে যা আমি
প্রায়শই অ্যাডাপ্টারের ক্লাসের সাথে তৃতীয় পক্ষের কোডটি ব্রড করতে চাই না pp
interface NameChangeListener { // Implemented by a lot of people
void nameChanged(String name);
}
interface NameChangeCount { // Only implemented by my class
int getCount();
}
class NameChangeCounter implements NameChangeListener, NameChangeCount {
...
}
class SomeUserInterface {
private NameChangeCount currentCount; // Will never know that you can change the counter
}
শ্রেণি একটি নির্দিষ্ট প্রযুক্তি ব্যবহার
করে যা বাহ্যিক লাইব্রেরিগুলির সাথে ইন্টারঅ্যাক্ট করার সময় বেশিরভাগ ক্ষেত্রে ট্রুপ ফাঁস করা উচিত নয় । এমনকি যদি কেবলমাত্র একটি বাস্তবায়ন হয় তবে আমি বাইরের লাইব্রেরির সাথে অপ্রয়োজনীয় সংযুক্তির পরিচয় না দেওয়ার বিষয়টি নিশ্চিত করতে একটি ইন্টারফেস ব্যবহার করি।
interface SomeRepository { // Guarantee that the external library details won't leak trough
...
}
class OracleSomeRepository implements SomeRepository {
... // Oracle prefix allow us to quickly know what is going on in this class
}
ক্রস লেয়ার যোগাযোগ
এমনকি যদি কোনও একটি ইউআই ক্লাস কখনও ডোমেন শ্রেণীর মধ্যে একটি প্রয়োগ করে তবে এটি সেই স্তরগুলির মধ্যে আরও ভাল বিভাজনের অনুমতি দেয় এবং সর্বাগ্রে এটি চক্রীয় নির্ভরতা এড়ায়।
package project.domain;
interface UserRequestSource {
public UserRequest getLastRequest();
}
class UserBehaviorAnalyser {
private UserRequestSource requestSource;
}
package project.ui;
class OrderCompleteDialog extends SomeUIClass implements project.domain.UserRequestSource {
// UI concern, no need for my domain object to know about this method.
public void displayLabelInErrorMode();
// They most certainly need to know about *that* though
public UserRequest getLastRequest();
}
বেশিরভাগ অবজেক্টের জন্য কেবলমাত্র পদ্ধতির একটি উপসেট পাওয়া উচিত
বেশিরভাগ ক্ষেত্রে আমার যখন কংক্রিটের ক্লাসে কিছু কনফিগারেশন পদ্ধতি থাকে
interface Sender {
void sendMessage(Message message)
}
class PacketSender implements Sender {
void sendMessage(Message message);
void setPacketSize(int sizeInByte);
}
class Throttler { // This class need to have full access to the object
private PacketSender sender;
public useLowNetworkUsageMode() {
sender.setPacketSize(LOW_PACKET_SIZE);
sender.sendMessage(new NotifyLowNetworkUsageMessage());
... // Other details
}
}
class MailOrder { // Not this one though
private Sender sender;
}
সুতরাং শেষ পর্যন্ত আমি একই কারণে ইন্টারফেস ব্যবহার করি কারণ আমি ব্যক্তিগত ক্ষেত্রটি ব্যবহার করি: অন্য বস্তুর কাছে তাদের প্রবেশ করা উচিত নয় এমন স্টাফের অ্যাক্সেস থাকা উচিত নয়। আমার যদি এরকম কেস থাকে তবে আমি কেবল একটি শ্রেণি প্রয়োগ করলেও একটি ইন্টারফেস চালু করি।
ইন্টারফেসগুলি সত্যই গুরুত্বপূর্ণ তবে আপনার যে সংখ্যা রয়েছে তা নিয়ন্ত্রণ করার চেষ্টা করুন।
'কাটা-আপ স্প্যাগেটি' কোড দিয়ে শেষ করা সহজ প্রায় প্রতিটি কিছুর জন্য ইন্টারফেস তৈরির পথে নেমে যাওয়ার পরে। আমি আয়েন্দে রাহিয়েনের বৃহত্তর জ্ঞানকে পিছনে ফেলেছি যিনি এই বিষয়টিতে খুব জ্ঞানী শব্দ পোস্ট করেছেন:
http://ayende.com/blog/153889/limit-your-abstractions-analyzing-a-ddd-application
এটি তাঁর পুরো সিরিজের প্রথম পোস্ট তাই পড়তে থাকুন!
এই ক্ষেত্রে আপনি এখনও একটি ইন্টারফেস প্রবর্তন করতে চাইতে পারেন এমন একটি কারণ হ'ল নির্ভরতা বিপরীতমুখী নীতি অনুসরণ করা । অর্থাৎ, ক্লাসটি ব্যবহার করে এমন মডিউলটি কোনও কংক্রিটের প্রয়োগের উপর নির্ভর করে এর বিমূর্তকরণ (অর্থাৎ ইন্টারফেস) এর উপর নির্ভর করবে। এটি নিম্ন-স্তরের উপাদানগুলি থেকে উচ্চ-স্তরের উপাদানগুলি ডিকুপল করে।
কিছু করার আসল কারণ নেই। ইন্টারফেসগুলি আপনাকে সাহায্য করার জন্য এবং আউটপুট প্রোগ্রামকে নয়। এমনকি যদি ইন্টারফেসটি দশ লক্ষ শ্রেণীর দ্বারা প্রয়োগ করা হয় তবে এমন কোনও নিয়ম নেই যা বলে যে আপনাকে একটি তৈরি করতে হবে। আপনি একটি তৈরি করেন যাতে আপনি বা আপনার কোড ব্যবহারকারী অন্য কেউ যখন কোনও কিছু পরিবর্তন করতে চান তখন এটি সমস্ত বাস্তবায়নে প্রবেশ করে। একটি ইন্টারফেস তৈরি করা আপনাকে ভবিষ্যতের সমস্ত ক্ষেত্রে সহায়তা করবে যেখানে আপনি এটি প্রয়োগ করে এমন অন্য শ্রেণি তৈরি করতে চান।
কোনও শ্রেণীর জন্য ইন্টারফেসটি সংজ্ঞায়িত করার প্রয়োজন সর্বদা নেই।
মান অবজেক্টের মতো সাধারণ বস্তুর একাধিক বাস্তবায়ন হয় না। তাদেরও উপহাস করার দরকার নেই। বাস্তবায়নটি তার নিজের দ্বারা পরীক্ষা করা যেতে পারে এবং যখন অন্যান্য শ্রেণিগুলি তাদের উপর নির্ভর করে পরীক্ষা করা হয়, আসল মান বস্তুটি ব্যবহার করা যেতে পারে।
মনে রাখবেন একটি ইন্টারফেস তৈরির জন্য একটি ব্যয় হয়। এটি বাস্তবায়নের পাশাপাশি আপডেট করা দরকার, এটির জন্য অতিরিক্ত ফাইল দরকার এবং কিছু আইডিইর ইন্টারফেস নয়, বাস্তবায়নে জুম করতে সমস্যা হবে।
সুতরাং আমি কেবলমাত্র উচ্চ স্তরের শ্রেণির জন্য ইন্টারফেসগুলি সংজ্ঞায়িত করব, যেখানে আপনি বাস্তবায়ন থেকে বিমূর্ততা চান।
নোট করুন যে কোনও শ্রেণীর সাথে আপনি বিনা জন্য একটি ইন্টারফেস পাবেন। বাস্তবায়ন ছাড়াও, একটি শ্রেণি পাবলিক পদ্ধতির সেট থেকে একটি ইন্টারফেসকে সংজ্ঞায়িত করে। এই ইন্টারফেসটি সমস্ত উত্পন্ন ক্লাস দ্বারা প্রয়োগ করা হয়। এটি কঠোরভাবে কোনও ইন্টারফেস বলছে না, তবে এটি একইভাবে ব্যবহার করা যেতে পারে। সুতরাং আমি মনে করি না যে কোনও ইন্টারফেসটি পুনরায় তৈরি করা প্রয়োজন যা শ্রেণীর নামে ইতিমধ্যে বিদ্যমান।