জাভাতে "ইন্টারফেসের সাথে প্রোগ্রাম করার" জন্য এটি কি সর্বদা ধারণা দেয়?


9

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

Map<X> map = new TreeMap<X>();

আমার প্রোগ্রামে, আমি ফাংশনটি কল করছি map.pollFirstEntry(), যা Mapইন্টারফেসে ঘোষণা করা হয়নি (এবং আরও কয়েকজন যারা Mapইন্টারফেসে উপস্থিত আছেন)। আমি TreeMap<X>এই পদ্ধতিটিকে যে কোনও জায়গায় বলি যেখানেই কাস্টিং করে এটি করতে পেরেছি:

someEntry = ((TreeMap<X>) map).pollFirstEntry();

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

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


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

পছন্দ করুন
জিমিজ্জাজ


2
"আমি বড় প্রোগ্রামগুলির জন্য উপরে বর্ণিত সূচনা নির্দেশিকার সুবিধাগুলি বুঝতে পেরেছি" প্রোগ্রামের আকার যতই হোক না কেন পুরো জায়গাতেই কাস্ট করা সুবিধাজনক নয়
বেন অ্যারনসন

উত্তর:


23

"একটি ইন্টারফেসে প্রোগ্রামিং" এর অর্থ "সম্ভাব্য সবচেয়ে বিমূর্ত সংস্করণ ব্যবহার করা" নয়। সেক্ষেত্রে সবাই কেবল ব্যবহার করবে Object

এর অর্থ হ'ল আপনার কার্যকারিতাটি হারাতে না পারলে আপনার প্রোগ্রামটি সর্বনিম্ন সম্ভাব্য বিমূর্ততার বিরুদ্ধে সংজ্ঞায়িত করা উচিত । আপনি যদি একটি প্রয়োজন হলে TreeMapতারপর আপনি একটি ব্যবহার করে একটি চুক্তি সংজ্ঞায়িত করতে হবে TreeMap


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

3
@ মিশেলটি: এই নির্দিষ্ট দৃশ্যে তার ঠিক কী বিমূর্ততা দরকার তা আমি দেখিনি তাই আমি TreeMapউদাহরণ হিসাবে ব্যবহার করেছি । "প্রোগ্রামকে একটি ইন্টারফেস" আক্ষরিকভাবে একটি ইন্টারফেস বা বিমূর্ত শ্রেণীর হিসাবে নেওয়া উচিত নয় - একটি বাস্তবায়নও একটি ইন্টারফেস হিসাবে বিবেচনা করা যেতে পারে।
জেরোইন ভেনেভেল

1
যদিও একটি বাস্তবায়ন শ্রেণীর পাবলিক ইন্টারফেস / পদ্ধতিগুলি প্রযুক্তিগতভাবে একটি 'ইন্টারফেস', এটি এলএসপির পিছনে ধারণাকে ভেঙে দেয় এবং একটি পৃথক সাবক্লাসের প্রতিস্থাপনকে বাধা দেয় যার কারণে আপনি public interface'বাস্তবায়নের পাবলিক পদ্ধতিগুলি' পরিবর্তে প্রোগ্রাম করতে চান ।

@JeroenVannevel সে ব্যাপারে আমি সম্মত একটি ইন্টারফেসে প্রোগ্রামিং যখন কাজ করা যেতে পারে ইন্টারফেস আসলে একটি বর্গ প্রতিনিধিত্ব করেন। যাইহোক, আমি কি ব্যবহার সুবিধার মনে হল না TreeMapউপরে হবে SortedMapবাNavigableMap
toniedzwiedz

16

আপনি যদি এখনও ইন্টারফেস ব্যবহার করতে চান তবে আপনি ব্যবহার করতে পারেন

NavigableMap <X, Y> map = new TreeMap<X, Y>();

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


3

একটি প্রয়োগকরণের পরিবর্তে একটি ইন্টারফেসে কোডিংয়ের পিছনে মূল বিষয়টি হ'ল বাস্তবায়ন সংক্রান্ত বিশদটি ফাঁস করা এড়ানো যা অন্যথায় আপনার প্রোগ্রামকে বাধা দেয়।

আপনার কোডের মূল সংস্করণটি যেটি ব্যবহার করেছে HashMapএবং তা প্রকাশ করেছে সেই পরিস্থিতিটি বিবেচনা করুন ।

private HashMap foo = new HashMap();
public HashMap getFoo() { return foo; }  // This is bad, don't do this.

এর অর্থ হ'ল যে কোনও পরিবর্তন getFoo()হ'ল একটি ব্রেকিং এপিআই পরিবর্তন এবং এটি ব্যবহার করে লোককে অসন্তুষ্ট করবে। আপনি যে সমস্ত গ্যারান্টি দিচ্ছেন সেগুলি fooযদি মানচিত্র হয় তবে পরিবর্তে আপনার এটি ফিরিয়ে দেওয়া উচিত।

private Map foo = new HashMap();
public Map getFoo() { return foo; }

এটি আপনাকে কীভাবে আপনার কোডের অভ্যন্তরে কাজ করে তা পরিবর্তন করার নমনীয়তা দেয়। আপনি বুঝতে পারেন যে fooআসলে একটি মানচিত্র হওয়া দরকার যা কোনও নির্দিষ্ট ক্রমে জিনিসগুলি ফিরিয়ে দেয়।

private NavigableMap foo = new TreeMap();
public Map getFoo() { return foo; }
private void doBar() { ... foo.lastEntry(); ... }

এবং এটি বাকী কোডটির জন্য কিছু ভঙ্গ করে না।

পরে কোনও কিছু না ভাঙিয়ে ক্লাসটি দেয় চুক্তিটি আপনি পরে শক্ত করতে পারেন।

private NavigableMap foo = new TreeMap();
public NavigableMap getFoo() { return foo; }
private void doBar() { ... foo.lastEntry(); ... }

এটি লিসকোভের প্রতিস্থাপনের নীতিটি আবিষ্কার করে

সাবস্টিটিউটেবিলিটি অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের একটি নীতি principle এটিতে বলা হয়েছে যে একটি কম্পিউটার প্রোগ্রামে যদি এস টি এর টিউব টাইপ হয়, তবে টাইপ টির জিনিসগুলি এস টাইপের এসের সাথে প্রতিস্থাপন করা যেতে পারে (অর্থাত, এস টাইপের এসের অবজেক্টগুলি টাইপ টি-এর বস্তুর প্রতিস্থাপন করতে পারে) কাঙ্ক্ষিত কোনও পরিবর্তন ছাড়াই সেই প্রোগ্রামের বৈশিষ্ট্য (সঠিকতা, কার্য সম্পাদন, ইত্যাদি)।

যেহেতু নাভিগিয়েবলম্যাপ মানচিত্রের একটি সাব টাইপ, তাই প্রোগ্রামটি পরিবর্তন না করেই এই প্রতিস্থাপনটি করা যেতে পারে।

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

আপনি এখনও বাস্তবায়ন ধরণের ফাঁস এড়াতে চাইবেন। উদাহরণস্বরূপ, আপনি কিছু পারফরম্যান্স বৈশিষ্ট্যের কারণে বা আপনার আমদানি বিবৃতি বা যা java.util.concurrent.ConcurrentSkipListMapকিছু java.util.TreeMapনা করে বরং পছন্দ করেন তার পরিবর্তে আপনি কনকন্টারস্কিপলিস্টম্যাপটি প্রয়োগ করতে চাইতে পারেন ।


1

অন্যান্য উত্তরের সাথে একমত যে আপনার সর্বাধিক জেনেরিক শ্রেণি (বা ইন্টারফেস) ব্যবহার করা উচিত যার মধ্যে আপনার আসলে কিছু দরকার, এই ক্ষেত্রে ট্রিম্যাপ (বা কেউ নেভিগিব্যাপের মতো পরামর্শ দিয়েছেন)। তবে আমি যুক্ত করতে চাই যে এটি সর্বত্র এটি ছড়িয়ে দেওয়ার চেয়ে অবশ্যই সবচেয়ে ভাল, এটি যে কোনও ক্ষেত্রেই আরও বড় গন্ধ হবে smell কিছু কারণে /programming/4167304/why-should-casting-be-avoided দেখুন ।


1

এটা আপনার যোগাযোগ সম্বন্ধে অভিপ্রায় এর কিভাবে বস্তু ব্যবহার করা উচিত। উদাহরণস্বরূপ, যদি আপনার পদ্ধতিটি পূর্বাভাসযোগ্য পুনরাবৃত্তির ক্রমMap সহ কোনও বস্তুর প্রত্যাশা করে :

private Map<String, String> processOrderedMap(LinkedHashMap<String, String> input) {
    // ...
}

তারপরে, যদি আপনাকে উপরের পদ্ধতিটির কলকারীদের একেবারে বলতে হয় যে এটি খুব পূর্বাভাসযোগ্য পুনরাবৃত্তির ক্রমMap সহ কোনও বস্তুটি ফেরত দেয় , কারণ কোনও কারণে এমন প্রত্যাশা রয়েছে:

private LinkedHashMap<String,String> processOrderedMap(LinkedHashMap<String,String> input) {
    // ...
}

অবশ্যই, কলাররা এখনও রিটার্ন অবজেক্টটিকে Mapএরূপ হিসাবে বিবেচনা করতে পারে তবে এটি আপনার পদ্ধতির বাইরে beyond

private Map<String, String> output = processOrderedMap(input);

এক ধাপ পিছনে নিচ্ছে

একটি ইন্টারফেসে কোডিংয়ের সাধারণ পরামর্শটি (সাধারণত) প্রযোজ্য হয়, কারণ এটি সাধারণত ইন্টারফেস যা গ্যারান্টি সরবরাহ করে যে বস্তুটি সম্পাদন করতে সক্ষম হওয়া উচিত, চুক্তিটি ওরফে । অনেক সূচনা দিয়ে শুরু হয় HashMap<K, V> map = new HashMap<>()এবং তাদেরকে এটি হিসাবে ঘোষণা করার পরামর্শ দেওয়া হয় Map, কারণ একটি করণীয় HashMapযা করা Mapহয় তার চেয়ে বেশি কিছু সরবরাহ করে না। এখান থেকে তারা তখন বুঝতে পারবেন (আশা করি) কেন তাদের পদ্ধতিগুলি Mapপরিবর্তে একটি পরিবর্তে নেওয়া উচিত HashMapএবং এটি ওওপি-র উত্তরাধিকার বৈশিষ্ট্যটি উপলব্ধি করতে দেয়।

এই বিষয় সম্পর্কিত প্রত্যেকের প্রিয় নীতি উইকিপিডিয়া এন্ট্রি থেকে শুধুমাত্র একটি লাইন উদ্ধৃত :

এটি নিছক সিনট্যাক্টিক সম্পর্কের পরিবর্তে একটি শব্দার্থক কারণ এটি একটি শ্রেণিবিন্যাসের ধরণের শব্দার্থক আন্তঃব্যবযোগিতার গ্যারান্টি দিতে চায় ...

অন্য কথায়, একটি Mapঘোষণাপত্র ব্যবহার করা নয় কারণ এটি 'সিনট্যাক্টিক্যালি' অর্থবোধ করে, বরং বস্তুটির অনুরোধগুলি কেবল এটির একধরণের যত্ন নেওয়া উচিত Map

ক্লিনার কোড

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

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