প্রতিবিম্ব সহ জেনেরিক সেটার এবং গেটর তৈরি করা কেন খারাপ ধারণা?


49

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

সুতরাং, বিশেষত জেনেরিক গেটার এবং সিটারের ক্ষেত্রে প্রতিচ্ছবিটি এড়ানো উচিত বলে কেন এটি দেওয়া হয়েছে তা কেউ মৌখিক করতে পারেন?


12
আপনি যদি কেবল বয়লারপ্লেট হ্রাস করতে চান তবে লম্বোক এবং গ্রোভি উভয়ই নিঃশব্দে তবে নিরাপদে গেটার এবং সেটটার তৈরি করবে।
ক্রাইলিস-হরতাল-

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

@EsbenSkovPedersen আপনি তাদেরকে অনেক একটি মত গ্রাস করতো Map'র getএবং putযার জিনিসগুলি একটি চমত্কার ক্লাঙ্কি উপায়।
HAEM

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

উত্তর:


117

সাধারণভাবে প্রতিবিম্বের ডাউনসাইডস

সরলরেখার কোডের চেয়ে প্রতিবিম্ব বোঝা শক্ত।

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

প্রতিবিম্ব কোডটি স্থির বিশ্লেষণে অ্যাক্সেসযোগ্য

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

তবে যদি গেটর ব্যবহার করে এমন জায়গাটি যদি এর মতো callGetter("Foo")এবং কিছু callGetterহয় getClass().getMethod("get"+name).invoke(this)তবে উপরের পদ্ধতিটি এটি খুঁজে পাবে না এবং সংকলকটি অভিযোগ করবে না। কোডটি আসলে কার্যকর হলেই আপনি একটি পাবেন NoSuchMethodException। এবং সেই ব্যতিক্রমটি (যা ট্র্যাক করা হয়) গিলে ফেললে আপনি যে ব্যথার মধ্যে রয়েছেন তা কল্পনা করুন callGetterকারণ "এটি কেবল হার্ড-কোডিং স্ট্রিংগুলির সাথে ব্যবহৃত হয়, এটি আসলে ঘটতে পারে না"। (কেউ তা করবে না, কেউ তর্ক করতে পারে? বাদে ওপি তার এসও উত্তরে ঠিক এমনটি করেছিল the যদি ক্ষেত্রটির নাম পরিবর্তন করা হয় তবে জেনেরিক সেটারের ব্যবহারকারীরা সেটার চূড়ান্ত অস্পষ্ট ত্রুটিবিহীন চুপচাপ কিছুই বাদ দিয়ে কিছুই খেয়াল করতে পারে না। প্রাপ্ত ব্যবহারকারীরা যদি ভাগ্যবান হন তবে অবহেলিত ব্যতিক্রমের কনসোল আউটপুটটি লক্ষ্য করুন))

প্রতিবিম্ব কোডটি সংকলক দ্বারা টাইপ-চেক করা হয় না

এটি মূলত উপরের একটি বৃহত উপ-পয়েন্ট। প্রতিবিম্ব কোড সম্পর্কে Object। প্রকারগুলি রানটাইমের সময় পরীক্ষা করা হয়। ত্রুটিগুলি ইউনিট পরীক্ষাগুলি দ্বারা আবিষ্কার করা হয় তবে কেবল আপনার কভারেজ থাকলে। ("এটি কেবল প্রাপ্তি, আমার এটি পরীক্ষা করার দরকার নেই।") মূলত, আপনি পাইথনের ওপরে জাভা ব্যবহার করে সুবিধাটি হারাতে পারেন place

অপ্টিমাইজেশনের জন্য প্রতিবিম্ব কোড অনুপলব্ধ

সম্ভবত তাত্ত্বিকভাবে নয়, তবে অনুশীলনে আপনি এমন কোনও জেভিএম পাবেন না যা এর জন্য একটি ইনলাইন ক্যাশে ইনলাইন করে বা তৈরি করে Method.invoke। এই জাতীয়করণের জন্য সাধারণ পদ্ধতি কলগুলি উপলভ্য। এটি তাদের অনেক দ্রুত করে তোলে।

প্রতিবিম্ব কোডটি সাধারণভাবে স্লো

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

জেনেরিক গেটর / সেটারের বিশেষত ক্ষতি

এটি কেবল একটি খারাপ ধারণা, কারণ আপনার ক্লাসের এখন আর কোনও এনক্যাপসুলেশন নেই। এটির প্রতিটি ক্ষেত্র অ্যাক্সেসযোগ্য। আপনি তাদের পাশাপাশি সর্বজনীন করতে পারেন।


8
আপনি সমস্ত প্রধান পয়েন্ট আঘাত। বেশ একটি নিখুঁত উত্তর। আমি দ্বিধা করতে পারি যে গেটার্স এবং সেটারগুলি পাবলিক ফিল্ডগুলির তুলনায় প্রান্তিকভাবে ভাল তবে বড় বিষয়টি সঠিক।
জিমি জেমস

2
এটিও উল্লেখযোগ্য যে গেইটার্স / সেটটারগুলি সহজেই কোনও আইডিই দ্বারা তৈরি করা যায়।
stiemannkj1

26
প্রোডাকশন-আকারের প্রকল্পে +1 ডিবাগিং প্রতিবিম্বের যুক্তিটিকে জাতিসংঘ কর্তৃক নির্যাতন হিসাবে স্বীকৃতি দেওয়া উচিত এবং অবৈধভাবে চালিত হওয়া উচিত।
ভুল ত্রুটি

4
"এই প্রোগ্রামারগুলির পক্ষে বোঝা শক্ত" " - এই প্রোগ্রামারদের পক্ষে এটি বোঝার জন্য উল্লেখযোগ্যভাবে কঠিন, তবে যতই দক্ষই হোক না কেন, সবার পক্ষে এটি বোঝা আরও শক্ত
বার্তোসকেপিপি

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

11

কারণ পাস-থ্রি গেটর / সেটারগুলি এমন একটি ঘৃণা যা কোনও মূল্য দেয় না। তারা কোনও এনক্যাপসুলেশন সরবরাহ করে না কারণ ব্যবহারকারীরা সম্পত্তিটির মাধ্যমে প্রকৃত মান পেতে পারেন। এগুলি ইয়াজিএনআই কারণ আপনার ক্ষেত্রের সঞ্চয়স্থানের প্রয়োগ পরিবর্তন করতে গেলে খুব কমই হয়।

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

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


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

11
সি # বৈশিষ্ট্যগুলি পোষাক-আপ প্রাপ্তি / সেটটারগুলি রয়েছে। তবে হ্যাঁ, বিনের ধারণাটি একটি বিপর্যয়।
সেবাস্তিয়ান রেডল

6
@ এমন রাইট, সি # একটি ভয়ানক ধারণা নিয়েছে এবং এটি কার্যকর করা সহজ is
জিমি জেমস

5
@ জিমি জেমস সত্যিই এটি কোনও ভয়ঙ্কর ধারণা নয়; কোড পরিবর্তন সত্ত্বেও আপনি এবিআইয়ের সামঞ্জস্যতা বজায় রাখতে পারেন। আমার মনে হয় অনেকেরই সমস্যা নেই।
কেসি

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

8

ইতিমধ্যে উপস্থাপন যুক্তি ছাড়াও।

এটি প্রত্যাশিত ইন্টারফেস সরবরাহ করে না।

ব্যবহারকারীরা foo.getBar () এবং foo.setBar (মান) কল করতে চাইবে, foo.get ("বার") এবং foo.set ("বার", মান) কল করবে না

ইন্টারফেসটি সরবরাহ করার জন্য যা ব্যবহারকারীরা প্রত্যাশা করেন যে আপনার প্রতিটি সম্পত্তির জন্য একটি পৃথক গেটর / সেটার লিখতে হবে। একবার আপনি করেছেন যে প্রতিবিম্ব ব্যবহার করার কোন লাভ নেই।


আমার কাছে মনে হয় যে এই কারণটি অন্যান্য উত্তরের অন্যান্য সকলের চেয়ে গুরুত্বপূর্ণ।
এসবেন স্কোভ পেডারসেন

-4

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

সত্য হিসাবে কিছুই সঠিক বা ভুল নয়।

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