অর্থপূর্ণ শ্রেণীর নাম সহ জাভা সংগ্রহগুলি মাস্ক করার জন্য ভাল বা খারাপ অনুশীলন?


46

ইদানীং আমি মানব-বান্ধব শ্রেণীর নাম সহ জাভা সংগ্রহগুলি "মাস্কিং" করার অভ্যাসে এসেছি। কয়েকটি সহজ উদাহরণ:

// Facade class that makes code more readable and understandable.
public class WidgetCache extends Map<String, Widget> {
}

বা:

// If you saw a ArrayList<ArrayList<?>> being passed around in the code, would you
// run away screaming, or would you actually understand what it is and what
// it represents?
public class Changelist extends ArrayList<ArrayList<SomePOJO>> {
}

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


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

ChangeListসংকলনটি বিরতিতে হবে extends, কারণ তালিকাটি একটি ইন্টারফেস, প্রয়োজন implements। @randomA কি তুমি কল্পী এই ত্রুটির কারণে বিন্দু ব্যার্থ
মশা

@gnat এটি পয়েন্টটি মিস করছে না, আমি ধরে নিচ্ছি যে তিনি একটি implementationঅর্থাত্ প্রসারিত করছিলেন HashMapবা তার কাছে যা TreeMapছিল সেখানে একটি টাইপো ছিল।
অবহিত

4
এটি একটি বিএডি অনুশীলন। খারাপ খারাপ খারাপ. এটি করবেন না। মানচিত্র <স্ট্রিং, উইজেট> কী তা সকলেই জানেন। তবে একটি উইজেটক্যাচ? এখন আমাকে উইজেটক্যাচ.জাভা খোলার দরকার আছে, আমার মনে রাখা দরকার যে উইজেটক্যাচ কেবল একটি মানচিত্র। আমি যখনই নতুন সংস্করণ প্রকাশ করি তখনই আমাকে যাচাই করতে হবে যে আপনি উইজেটক্যাচে নতুন কিছু যোগ করেন নি। Godশ্বর না, এই কখনও করবেন না।
মাইলস রাউট

"আপনি যদি কোনও অ্যারেলিস্ট <অ্যারেলিস্ট <? >> কোডের চারপাশে পাস করতে দেখেন তবে আপনি কি চিৎকার করে পালিয়ে যাবেন?।?" না, নেস্টেড জেনেরিক সংগ্রহগুলি নিয়ে আমি বেশ আরামদায়ক। এবং আপনারও হওয়া উচিত।
কেভিন ক্রামউইদে

উত্তর:


75

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

কিছু কোড ওভারহেড আছে। আপনার বেস বেসটি যা চান তা থেকে সমস্ত কনস্ট্রাক্টর তৈরি করতে হবে, তাদের পরামিতিগুলি ফরওয়ার্ড করে।

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

তদুপরি, সংগ্রহের ক্ষেত্রে, প্যাটার্নটি কেবল ইন্টারফেস ব্যবহারের সাধারণ নিয়মের সাথে একত্রে কাজ করে না, বাস্তবায়ন করে না - অর্থাৎ, সরল সংগ্রহের কোডে আপনি একটি তৈরি করতে পারেন HashMap<String, Widget>এবং তারপরে এটিকে পরিবর্তনশীল আকারে নির্ধারণ করতে পারেন Map<String, Widget>। আপনার WidgetCacheপ্রসারিত হতে পারে না Map<String, Widget>, কারণ এটি একটি ইন্টারফেস। এটি কোনও ইন্টারফেস হতে পারে না যা বেস ইন্টারফেসকে প্রসারিত করে, কারণ HashMap<String, Widget>সেই ইন্টারফেসটি কার্যকর করে না এবং অন্য কোনও মানক সংগ্রহও করে না। এবং যখন আপনি এটিকে প্রসারিত একটি শ্রেণি তৈরি করতে পারেন HashMap<String, Widget>, তখন আপনাকে ভেরিয়েবলগুলি হিসাবে WidgetCacheবা হিসাবে ঘোষণা করতে হবে Map<String, Widget>এবং প্রথমটি আপনাকে আলাদা সংগ্রহ (সম্ভবত কিছু ওআরএমের অলস লোডিং সংগ্রহ) প্রতিস্থাপনের নমনীয়তা হারাবে, যখন দ্বিতীয় ধরণের বিন্দুটি পরাজিত করে ক্লাস থাকার।

এর কিছু প্রতিরূপ আমার প্রস্তাবিত বিশেষায়িত শ্রেণিতেও প্রযোজ্য।

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


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

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

16
+1 "" কেবল নতুন নামকরণের উদ্দেশ্যে বেস ক্লাসটি তৈরি করে এমন একটি ক্লাস তৈরি করার পরিবর্তে আপনি কীভাবে সংগ্রহ সহ একটি ক্লাস তৈরি করেন এবং কেস-সুনির্দিষ্ট, উন্নত ইন্টারফেসের প্রস্তাব দেন? "
ব্যবহারকারী 11153

6
প্রাকটিক্যাল উদাহরণ এই উত্তরটি প্রধান বিন্দু ব্যাখ্যা: ডকুমেন্টেশন জন্য public class Properties extends Hashtable<Object,Object>java.utilবলে "hashtable, করা এবং putAll পদ্ধতি থেকে প্রোপার্টি উত্তরাধিকারী একটি প্রোপার্টি বস্তুর প্রয়োগ করা যেতে পারে কারণ তাদের ব্যবহার জোরালোভাবে নিরুৎসাহিত করা হয় হিসাবে তারা আহ্বানকারী এন্ট্রি যার চাবি ঢুকিয়ে করার অনুমতি দেয়। বা মানগুলি স্ট্রিং নয়। সংমিশ্রণটি অনেক পরিষ্কার হত।
প্যাট্রিসিয়া শানাহান

3
@ ডকব্রাউন না, এই উত্তরে দাবি করা হয়েছে যে কার্য সম্পাদনের কোনও প্রভাব নেই। আপনি যদি দৃ strong় বক্তব্য দেন তবে আপনি তাদের সমর্থন করতে আরও সক্ষম হবেন, অন্যথায় লোকেরা সম্ভবত আপনাকে এটিকে ডাকবে। মন্তব্যের পুরো বক্তব্য (উত্তরে) হ'ল ভুল তথ্য বা অনুমানগুলি নির্দেশ করা বা দরকারী নোটগুলি যুক্ত করা, তবে অবশ্যই মানুষকে অভিনন্দন জানানো নয়, এটিই ভোটদানের ব্যবস্থা।
ভু

25

আইবিএমের মতে এটি আসলে একটি অ্যান্টি-প্যাটার্ন। ক্লাসের মতো এই 'টাইপিডেফ' কে স্যুইডো টাইপ বলা হয়।

নিবন্ধটি আমার থেকে অনেক ভাল ব্যাখ্যা করেছে তবে লিঙ্কটি নীচে নেমে গেলে আমি সংক্ষিপ্ত করার চেষ্টা করব:

  • এমন কোনও কোড যা প্রত্যাশা করে একটি WidgetCacheহ্যান্ডেল করতে পারে নাMap<String, Widget>
  • এই সিউডোটাইপগুলি 'ভাইরাল' যখন একাধিক প্যাকেজ ব্যবহার করে তারা বেমানানদের দিকে নিয়ে যায় যখন বেস টাইপ (কেবল একটি নির্বোধ মানচিত্র <...>) সমস্ত প্যাকেজে সমস্ত ক্ষেত্রে কাজ করে।
  • সিউডোর ধরণগুলি প্রায়শই কংক্রিটের জন্য থাকে, তারা নির্দিষ্ট ইন্টারফেস প্রয়োগ করে না কারণ তাদের বেস ক্লাসগুলি কেবল জেনেরিক সংস্করণ প্রয়োগ করে।

নিবন্ধে তারা ছদ্ম প্রকার ব্যবহার না করে জীবনকে আরও সহজ করার জন্য নিম্নলিখিত কৌশলটি প্রস্তাব করেছেন:

public static <K,V> Map<K,V> newHashMap() {
    return new HashMap<K,V>(); 
}

Map<Socket, Future<String>> socketOwner = Util.newHashMap();

যা স্বয়ংক্রিয় প্রকারের অনুক্রমের কারণে কাজ করে।

(আমি এই সম্পর্কিত স্ট্যাক ওভারফ্লো প্রশ্নের মাধ্যমে এই উত্তরে এসেছি )


13
newHashMapহীরা অপারেটর দ্বারা এখন কি সমাধানের প্রয়োজন নেই ?
সুইভ

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

আমি আশা করি যে ভাষাগুলি অন্যান্য ধরণের উদাহরণগুলির জন্য উল্লেখযোগ্য বৈকল্পিক ধরণের একটি মহাবিশ্বের জন্য অনুমতি দেয় তবে তারা এখনও সংকলন-সময় যাচাইকরণকে সমর্থন করতে পারে, যেমন প্রকারের মান একটি ধরণের WidgetCacheপরিবর্তনশীল WidgetCacheবা Map<String,Widget>aালাই ছাড়াই নির্ধারিত হতে পারে তবে সেখানে রয়েছে একটি উপায় ছিল যার মাধ্যমে একটি স্থিতিশীল পদ্ধতি WidgetCacheকোনও রেফারেন্স নিতে পারে Map<String,Widget>এবং WidgetCacheকোনও পছন্দসই বৈধতা সম্পাদন করার পরে এটিকে টাইপ হিসাবে ফিরিয়ে দিতে পারে । এই জাতীয় বৈশিষ্ট্য জেনারিকদের সাথে বিশেষত কার্যকর হতে পারে, যা টাইপ-মুছতে হবে না (যেহেতু ...
সুপারক্যাট

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

5
জাভা কেন টাইপ অ্যালিয়াসের প্রয়োজন তা এটি একটি দুর্দান্ত যুক্তি।
গ্লেনপিটারসন

13

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

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

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


কনস্ট্রাক্টরগুলিতে একটি মিনিস্কুল ওভারহেডও রয়েছে।
স্টিফেন সি

11

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

আপনি বর্ণিত অনুরূপ সমস্যার সমাধান সহ আমার কোডবেস থেকে ক্লাসের উদাহরণ:

public class Translations {

    private Map<Locale, Properties> translations = new HashMap<>();

    public void appendMessage(Locale locale, String code, String message) {
        /* code */
    }

    public void addMessages(Locale locale, Properties messages) {
        /* code */
    }

    public String getMessage(Locale locale, String code) {
        /* code */
    }

    public boolean localeExists(Locale locale) {
        /* code */
    }
}

আপনি দেখতে পাচ্ছেন যে অভ্যন্তরীণভাবে এটি "কেবল একটি মানচিত্র", তবে পাবলিক ইন্টারফেস এটি দেখায় না। এবং এর মধ্যে "প্রোগ্রামার-বান্ধব" পদ্ধতি রয়েছে যেমন appendMessage(Locale locale, String code, String message)নতুন এন্ট্রি সন্নিবেশ করার সহজ এবং আরও অর্থপূর্ণ উপায় way এবং শ্রেণীর ব্যবহারকারীরা উদাহরণস্বরূপ, করতে পারবেন না translations.clear()কারণ Translationsপ্রসারিত হচ্ছে না Map

Allyচ্ছিকভাবে, আপনি অভ্যন্তরীণভাবে ব্যবহৃত মানচিত্রে প্রয়োজনীয় কিছু পদ্ধতি সর্বদা অর্পণ করতে পারেন।


6

আমি এটি একটি অর্থবহ বিমূর্তির উদাহরণ হিসাবে দেখছি। একটি ভাল বিমূর্ততা কয়েক বৈশিষ্ট আছে:

  1. এটি প্রয়োগের বিশদটি গোপন করে যা এটি ব্যবহারের কোডের সাথে সম্পর্কিত নয়।

  2. এটি যতটা জটিল হওয়া দরকার ততটাই জটিল।

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

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


4

অন্যান্য উত্তরগুলি এখানে +1 করুন। আমি এও যুক্ত করব যে এটি ডোমেন ড্রাইভন ডিজাইন (ডিডিডি) সম্প্রদায়টি আসলে খুব ভাল অনুশীলন বলে মনে করে। তারা সমর্থন করে যে আপনার ডোমেন এবং এটির সাথে মিথস্ক্রিয়াটির অর্থ অন্তর্ভুক্ত ডেটা কাঠামোর বিপরীতে অর্থপূর্ণ ডোমেন হওয়া উচিত। এ Map<String, Widget>ক্যাশে হতে পারে তবে এটি অন্যরকম কিছু হতেও পারে, আপনি মাই নট সো হাম্বল মতামত (আইএমএনএসএইচও) -তে সঠিকভাবে যা করেছেন তা সংগ্রহটি কী উপস্থাপন করে তা মডেল করা, এক্ষেত্রে ক্যাশে।

আমি একটি গুরুত্বপূর্ণ সম্পাদনা যুক্ত করব যে অন্তর্নিহিত ডেটা কাঠামোর চারপাশে ডোমেন শ্রেণির মোড়কের সম্ভবত অন্যান্য সদস্যের ভেরিয়েবল বা ফাংশন থাকতে হবে যা সত্যিকার অর্থে এটি কেবলমাত্র একটি ডেটা কাঠামোর বিপরীতে ইন্টারঅ্যাকশন সহ একটি ডোমেন শ্রেণিতে পরিণত করে (যদি কেবল জাভাতে মান ধরণের থাকে) , আমরা তাদের জাভা 10-এ পেয়ে যাব - প্রতিশ্রুতি!)

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

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