ইন্টারফেস বনাম বেস শ্রেণি


767

আমার কখন একটি ইন্টারফেস ব্যবহার করা উচিত এবং কখন আমার একটি বেস ক্লাস ব্যবহার করা উচিত?

আমি যদি পদ্ধতিগুলির ভিত্তি বাস্তবায়নটি সংজ্ঞায়িত করতে না চাই তবে কি সর্বদা ইন্টারফেস হওয়া উচিত?

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


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

1
এই প্রশ্নটি ইন্টারফেসের ধারণাটি বুঝতে সহায়তা করতে পারে। stackoverflow.com/q/8531292/1055241
gprathour

আমি শুধু কৌতূহলী। আমি পূরণ মাধ্যমে C # এর CLR উদ্ধৃতাংশ করুন: I tend to prefer using the interface technique over the base type technique because the base type technique doesn’t allow the developer to choose the base type that works best in a particular situation.। সংক্ষিপ্তসার বলতে কী বোঝায় তা আমি বুঝতে পারি না। আমরা কয়েকটি বেস প্রকার তৈরি করতে পারি এবং সেগুলির যে কোনওর জন্য একটি উদ্ভূত প্রকার তৈরি করতে পারি, সুতরাং বিকাশকারী একটি বেস প্রকারটি চয়ন করতে পারেন। কেউ ব্যাখ্যা করতে পারেন, দয়া করে, আমি কী মিস করছি? আমি বিশ্বাস করি এটি এই প্রশ্নের একটি অংশ হতে পারে। বা নির্দিষ্ট অংশটি সম্পর্কে আমার অন্য একটি পোস্ট করা উচিত?
qqqqqqq

উত্তর:


501

আসুন আপনার কুকুর এবং একটি বিড়াল শ্রেণীর উদাহরণটি ধরুন এবং আসুন সি # ব্যবহার করে চিত্রিত করুন:

কুকুর এবং একটি বিড়াল উভয়ই প্রাণী, বিশেষত, চতুর্ভুজ স্তন্যপায়ী প্রাণীরা (প্রাণীগুলি খুব সাধারণ আকারে থাকে)। আসুন ধরে নেওয়া যাক আপনার উভয়ের জন্য একটি বিমূর্ত ক্লাস স্তন্যপায়ী:

public abstract class Mammal

এই বেস শ্রেণিতে সম্ভবত ডিফল্ট পদ্ধতি থাকবে যেমন:

  • ভোজন
  • সঙ্গী

এগুলির সবই এমন আচরণ যা উভয় প্রজাতির মধ্যেই কমবেশি একই বাস্তবায়ন রয়েছে। এটি নির্ধারণ করতে আপনার কাছে রয়েছে:

public class Dog : Mammal
public class Cat : Mammal

এখন ধরা যাক অন্য স্তন্যপায়ী প্রাণীরা আছে, যা আমরা সাধারণত একটি চিড়িয়াখানায় দেখতে পাই:

public class Giraffe : Mammal
public class Rhinoceros : Mammal
public class Hippopotamus : Mammal

এটি এখনও কার্যকর হবে কারণ কার্যকারিতার মূল অংশে Feed()এবং Mate()এখনও একই থাকবে।

তবে জিরাফ, গণ্ডার এবং হিপ্পস হ'ল এমন প্রাণী নয় যা আপনি পোষা প্রাণীটিকে তৈরি করতে পারেন। সেখানেই একটি ইন্টারফেস কার্যকর হবে:

public interface IPettable
{
    IList<Trick> Tricks{get; set;}
    void Bathe();
    void Train(Trick t);
}

উপরের চুক্তির বাস্তবায়নটি একটি বিড়াল এবং কুকুরের মধ্যে এক হবে না; উত্তোলনের জন্য তাদের বাস্তবায়নগুলি একটি বিমূর্ত শ্রেণিতে স্থাপন করা একটি খারাপ ধারণা হবে।

আপনার কুকুর এবং বিড়াল সংজ্ঞা এখন দেখতে হবে:

public class Dog : Mammal, IPettable
public class Cat : Mammal, IPettable

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

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


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

18
ইন্টারফেসটি একটি চুক্তি। আপনি কেবলমাত্র পরিষেবাটির প্রয়োজনীয় চুক্তির অংশটি উন্মোচন করছেন। আপনার যদি একটি 'পেটিংজু' থাকে, তবে আপনি অবশ্যই ব্যবহারকারীকে 'ম্যাট'-ইঙ্গিতটি প্রকাশ করতে চান না!
অ্যান্টনি মাস্ট্রিয়ান

10
@ ডেভিড তোচে, যদিও আমি একটি ইন্টারফেস কী এবং তার বোঝার জন্য একটি বিমূর্ত শ্রেণি কী তা আরও ভালভাবে চিত্রিত করার জন্য এটি করেছি। একটি কুকুর এবং একটি বিড়াল অনমনীয় প্রয়োজন বলে মনে হয় না!
জন লিমাজাপ

2
এটি লক্ষ করা উচিত যে ব্যাখ্যা করা, জেআইটি-ইন পরিবেশ (বিশেষত জেভিএম), ভার্চুয়াল পদ্ধতি কলগুলি প্রেক্ষাপটের উপর নির্ভর করে ইন্টারফেস পদ্ধতি কলগুলির তুলনায় উল্লেখযোগ্যভাবে দ্রুত হয় faster আমি "প্রসঙ্গে" জোর দিয়েছি কারণ জেভিএম প্রায়শই ধীর পদ্ধতির অনুসন্ধানগুলি সরিয়ে নিতে পারে। (উদাহরণস্বরূপ, যদি ইন্টারফেস উত্তরাধিকারীদের একটি তালিকা একই বর্গের উদাহরণ হিসাবে থাকে ly এটি দুঃখের সাথে একটি বাচ্চাকে চিহ্নিত করে তোলে।
ফিলিপ গিন

14
এছাড়াও, একটি ইন্টারফেস একটি পোষ্য শৈলটিকে স্নান করার এবং কৌশল শেখানোর অনুমতি দেয়, তবে খাওয়ানো এবং সঙ্গম সমর্থন করা যায় না কারণ এটি শৈলটির জন্য হাস্যকর।
বাস্তু

146

ঠিক আছে, জোশ ব্লচ নিজেকে কার্যকর জাভা 2 ডি-তে বলেছেন :

বিমূর্ত ক্লাসের চেয়ে ইন্টারফেস পছন্দ করে

কয়েকটি মূল বিষয়:

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

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

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

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

তদুপরি, আপনি রফতানি করে এমন প্রতিটি ন্যান্ট্রাইভিয়াল ইন্টারফেসের সাথে যেতে একটি বিমূর্ত কঙ্কাল বাস্তবায়ন ক্লাস সরবরাহ করে আপনি ইন্টারফেস এবং বিমূর্ত শ্রেণির গুণাবলী একত্রিত করতে পারেন।

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

পিএস .: বইটি কিনুন। এটি অনেক বেশি বিস্তারিত।


71
যখনই কোনও ইন্টারফেসে পরিবর্তন আনার প্রয়োজন হয়, তা করার অ-ব্রেকিং উপায়টি হল একটি নতুন ইন্টারফেস তৈরি করা যা পুরানোটির থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। এটি বিদ্যমান বাস্তবায়নগুলি সংরক্ষণ করে এবং নতুনটিতে আপনি যা চান তা করতে দেয়।
স্কট লরেন্স 20

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

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

118

ইন্টারফেস এবং বেস ক্লাস দুটি ভিন্ন সম্পর্কের প্রতিনিধিত্ব করে।

উত্তরাধিকার (বেস ক্লাস) একটি "is-a" সম্পর্কের প্রতিনিধিত্ব করে। যেমন একটি কুকুর বা বিড়াল "is-a" পোষা প্রাণী। এই সম্পর্কটি সর্বদা শ্রেণীর (একক) উদ্দেশ্যে প্রতিনিধিত্ব করে ( "একক দায়িত্বের নীতিটির সাথে মিলিত ) "

অন্যদিকে ইন্টারফেসগুলি একটি শ্রেণীর অতিরিক্ত বৈশিষ্ট্য উপস্থাপন করে । আমি এটিকে একটি "" "সম্পর্ক, যেমন" Fooডিসপোজেবল " বলে আছি , সুতরাং IDisposableসি # তে ইন্টারফেস।


10
সমস্ত উত্তরগুলির মধ্যে, এইটি কোনও স্বচ্ছতা ছাড়াই ব্রিভটির সেরা মিশ্রণ দেয়
ম্যাট উইলকো

কেউ যখন একবার আমাকে "ইন্টারফেস" ব্যবহার করার জন্য বলেছিলেন যখন "হেস-এ" সম্পর্ক রয়েছে। আমি যদিও নিশ্চিত যে এটি সর্বদা সত্য কিনা; আমার ল্যাপটপের একটি স্ক্রিন রয়েছে, তাই ল্যাপটপের আইস্ক্রিন প্রয়োগ করা উচিত, না কোনও স্ক্রিন সম্পত্তি থাকতে হবে? পরেরটি আমার কাছে আরও স্বাভাবিক মনে হয়।
বেরেন্ড

1
@ মজার মজার বিষয় যে আপনি লিখেছেন যে পর্দা ইন্টারফেসের মাধ্যমে প্রয়োগ করা হয়েছে - ভিজিএ, এইচডিএমআই ইত্যাদি
কনস্টান্টিন

এটি ওওপি হওয়ার কারণে, বাস্তব জীবনের পরিস্থিতি অনুসরণ করতে আমাদের আমাদের কল্পনা প্রসার করতে হবে। এটি সর্বদা প্রযোজ্য নয়।
ক্রিসমগ্রাম

110

আধুনিক শৈলী হ'ল আইপেট এবং পেটবেস সংজ্ঞায়িত করা ।

ইন্টারফেসের সুবিধাটি হ'ল অন্যান্য কোড অন্য এক্সিকিউটেবল কোডের সাথে কোনও সম্পর্ক ছাড়াই এটি ব্যবহার করতে পারে। সম্পূর্ণ "পরিষ্কার"। এছাড়াও ইন্টারফেস মিশ্রিত করা যেতে পারে।

তবে বেস ক্লাসগুলি সাধারণ বাস্তবায়ন এবং সাধারণ উপযোগের জন্য কার্যকর। সুতরাং সময় এবং কোড সাশ্রয় করার জন্য একটি বিমূর্ত বেস ক্লাস সরবরাহ করুন।


আপনার পিষ্টক আছে এবং এটি খাও!
ড্যারেন কোপ

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

27
এখানে "আধুনিক" কিছুই নেই। একই এপিআই সহ বেস ক্লাস এবং ইন্টারফেস কেবল অনর্থক। আপনি কিছু ক্ষেত্রে এই পদ্ধতির ব্যবহার করতে পারেন তবে আপনার সাধারণীকরণ করা উচিত নয়!
smentek

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

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

63

ইন্টারফেস

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

বেস ক্লাস

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

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

59

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

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


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

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

3
এটি কি কেবল আমি, বা বেশিরভাগ "সাধারণ কর্মী" শ্রেণি একটি সাধারণ বাস্তবায়ন ভাগ করে দেয়? সেই প্রসঙ্গে এটি আপনার ইন্টারফেসের পক্ষে নেওয়ার সাধারণ নিয়মের বিরুদ্ধে যায়। আমি আপনার জেনারালাইজেশনটিকে 2 জেনারালাইজেশনে পুনরায় ফিরিয়ে আনব: যে সাধারণ ক্লাসগুলিতে খুব কম বা যুক্তি থাকে না তাদের একটি ইন্টারফেস প্রয়োগ করা উচিত। যেসব সাধারণ ক্লাসগুলির "শালীন" পরিমাণ যুক্তিযুক্ত রয়েছে তাদের একটি বেস ক্লাস থেকে নেওয়া উচিত (যেহেতু সম্ভবত তারা কার্যকারিতা ভাগ করে নেবে)।
goku_da_master

@ কিলহোফার "ইন্টারফেসগুলি সীমানা জুড়ে সর্বাধিক পরিমাণে নমনীয়তা এবং প্রকারের বহনযোগ্যতাকে মঞ্জুরি দেয়" দয়া করে এই বিবৃতিটি বিস্তারিতভাবে বর্ণনা করুন।
জাভা

49

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

ক্রিজিসটফ কোয়ালিনা ৮১ পৃষ্ঠায় বলেছেন:

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

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


19

জুয়ান,

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

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

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

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

সুতরাং আপনি যদি আমার মতো মনে করেন তবে আপনি অবশ্যই বলবেন যে বিড়াল এবং কুকুর আইপেটেবল। এটি একটি বৈশিষ্ট্য যা তাদের উভয়ের সাথে মেলে।

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

বলুন আমি সমস্ত অ্যানিম্যাল ক্লাস সংগ্রহ করতে এবং সেগুলি আমার সিন্দুকের পাত্রে রেখে দিতে চাই।

বা তাদের কি স্তন্যপায়ী হতে হবে? সম্ভবত আমাদের কোনও ধরণের ক্রস অ্যানিম্যাল মিল্কিং কারখানা দরকার?

এমনকি তাদের কি আদৌ একসাথে যুক্ত হওয়ার দরকার আছে? তারা উভয়ই আইপিটেটেবল কিনা তা কেবল জানা কি যথেষ্ট?

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

আপনি এক পর্যায়ে এটিও পেতে পারেন যে সমস্ত বিড়াল আইপেটেবল নয় (সেই চুলবিহীন একের মতো)। এখন আপনি সেই ইন্টারফেসটি সমস্ত ডেরাইভেটিভ ক্লাসে ফিট করতে পারেন যেগুলি উপযুক্ত that আপনি দেখতে পাবেন যে হঠাৎ বিড়ালগুলির সবগুলি আর পেটবেল থেকে উত্পন্ন নয় a


18

এখানে ইন্টারফেস এবং বেস শ্রেণীর প্রাথমিক এবং সাধারণ নির্ধারণ:

  • বেস শ্রেণি = বস্তুর উত্তরাধিকার।
  • ইন্টারফেস = কার্যকরী উত্তরাধিকার।

চিয়ার্স


12

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

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

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

আপনি যদি এটি করেন তবে আপনি খুঁজে পাবেন যে আপনার কোডটি অনেক বেশি নমনীয় এবং আপনার বেশিরভাগ সরল অবজেক্ট খুব বেসিক সিস্টেম-ব্যাপী আচরণের সাথে ডিল করে।

আমি একাধিক-উত্তরাধিকারী ভাষায়ও এই প্যাটার্নটি সুপারিশ করি।


12

জাভা ওয়ার্ল্ডের এই নিবন্ধে এটি ভালভাবে ব্যাখ্যা করা হয়েছে

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

এটি অস্বাভাবিক নয় যে আমার কাছে এক বা একাধিক ইন্টারফেস প্রয়োগকারী একটি ক্লাস থাকবে।

বিমূর্ত ক্লাসগুলি আমি অন্য কোনও কিছুর ভিত্তি হিসাবে ব্যবহার করি।

নীচে উপরে বর্ণিত জাভাওয়ার্ড.কম. নিবন্ধ, লেখক টনি সিনটেস, 04/20/01


ইন্টারফেস বনাম বিমূর্ত শ্রেণি

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

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

অনেক বিকাশকারী ভুলে যান যে একটি ক্লাস যে একটি বিমূর্ত পদ্ধতি সংজ্ঞায়িত করে সেই পদ্ধতিটিকেও কল করতে পারে। পরিকল্পিত উত্তরাধিকারের শ্রেণিবিন্যাস তৈরি করার জন্য অ্যাবস্ট্রাক্ট ক্লাসগুলি একটি দুর্দান্ত উপায়। শ্রেণি শ্রেণিবিন্যাসের ননলিফ ক্লাসগুলির জন্যও তারা ভাল পছন্দ।

ক্লাস বনাম ইন্টারফেস

কেউ কেউ বলেন যে আপনাকে ইন্টারফেসের ক্ষেত্রে সমস্ত শ্রেণির সংজ্ঞা দেওয়া উচিত, তবে আমি মনে করি সুপারিশটি কিছুটা চরম বলে মনে হচ্ছে। আমি যখন ইন্টারফেসগুলি ব্যবহার করি যখন দেখি আমার ডিজাইনের কিছু ঘন ঘন পরিবর্তিত হবে।

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

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

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


2
+1 টি। "ধরণের পরিচয়ের জন্য উত্তরাধিকারের উপর নির্ভর করা বিপজ্জনক; এটি আপনাকে একটি নির্দিষ্ট উত্তরাধিকারের শ্রেণিবিন্যাসে লক করে।" এই বাক্যটি ইন্টারফেস পছন্দ করার জন্য আমার কারণগুলি পুরোপুরি বর্ণনা করে।
ইঞ্জিনিয়ার

এবং এর বাইরেও, আপনার ইন্টারফেসের প্রতিটি পদ্ধতির পিছনে প্রসারিত করার পরিবর্তে রচনাটি রচনা করুন।
ইঞ্জিনিয়ার

10

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


10

আমার কাছে থাম্বের মোটামুটি নিয়ম আছে

কার্যকারিতা: সমস্ত অংশে পৃথক হওয়ার সম্ভাবনা রয়েছে: ইন্টারফেস।

ডেটা এবং কার্যকারিতা, অংশগুলি বেশিরভাগ ক্ষেত্রে একই, অংশগুলি পৃথক: বিমূর্ত শ্রেণি class

ডেটা এবং কার্যকারিতা, আসলে কাজ করছে, কেবলমাত্র সামান্য পরিবর্তন সহ প্রসারিত হয়: সাধারণ (কংক্রিট) শ্রেণি

ডেটা এবং কার্যকারিতা, কোনও পরিবর্তন পরিকল্পনা করা হয়নি: চূড়ান্ত সংশোধক সহ সাধারণ (কংক্রিট) শ্রেণি।

ডেটা এবং সম্ভবত কার্যকারিতা: কেবল পঠনযোগ্য: এনুম সদস্যগণ।

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


7

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

বিমূর্ত ক্লাস শর্টকাট হয়। পেটবেসের সমস্ত ডেরিভেটিভগুলি এমন কিছু রয়েছে যা আপনি একবার কোড করতে পারেন এবং এর সাথে সম্পন্ন করতে পারেন? যদি হ্যাঁ, তবে এটি বিমূর্ত শ্রেণির জন্য সময় time

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

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

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


7

সূত্র : http://jasonroell.com/2014/12/09/interfaces-vs-abstract-classes- কি- শোল্ড- আপনি- ইউস /

সি # একটি দুর্দান্ত ভাষা যা গত 14 বছরে পরিপক্ক এবং বিকশিত হয়েছে। এটি আমাদের বিকাশকারীদের পক্ষে দুর্দান্ত কারণ একটি পরিপক্ক ভাষা আমাদের ভাষার বৈশিষ্ট্যগুলির আধিক্য সরবরাহ করে।

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

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

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

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

public abstract class Dog
{
      public virtual void Bark()
      {
        Console.WriteLine("Base Class implementation of Bark");
      }
}

public class GoldenRetriever : Dog
{
   // the Bark method is inherited from the Dog class
}

public class Poodle : Dog
{
  // here we are overriding the base functionality of Bark with our new implementation
  // specific to the Poodle class
  public override void Bark()
  {
     Console.WriteLine("Poodle's implementation of Bark");
  }
}

// Add a list of dogs to a collection and call the bark method.

void Main()
{
    var poodle = new Poodle();
    var goldenRetriever = new GoldenRetriever();

    var dogs = new List<Dog>();
    dogs.Add(poodle);
    dogs.Add(goldenRetriever);

    foreach (var dog in dogs)
    {
       dog.Bark();
    }
}

// Output will be:
// Poodle's implementation of Bark
// Base Class implementation of Bark

// 

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

তবে আমি নিশ্চিত যে আপনি এটি ইতিমধ্যে জানতেন।

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

এখন হেক মানে কি? ঠিক আছে, উদাহরণস্বরূপ: একটি মানুষ হাঁস নয় ... এবং হাঁস মানুষ নয়। বেশ স্পষ্ট. তবে, হাঁস এবং একজন মানুষের উভয়েরই সাঁতার কাটার "ক্ষমতা" রয়েছে (এই কারণে যে মানুষ তার সাঁতারের পাঠ 1 ম শ্রেণিতে পাস করেছে :)) এছাড়াও, যেহেতু হাঁস কোনও মানব বা তদ্বিপরীত নয়, তাই এটি "একটি" একটি "রিলেশনশীপ নয়, পরিবর্তে একটি" সক্ষম "সম্পর্ক এবং এটি চিত্রিত করার জন্য আমরা একটি ইন্টারফেস ব্যবহার করতে পারি:

// Create ISwimable interface
public interface ISwimable
{
      public void Swim();
}

// Have Human implement ISwimable Interface
public class Human : ISwimable

     public void Swim()
     {
        //Human's implementation of Swim
        Console.WriteLine("I'm a human swimming!");
     }

// Have Duck implement ISwimable interface
public class Duck: ISwimable
{
     public void Swim()
     {
          // Duck's implementation of Swim
          Console.WriteLine("Quack! Quack! I'm a Duck swimming!")
     }
}

//Now they can both be used in places where you just need an object that has the ability "to swim"

public void ShowHowYouSwim(ISwimable somethingThatCanSwim)
{
     somethingThatCanSwim.Swim();
}

public void Main()
{
      var human = new Human();
      var duck = new Duck();

      var listOfThingsThatCanSwim = new List<ISwimable>();

      listOfThingsThatCanSwim.Add(duck);
      listOfThingsThatCanSwim.Add(human);

      foreach (var something in listOfThingsThatCanSwim)
      {
           ShowHowYouSwim(something);
      }
}

 // So at runtime the correct implementation of something.Swim() will be called
 // Output:
 // Quack! Quack! I'm a Duck swimming!
 // I'm a human swimming!

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

আবারও এটি আপনার কোডটিকে ডিআরওয়াই রাখতে সহায়তা করে যাতে আপনাকে একাধিক পদ্ধতি লিখতে হবে না যা একই কোর ফাংশনটি (শো-হিউম্যানসুইমস (হিউম্যান), শোহউডাকসুইমস (হাঁস), ইত্যাদি) প্রবর্তনের জন্য বস্তুকে কল করছে calling

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

সারসংক্ষেপ:

সুতরাং আমার থাম্বের মূল নিয়মটি একটি বিমূর্ত শ্রেণিটি ব্যবহার করা হয় যখন আপনি শ্রেণি শ্রেণিবদ্ধের জন্য "ডিফল্ট" কার্যকারিতা বাস্তবায়ন করতে চান বা / এবং আপনি যে ক্লাসগুলি বা ধরণের ভাগ করে যাচ্ছেন "একটি" সম্পর্ক (প্রাক্তন পোডল ") একটি ”কুকুরের ধরণ)।

অন্যদিকে একটি ইন্টারফেস ব্যবহার করুন যখন আপনার "একটি" সম্পর্ক নেই তবে এমন কিছু রয়েছে যা কিছু করার বা কিছু করার "ক্ষমতা" ভাগ করে দেয় (প্রাক্তন হাঁস "মানুষ নয়" তবে হাঁস এবং মানুষের ভাগ সাঁতার "ক্ষমতা")।

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

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

আরেকটি টিপ হ'ল আপনি যদি কার্যকারিতার ক্ষুদ্র, সংক্ষিপ্ত বিট বিকাশ করছেন, ইন্টারফেস ব্যবহার করুন। যদি আপনি বড় ক্রিয়ামূলক ইউনিট ডিজাইন করেন তবে একটি বিমূর্ত শ্রেণি ব্যবহার করুন।

আশা করি কিছু লোকের জন্য এটি পরিষ্কার হয়ে যায়!

এছাড়াও যদি আপনি আরও ভাল উদাহরণগুলি ভাবতে পারেন বা কিছু উল্লেখ করতে চান তবে দয়া করে নীচের মন্তব্যে এটি করুন!


6

বেস ক্লাস ওভার ইন্টারফেসের ক্ষেত্রে সাবমাইন। নেট কোড কোডিং গাইডলাইনে ভালভাবে ব্যাখ্যা করা হয়েছিল:

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

ইন্টারফেস বাস্তবায়ন উত্তরাধিকার সমর্থন করে না, ক্লাসে প্রযোজ্য প্যাটার্নটি ইন্টারফেসের ক্ষেত্রে প্রযোজ্য না। একটি ইন্টারফেসে একটি পদ্ধতি যুক্ত করা একটি বেস শ্রেণিতে একটি বিমূর্ত পদ্ধতি যুক্ত করার সমতুল্য; ইন্টারফেস প্রয়োগ করে এমন কোনও শ্রেণি ভেঙে যাবে কারণ শ্রেণিটি নতুন পদ্ধতি প্রয়োগ করে না। ইন্টারফেসগুলি নিম্নলিখিত পরিস্থিতিতে উপযুক্ত:

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

আমার মনে হচ্ছে এই উত্তরটির আরও মনোযোগ দেওয়া উচিত। এটি এখানে অনেক উত্তরের শস্যের বিরুদ্ধে যায়। আমি বলব না যে আমি সম্পূর্ণরূপে একমত, তবে এখানে দুর্দান্ত পয়েন্ট রয়েছে।
kayleeFrye_onDeck

5

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


4

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

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

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

আচরণগুলি প্রথমে ইন্টারফেসের (শ্রেণীর ডিফল্ট ইন্টারফেস সহ) বরাদ্দ করা উচিত, এবং কেবলমাত্র যদি তারা (ক) বৃহত্তর শ্রেণীর উপ-বিভাগের বৃহত শ্রেণির মধ্যে সাধারণ হয় - তবে একই অর্থে যে বেস শ্রেণিতে উন্নীত হয় should "বিড়াল" এবং "ব্যক্তি" হ'ল "স্তন্যপায়ী" এর উপগ্রহ।

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

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


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

4

বিমূর্ত ক্লাসের চেয়ে ইন্টারফেস পছন্দ করে

রেশনেল, বিবেচনা করার মূল বিষয়গুলি [এখানে ইতিমধ্যে দু'এই উল্লেখ করা হয়েছে]:

  • ইন্টারফেসগুলি আরও নমনীয়, কারণ একটি শ্রেণি একাধিক ইন্টারফেস প্রয়োগ করতে পারে। যেহেতু জাভার একাধিক উত্তরাধিকার নেই, বিমূর্ত ক্লাস ব্যবহার করা আপনার ব্যবহারকারীদের অন্য কোনও শ্রেণির শ্রেণিবিন্যাস ব্যবহার করা থেকে বিরত রাখে। সাধারণভাবে, যখন কোনও ডিফল্ট বাস্তবায়ন বা রাষ্ট্র না থাকে তখন ইন্টারফেসগুলি পছন্দ করুন। জাভা সংগ্রহগুলি এর ভাল উদাহরণ দেয় (মানচিত্র, সেট ইত্যাদি)।
  • অ্যাবস্ট্রাক্ট ক্লাসে আরও ভাল ফরোয়ার্ড সামঞ্জস্য করার সুযোগ রয়েছে। ক্লায়েন্টরা একবার ইন্টারফেস ব্যবহার করলে আপনি এটিকে পরিবর্তন করতে পারবেন না; যদি তারা একটি বিমূর্ত শ্রেণি ব্যবহার করে তবে আপনি বিদ্যমান কোডটি ভঙ্গ না করে আচরণ যুক্ত করতে পারেন। সামঞ্জস্যতা যদি উদ্বেগের বিষয় থাকে তবে বিমূর্ত ক্লাস ব্যবহার করে বিবেচনা করুন।
  • এমনকি যদি আপনার ডিফল্ট বাস্তবায়ন বা অভ্যন্তরীণ অবস্থা থাকে, তবে একটি ইন্টারফেস এবং এটির একটি বিমূর্ত বাস্তবায়ন প্রস্তাব করুন । এটি ক্লায়েন্টদের সহায়তা করবে, তবে এখনও যদি তাদের ইচ্ছা হয় তবে বৃহত্তর স্বাধীনতার অনুমতি দেয় [1] 1
    অবশ্যই, বিষয়টি অন্যত্র [2,3] দৈর্ঘ্যে আলোচনা করা হয়েছে।

[1] এটি অবশ্যই আরও কোড যুক্ত করে, তবে যদি সংকীর্ণতা আপনার প্রাথমিক উদ্বেগ হয় তবে আপনার সম্ভবত জাভাটিকে প্রথমে এড়ানো উচিত ছিল!

[2] জোশুয়া ব্লচ, কার্যকর জাভা, আইটেম 16-18।

[3] http://www.codeproject.com/KB/ar ...


3

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


3

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

OOD- এ সর্বজনীন উত্তরাধিকারকে অতিরিক্ত ব্যবহার করা হয় এবং বেশিরভাগ বিকাশকারীরা বুঝতে পারছেন বা বেঁচে থাকতে ইচ্ছুক নয় তার চেয়ে অনেক বেশি প্রকাশ করে। দেখুন Liskov Substitutablity নীতি

সংক্ষেপে, যদি A "B" B হয় তবে A এর B এর চেয়ে বেশি দরকার নেই এবং প্রতিটি পদ্ধতির জন্য এটি B এর চেয়ে কম সরবরাহ করে না।


3

মাথায় রাখার আরেকটি বিকল্প হ'ল "হ্যাস-এ" রিলেশনশিপটি ব্যবহার করা হচ্ছে, ওরফে "" বা "রচনার ক্ষেত্রে প্রয়োগ করা হয়েছে। কখনও কখনও এটি "ক্লাস-এ" উত্তরাধিকার ব্যবহারের চেয়ে জিনিসগুলির কাঠামোর আরও পরিচ্ছন্নতর উপায় flex

এটি যুক্তিযুক্তভাবে ততটুকু অনুভূত হতে পারে না যে কুকুর এবং ক্যাট উভয়েরই একটি পোষা প্রাণী রয়েছে "তবে এটি একাধিক উত্তরাধিকারের সমস্যাগুলি এড়িয়ে চলে:

public class Pet
{
    void Bathe();
    void Train(Trick t);
}

public class Dog
{
    private Pet pet;

    public void Bathe() { pet.Bathe(); }
    public void Train(Trick t) { pet.Train(t); }
}

public class Cat
{
    private Pet pet;

    public void Bathe() { pet.Bathe(); }
    public void Train(Trick t) { pet.Train(t); }
}

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

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

উত্তরাধিকার, রচনা এবং ইন্টারফেসের মধ্যে সর্বদা সঠিক কোনও উপায় নেই এবং এটি তিনটি বিকল্পকে কীভাবে সামঞ্জস্যভাবে ব্যবহার করা যেতে পারে তা বিবেচনা করতে সহায়তা করে। তিনটির মধ্যে উত্তরাধিকার হ'ল বিকল্পটি যা কমপক্ষে প্রায়শই ব্যবহার করা উচিত।


3

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

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

ক্লাসগুলি একটি বাস্তবায়ন সরবরাহ করে এবং তারা ঘোষণা করতে পারে যে তারা শূন্য, এক বা একাধিক ইন্টারফেস প্রয়োগ করে। যদি কোনও শ্রেণি উত্তরাধিকার সূত্রে প্রাপ্ত হওয়ার উদ্দেশ্যে হয়, তবে কনভেনশনটি ক্লাসের নামটিকে "বেস" দিয়ে উপসর্গ করা হয়।

বেস ক্লাস এবং অ্যাবস্ট্রাক্ট বেস ক্লাস (এবিসি) এর মধ্যে পার্থক্য রয়েছে । এবিসিরা একসাথে ইন্টারফেস এবং প্রয়োগের মিশ্রণ করে। কম্পিউটার প্রোগ্রামিংয়ের বাইরে বিমূর্তিটির অর্থ "সারাংশ", এটি "বিমূর্ত == ইন্টারফেস"। তারপরে একটি বিমূর্ত বেস ক্লাস উভয়ই একটি ইন্টারফেস বর্ণনা করতে পারে, পাশাপাশি খালি, আংশিক বা সম্পূর্ণ প্রয়োগ যা উত্তরাধিকার সূত্রে প্রাপ্ত বলে মনে হয়।

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

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


2

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

বেস ক্লাস বাস্তবায়নের ক্ষয়ক্ষতি হ'ল বিদ্যমান পদ্ধতিগুলির override(বা new) প্রয়োজনীয়তা । এটি তাদের ভার্চুয়াল পদ্ধতিতে পরিণত করে যার অর্থ আপনি কীভাবে অবজেক্ট উদাহরণটি ব্যবহার করবেন সে সম্পর্কে আপনাকে সতর্কতা অবলম্বন করতে হবে।

শেষ অবধি, .NET এর একক উত্তরাধিকার আমাকে হত্যা করে। একটি নিষ্পাপ উদাহরণ: বলুন যে আপনি একটি ব্যবহারকারী নিয়ন্ত্রণ তৈরি করছেন, যাতে আপনি উত্তরাধিকার সূত্রে পান UserControl। তবে, এখন আপনি উত্তরাধিকার সূত্রে লক আউট হয়ে গেছেন PetBase। এটি আপনাকে পুনর্গঠন করতে বাধ্য করে, যেমন PetBaseপরিবর্তে কোনও শ্রেণীর সদস্য তৈরি করতে।


2

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


2

সি # সম্পর্কিত, কিছু সংবেদনে ইন্টারফেস এবং বিমূর্ত শ্রেণিগুলি বিনিময়যোগ্য হতে পারে। তবে, পার্থক্যগুলি হ'ল: i) ইন্টারফেসগুলি কোড প্রয়োগ করতে পারে না; ii) এ কারণে, ইন্টারফেসগুলি সাবক্লাসে স্ট্যাকটি আর কল করতে পারে না; এবং iii) কেবল বিমূর্ত ক্লাসটি কোনও শ্রেণিতে উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে, যেখানে একাধিক ইন্টারফেস একটি শ্রেণিতে প্রয়োগ করা যেতে পারে।


2

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


2

আমি দেখতে পেয়েছি যে ইন্টারফেস> বিমূর্তি> কংক্রিটের একটি প্যাটার্ন নিম্নলিখিত ব্যবহারের ক্ষেত্রে কাজ করে:

1.  You have a general interface (eg IPet)
2.  You have a implementation that is less general (eg Mammal)
3.  You have many concrete members (eg Cat, Dog, Ape)

বিমূর্ত শ্রেণিটি কংক্রিট শ্রেণীর ডিফল্ট ভাগযুক্ত বৈশিষ্ট্যগুলি সংজ্ঞায়িত করে, তবুও ইন্টারফেসটি প্রয়োগ করে। উদাহরণ স্বরূপ:

public interface IPet{

    public boolean hasHair();

    public boolean walksUprights();

    public boolean hasNipples();
}

এখন, যেহেতু সমস্ত স্তন্যপায়ী প্রাণীর চুল এবং স্তনবৃন্ত রয়েছে (আফাইক, আমি একজন প্রাণীবিজ্ঞানী নই), তাই আমরা এটি বিমূর্ত বেস শ্রেণিতে রোল করতে পারি

public abstract class Mammal() implements IPet{

     @override
     public walksUpright(){
         throw new NotSupportedException("Walks Upright not implemented");
     }

     @override
     public hasNipples(){return true}

     @override
     public hasHair(){return true}

এবং তারপরে কংক্রিট ক্লাসগুলি কেবলমাত্র সংজ্ঞায়িত করে যে তারা সোজা হয়ে হাঁটছে।

public class Ape extends Mammal(){

    @override
    public walksUpright(return true)
}

public class Catextends Mammal(){

    @override
    public walksUpright(return false)
}

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

এই ক্ষেত্রে, বিমূর্তটি ঠিক পাশাপাশি কংক্রিট হতে পারে; তবে, বিমূর্ত পদবী জোর দিয়ে সাহায্য করে যে এই প্যাটার্নটি নিযুক্ত করা হচ্ছে।


1

বেস শ্রেণীর উত্তরাধিকারীর "" একটি "সম্পর্ক থাকা উচিত। ইন্টারফেস একটি "প্রয়োগ করে" সম্পর্ককে প্রতিনিধিত্ব করে। সুতরাং কেবলমাত্র একটি বেস ক্লাস ব্যবহার করুন যখন আপনার উত্তরাধিকারীরা সম্পর্ক বজায় রাখবেন।


1

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

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

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