জাভা উদাহরণস্বরূপ প্রতিস্থাপন?


10

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

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

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

এটি করার আরও ভাল উপায় আছে বা আমি কি instanceofক্ষেত্রগুলিকে নির্দিষ্ট ক্ষেত্রগুলি নির্দিষ্ট করার জন্য বা কোনও ধরণের প্রতিবিম্ব ব্যবহার করে আটকেছি?


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

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

উত্তর:


16

instanceofনিরুৎসাহিত হওয়ার কারণটি এটি ওওপি নয়।

কোন বস্তুর কলার / ব্যবহারকারীর পক্ষে কোন কংক্রিটের শ্রেণি এটি কোন ধরণের ভেরিয়েবল হিসাবে ঘোষিত হয়েছে তা প্রমাণ করার কোনও কারণ নেই।

আপনার যদি সাবক্লাসে ভিন্ন আচরণের প্রয়োজন হয় তবে একটি পদ্ধতি যুক্ত করুন এবং সেগুলি আলাদাভাবে প্রয়োগ করুন।


1
সুতরাং getSpecifics()প্রতিটি ক্লাসে একটি পদ্ধতি (বা অনুরূপ কিছু) যা প্রতিটি শ্রেণির জন্য নির্দিষ্ট বৈশিষ্ট্যগুলি ফিরিয়ে দেবে। এটিই কি সেরা পন্থা?
থমাস মিচেল

@ স্কমুও আপনাকে সত্যই চিন্তা করতে হবে শ্রেণিবক্ষের মধ্যে কোথায় সাধারণ কার্যকারিতা বিদ্যমান এবং প্রতিটি স্তরে কোন চুক্তি বিদ্যমান।

3
তবে যখন আপনার অবজেক্ট ক্রস স্তরগুলি এবং প্রকারের তথ্যটি হারিয়ে যায় তখন কী হবে? উদাহরণ আমি তৈরি একটি List। আমি এটি একটি অবজেক্টে পাস করি যে কোনও গ্রহণ করে Iterable। এখন যে দ্বিতীয় অবজেক্টটি এটি তৃতীয় অবজেক্টকে দেয় যা Listঅপ্টিমাইজেশনের জন্য নেয়, বা একটি Iterableকিন্তু অনেক ধীর হয়। দ্বিতীয়টি এটির একটি তালিকা জানা উচিত নয়, তবে তৃতীয়টি এটি জানতে আগ্রহী। উদাহরণস্বরূপ তৃতীয় অবজেক্টটি চেক করা উচিত নয় যে এটি অপ্টিমাইজেশন প্রয়োগ করতে পারে? উদাহরণস্বরূপ পেয়ারা দেখুন FluentIterableযা কেবল এটি করে।
লরেন্ট বোর্গোল্ট-রায়

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

9

instanceof অগত্যা কোনও খারাপ জিনিস নয়, তবে এটি এমন একটি বিষয় যা দেখানো উচিত।

এটি সঠিকভাবে কোথায় কাজ করে তার একটি উদাহরণ এমন এক জায়গায় যেখানে কোনওটি বেস ধরণের সংগ্রহ পায় এবং আপনি কেবল একটি উপ-টাইপ চান। নেটওয়ার্ক NetworkInterface.getNetworkInterfaces()ইনটারফেস অবজেক্টগুলির ইনটএড্রেস অবজেক্টের সংকলন রয়েছে এমন নেটওয়ার্কের ঠিকানাগুলি ফেরত পাওয়া যায় যার মধ্যে কয়েকটি ইনট 4 অ্যাড্রেস এবং কিছু ইনট 6 অ্যাড্রেস। যদি কেউ ইনট 4 অ্যাড্রেস অবজেক্টের জন্য সংগ্রহটি ফিল্টার করতে চায় তবে উদাহরণস্বরূপ ব্যবহার করা প্রয়োজন।

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

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

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


এটা সম্ভব যে ইন্টারফেসটি একটি isOfType(SomeEnum.IPv4)পদ্ধতি নির্দিষ্ট করে এর মাধ্যমে কংক্রিটের ধরণের নিরীক্ষণের চেয়ে এই জাতীয় গুণাবলীর জন্য ফিল্টার করার ভাল উপায় হতে পারে instanceof। আপনি যদি আপনার আইপিভি 4 বাস্তবায়ন শ্রেণীর পরে ভাগ করতে চান তবে কী হবে? এটি সর্বদা ভাল না এমন নয়, তবে এটি একটি বিবেচনা।
স্টিভেন শ্লানস্কার

@ স্টিভেনশ্ল্যাঙ্কার যা নির্দিষ্ট শ্রেণীর জন্য কাজ করতে পারে। তবে যদি কোনও কাস্ট্র্ট সম্ভব কিনা তা দেখার জন্য কংক্রিটের ধরণটি পরীক্ষা করার প্রয়োজন হয় (বা কোনও কি কেবল ব্যতিক্রমটি কাস্ট করতে পারে এবং ধরতে পারে?) ইনেট 6 অ্যাড্রেস ইনটএড্রেসের চেয়ে আরও বেশি পদ্ধতি প্রয়োগ করে। ইন্টারফেসের সাথে কাজ করা কঠিন হবে (প্যাকেজের প্রতিটি শ্রেণি গণনা করে এমন একটি এনাম? বা শ্রেণি লোডার?) এবং এর অর্থ হ'ল পদ্ধতিটি হাতে (বা অবজেক্টে কিছু প্রতিবিম্ব কোড) প্রয়োগ করতে হবে। কীভাবে করবেন তা বিবেচনা করুন (o instanceof Serializable) || (o instanceof Externalizable)। উদাহরণ বিকল্পের চেয়ে ভাল

1

আপনি getClass () পদ্ধতি ব্যবহার করতে পারেন।

আপনি কি নিশ্চিত যে আপনার তিনটি পৃথক ক্লাস প্রয়োজন? ভিতরে একটি স্যুইচ সহ একটি শ্রেণি আরও ভাল পরিবেশন করবে?


7
getClassএবং instanceofডাউনসাইড ভাগ করুন। পলিমারফিজম এটি মাপসই করা উভয়ের চেয়ে বেশি ভাল এবং আমি দেখতে পাচ্ছি না যে এটি ওপির ব্যবহারের ক্ষেত্রে উপযুক্ত নয়।

আপনার প্রথম বাক্যটির বিরুদ্ধে আমার কিছুই নেই। তবে দ্বিতীয়টি - দুঃখিত, আপনি কী বলতে চাইছেন তা আমি বুঝতে পারি না।
গাংনুস

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

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

2
@ গাঙ্গাস আমি এটিকে "আক্রমণ" হিসাবে ভাবি না, মানে কোনও অপরাধ নয়। কিন্তু যাই হোক না কেন. না, প্রশ্নটি "আর কী ব্যবহার করা যায়" তা নয়, এটি "এটি করার আরও ভাল উপায় কি"। আপনি যদি তর্ক করতে না চান getClassতবে এটি করার সবচেয়ে ভাল উপায়, এটির বেশিরভাগ উত্তর গ্রহণের কোনও ব্যবসা নেই ;-)

1

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

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

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

আশাকরি এটা সাহায্য করবে

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