জাভার কালেকশন ইন্টারফেসটি ব্যবহার করার কোনও ভাল কারণ আছে?


11

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

আমি বরং নীচের মত কিছু দেখতে চাই:

List<Foo> getFoos()

অথবা

Set<Foo> getFoos()

পরিবর্তে

Collection<Foo> getFoos()

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

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


3
আপনি কি জাভা.সিকিউরিটি.সার্টে লক্ষ্য করেছেন যে এক রিটার্ন টাইপ Collection<List<?>>? কোডিং হরর সম্পর্কে কথা!
ম্যাকনাইল

1
@ ম্যাকনাইল আমি জানি না আপনি কোন শ্রেণীর বিষয়ে উল্লেখ করেছেন তবে এই ধরনের রিটার্নের ধরনটি যথেষ্ট বুদ্ধিমান হতে পারে। এটি মূলত আপনাকে বলে আপনি একটি আছে সংগ্রহ (যেমন একটি যে জিনিস গুচ্ছ ধারণকারী নেই একটি যুক্তিসম্মত ক্রম) তালিকা (অর্থাত যে ধারণকারী আছে একটি যুক্তিসম্মত ক্রম) বস্তু (যেমন আইটেম যার ধরনের আমরা জন্য স্ট্যাটিক্যালি জানি না যাই হোক না কেন কারণ)। আমার কাছে অযৌক্তিক বলে মনে হয় না।
জিরো 3

উত্তর:


13

বিমূর্ততা বাস্তবায়নের চেয়ে দীর্ঘকাল বেঁচে থাকে

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

যাইহোক, অত্যধিক নীতিটি হ'ল সর্বাধিক উপযুক্ত বিমূর্ততা ব্যবহার করা । সুতরাং যদি আপনার সংগ্রহটি অবশ্যই আদেশিত উপাদানগুলিকে সমর্থন করে তবে একটি তালিকা আদেশ করুন, যদি কোনও নকল না থাকে তবে একটি সেট ম্যান্ডেট করুন and

জেনেরিক ইন্টারফেস ডিজাইনের একটি নোট

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

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

public void pushAll(Collection<? extends E> producerCollection) {}

সুতরাং ইনপুট প্রকারটি E বা E এর যে কোনও সাবক্লাস হতে পারে (ই জাভা ভাষায় নিজের একটি সুপার এবং উপ-শ্রেণি উভয় হিসাবে সংজ্ঞায়িত হয়েছে)।

বিপরীতে, একটি জেনেরিক সংগ্রহ যা ডেটা গ্রহণের জন্য পাস করা হয় তাতে এর স্বাক্ষর থাকতে হবে:

public void popAll(Collection<? super E> consumerCollection) {}

পদ্ধতিটি ই এর যে কোনও সুপারক্লাসের সাথে সঠিকভাবে মোকাবেলা করবে O সামগ্রিকভাবে, এই পদ্ধতির ব্যবহারটি আপনার ব্যবহারকারীদের কাছে আপনার ইন্টারফেসটিকে কম আশ্চর্যজনক করে তুলবে কারণ আপনি এতে প্রবেশ করতে সক্ষম হবেন Collection<Number>এবং Collection<Integer>সঠিকভাবে চিকিত্সা করতে পারবেন।


6

Collectionইন্টারফেস, এবং সবচেয়ে প্রশ্রয়ের ফর্ম Collection<?>, জন্য মহান পরামিতি যে আপনার গ্রহণ। জাভা লাইব্রেরিতে নিজেই ব্যবহারের ভিত্তিতে এটি কোনও রিটার্ন টাইপের চেয়ে পরামিতি টাইপ হিসাবে বেশি সাধারণ।

প্রত্যাবর্তনের ধরণের জন্য, আমি মনে করি যে আপনার বক্তব্যটি বৈধ: লোকেরা যদি এটি অ্যাক্সেস করার প্রত্যাশা করে তবে তাদের অপারেশনটির ক্রমটি (বিগ-ও অর্থে) জানা উচিত। আমি কোনও Collectionপ্রত্যাবর্তনকালে পুনরাবৃত্তি করব এবং এটি অন্য সংগ্রহের সাথে যুক্ত করব, তবে এটি containsও (1), ও (লগ এন), বা ও (এন) ক্রিয়াকলাপ কিনা তা জেনেও এটির কল করা কিছুটা ক্রেজি মনে হবে। অবশ্যই, কারণ আপনার কাছে Setএটির অর্থ হ্যাশসেট বা একটি সাজানো সেট নয়, তবে কোনও কোনও সময় আপনি অনুমান করবেন যে ইন্টারফেসটি যুক্তিসঙ্গতভাবে প্রয়োগ করা হয়েছে (এবং তারপরে আপনার অনুমিতি যদি আপনাকে বি প্ল্যানে যেতে হবে) ভুল হিসাবে দেখানো হয়েছে)।

টম যেমন উল্লেখ করেছেন, কখনও কখনও Collectionএনক্যাপসুলেশন বজায় রাখার জন্য আপনাকে একটি ফেরত দিতে হবে: আপনি আরও কিছু সুনির্দিষ্ট কিছু ফিরিয়ে দিতে পারলেও বাস্তবায়ন বিশদটি ফাঁস হতে চান না। অথবা, টমের উল্লিখিত ক্ষেত্রে আপনি আরও সুনির্দিষ্ট ধারকটি ফিরিয়ে দিতে পারবেন তবে তারপরে আপনাকে এটি তৈরি করতে হবে।


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

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

@ টম: ভাল পয়েন্ট!
ম্যাকনিল

5

আমি সম্পূর্ণ বিপরীত দৃষ্টিকোণ থেকে এটি তাকান, এবং জিজ্ঞাসা:

যদি আপনি কোনও কোড পর্যালোচনা করার সময় তালিকা <> তালিকাভুক্ত এমন কোড জুড়ে এসে পৌঁছে থাকেন তবে আপনি কীভাবে এটি নির্ধারণ করবেন যে এর ব্যবহারটি ন্যায়সঙ্গত কিনা?

এটি ন্যায়সঙ্গত করা বেশ সহজ। আপনি তালিকাটি ব্যবহার করেন যখন আপনার কোনও কার্যকারিতা প্রয়োজন যা কোনও সংগ্রহ দ্বারা অফার করা হয় না। আপনার যদি অতিরিক্ত অতিরিক্ত কার্যকারিতা প্রয়োজন না হয় - আপনার কী ন্যায়সঙ্গততা আছে? (এবং আমি কিনব না, "আমি এটি দেখতে পছন্দ করব"))

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

একটি বাস্তব উদাহরণ দিতে। বলুন আমি একটি ডাটাবেসে একটি সাধারণ ক্যোয়ারী সম্পাদন করি। ( SELECT id,name,rep FROM people WHERE name LIKE '%squared') আমি প্রাসঙ্গিক ডেটা ফিরিয়ে আনি, ব্যক্তি বস্তুগুলি তৈরি করি এবং একটি ব্যক্তির তালিকায় রাখি)

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

সুতরাং এই অতিরিক্ত পদ্ধতিগুলির জন্য আমার কী ন্যায়সঙ্গততা থাকবে? (যা যাইহোক আমার ব্যক্তি তালিকায় অপরিবর্তিত রেখে দেওয়া হবে)


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

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

সম্মত হয়েছে, তবে আমরা হাইবারনেট ব্যবহার করছি এবং আমাদের সত্তাগুলি সমান () সমাপ্তির বিষয়টি নিশ্চিত করে। সুতরাং যখন কোনও ডিএও সত্তা ফিরিয়ে দিচ্ছে, আমরা খুব দ্রুত নতুন হ্যাশসেট () যোগ করতে পারি ll সমস্ত (ফলাফল) এবং সেইটিকে ফিরে পদ্ধতিতে ফিরে যেতে পারি।
ফিল্ম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.