"স্ট্যাটিক ইন্টারফেস" একটি ভাল অনুশীলন?


13

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

আমি নিশ্চিত নই যে এটি বাস্তবিক ইন্টারফেসগুলিতে কার্যকর হবে any তবে এটি প্রোগ্রামারকে এমন ইন্টারফেস তৈরি করতে সক্ষম করে যা স্ট্যাটিক স্টাফের জন্য যেমন কেবল খাম, যেমন ইউটিলিটি ক্লাস।

একটি সাধারণ উদাহরণ গ্লোবাল ধ্রুবকগুলির জন্য কেবল একটি খাম। একটি শ্রেণীর তুলনায়, আপনি public static finalঅনুমান করা হয় যেমন এটি অনুপস্থিত বয়লারপ্লেটটি সহজেই লক্ষ্য করতে পারেন (এটি কম ভার্বোস তৈরি করে)।

public interface Constants {
    String LOG_MESSAGE_FAILURE = "I took an arrow to the knee.";
    int DEFAULT_TIMEOUT_MS = 30;
}

আপনি কনফিগার কীগুলির এই সিউডো-এনামের মতো আরও জটিল কিছু তৈরি করতে পারেন।

public interface ConfigKeys {
    static createValues(ConfigKey<?>... values) {
        return Collections.unmodifiableSet(new HashSet(Arrays.asList(values)));
    }

    static ConfigKey<T> key(Class<T> clazz) {
        return new ConfigKey<>(clazz);
    }

    class ConfigKey<T> {
        private final Class<T> type;
        private ConfigKey(Class<T> type) {
            this.type = type;
        }
        private Class<T> getType() {
            return type;
        }
    }
}

import static ConfigKeys.*;
public interface MyAppConfigKeys {
    ConfigKey<Boolean> TEST_MODE = key(Boolean.class);
    ConfigKey<String> COMPANY_NAME = key(String.class);

    Set<ConfigKey<?>> VALUES = createValues(TEST_MODE, COMPANY_VALUE);

    static values() {
        return VALUES;
    }
}

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

আমি এটিকে একটি দুর্দান্ত নতুন বৈশিষ্ট্য হিসাবে বিবেচনা করেছি এবং বিশেষত স্থির সদস্যদের উত্তরাধিকার সূত্রে প্রাপ্ত নয় এমন একটি আকর্ষণীয় ধারণা যা কেবলমাত্র ইন্টারফেসের সাথে পরিচিত হয়েছিল।

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

আমি এই দুটিগুলির মতো নিদর্শনগুলি ব্যবহার করার কারণগুলিতে (না) বেশি আগ্রহী।


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


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

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

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

অ্যালিস্টার, আপনি defaultপদ্ধতি সম্পর্কে কথা বলছেন । আমি staticপদ্ধতি এবং ক্ষেত্র সম্পর্কে কথা বলছি । এগুলি উত্তরাধিকার সূত্রে প্রাপ্ত নয়, সুতরাং তারা একাধিক উত্তরাধিকার ভেঙে না।
ভ্ল্যাস্যাক

উত্তর:


1

একটি সাধারণ উদাহরণ গ্লোবাল ধ্রুবকগুলির জন্য কেবল একটি খাম।

ইন্টারফেসে ধ্রুবক স্থাপন করা বলা হয় Constant Interface Antipatternকারণ ধ্রুবকগুলি প্রায়শই কেবল একটি বাস্তবায়ন বিশদ হয়। কনস্ট্যান্ট ইন্টারফেসের উইকিপিডিয়া নিবন্ধে আরও ত্রুটিগুলি সংক্ষিপ্ত করা হয়েছে ।

আপনি কিছু উপযোগ "শ্রেণি" এভাবে তৈরি করতে পারেন।

প্রকৃতপক্ষে জাভা ডকটি বলেছে যে স্থির পদ্ধতিগুলি সাহায্যকারী পদ্ধতিগুলি সংগঠিত করা সহজ করে তুলতে পারে, উদাহরণস্বরূপ যখন ডিফল্ট পদ্ধতিগুলি থেকে সহায়তাকারী পদ্ধতিগুলি কল করার সময়।


1
আমি মনে করি না যে এটি আসলে উত্থাপিত প্রশ্নের উত্তর কারণ আপনি এই নতুন কার্যকারিতা ছাড়াই এই দুটি জিনিসই করতে পারতেন।
এড্রিয়ান

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

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

1

প্রশ্নে বর্ণিত হিসাবে, ইন্টারফেসটি প্রয়োগ করা (বা তাত্ক্ষণিক) বোঝানো নয়। সুতরাং আমরা এটিকে এমন একটি শ্রেণীর সাথে তুলনা করতে পারি যার একটি ব্যক্তিগত নির্মাণকারী রয়েছে:

  • super()কল না করার সাথে শ্রেণিটি বাড়ানো যাবে না , তবে ইন্টারফেসটি "প্রয়োগ করা" যেতে পারে
  • প্রতিচ্ছবি ছাড়াই ক্লাসটি ইনস্ট্যান্ট করা যায় না, যখন ইন্টারফেসটি সহজেই বেনাম শ্রেণীর মতো তত সহজে ইনস্ট্যান্ট করা যায়: new MyInterface() {};

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

"স্থিতিশীল ইন্টারফেস" থেকে উত্তরাধিকার সম্পর্কে একটি অদ্ভুত জিনিস রয়েছে:

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

এগুলি একটি খারাপ প্যাটার্ন বিবেচনা করার এবং এই ক্ষেত্রে স্ট্যাটিক ক্লাস ব্যবহার চালিয়ে যাওয়ার কারণ হতে পারে। তবে সিনট্যাকটিক চিনির প্রতি আসক্ত ব্যক্তির জন্য এটি ডাউনসাইডগুলির সাথে এখনও লোভনীয় হতে পারে।


... যাইহোক, একটি দলের কোডিং সম্মেলনগুলি এই সমস্যাগুলিকে coverাকতে পারে। আমার কাছে, যদিও এটি প্রাইভেট কনস্ট্রাক্টরের ক্লাসের মতো প্রোগ্রামারের হাতকে প্রায় শক্ত করে বাঁধেনি, সেটারগুলির তুলনায় এটি এখনও কম ঝুঁকি বহন করে এবং সেটারগুলি প্রায়শই ব্যবহৃত হয়।
ভ্লাস্যাক

0

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

সম্ভবত আরও গুরুত্বপূর্ণ, এটি করার দরকার নেই। ব্যবহার করুন স্ট্যাটিক আমদানির পরিবর্তে এবং আপনি কি আমদানি করছি সম্পর্কে এবং কোথা থেকে স্পষ্ট হবে।


হ্যাঁ, স্থির আমদানি স্থিরদের উত্তরাধিকারের চেয়ে ভাল ধারণা হিসাবে শোনাচ্ছে এবং এটি কাজ করে যা উভয় শ্রেণি এবং ইন্টারফেসের স্থির সদস্যদের সাথে কাজ করে। এবং এটি কেবল শ্রেণি / ইন্টারফেসের মধ্যে দৃশ্যমান।
ভ্ল্যাকের

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

আমি ইন্টারফেসে ধ্রুবকগুলির মান দেখতে পারি। ইন্টারফেসগুলি পদ্ধতিগুলি এবং পদ্ধতিগুলি কখনও কখনও পরামিতি হিসাবে ধ্রুবকগুলি গ্রহণ করে বলে সংজ্ঞা দেয়। উদাহরণ: interface ColorFilter {Image applyGradient(int colorSpace, int width, byte[] pixels); }। আমি কল্পনা করতে পারি সেখানে হচ্ছে কিছু ভিন্ন ধ্রুবক RGB, RGBA, CMYK, GREYSCALE, INDEXEDইত্যাদি
Stijn De Witt

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

0

আমি বলব, আপনি কীভাবে নতুন বৈশিষ্ট্যটি সঠিকভাবে ব্যবহার করতে আগ্রহী হন, জেডিকে কোডটি একবার দেখুন। ইন্টারফেসে ডিফল্ট পদ্ধতিগুলি ব্যাপকভাবে ব্যবহৃত হয় এবং এটি সহজেই পাওয়া যায় তবে ইন্টারফেসে স্থির পদ্ধতিগুলি খুব অস্বাভাবিক বলে মনে হয়। কিছু উদাহরণ অন্তর্ভুক্ত java.time.chrono.Chronology, java.util.Comparator, java.util.Map, এবং বেশ কয়েক ইন্টারফেসগুলি java.util.functionএবং java.util.stream

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

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


-1

আমি অবাক হই যে এটি ব্যবহার না করার কারণ আছে কিনা?

পুরানো জেভিএমগুলির সাথে সামঞ্জস্যতা কেমন হবে?

আপনি সাধারণভাবে এটি একটি ভাল ধারণা বিবেচনা?

না। এটি একটি পিছনের-অসামঞ্জস্যপূর্ণ পরিবর্তন যা ভাষার অভিব্যক্তিতে জিলচ যুক্ত করে। দুই থাম্ব নিচে।

এমন কিছু মডেল পরিস্থিতি রয়েছে যেখানে আপনি ক্লাসের দৃ classes়ভাবে সুপারিশ করেন?

আমি প্রয়োগের বিবরণ ধারণ করতে ক্লাস ব্যবহার করার দৃ strongly়ভাবে পরামর্শ দিচ্ছি। একটি ইন্টারফেস বলতে আসলে "এই অবজেক্টটি এক্সওয়াইজেড অপারেশনগুলিকে সমর্থন করে" বলে বোঝানো হয় এবং ইন্টারফেসের ঘোষণার ক্ষেত্রে আপনি যে স্ট্যাটিক পদ্ধতিতে ভাবতে পারেন তার সাথে কোনও সম্পর্ক নেই। এই বৈশিষ্ট্যটি বিল্ট-ইন মিনি-ফ্রিজ সহ রিক্লাইনারের মতো। নিশ্চিতভাবে এর কিছু কুলুঙ্গি ব্যবহার রয়েছে তবে এটি মূলধারার প্রাপ্য হওয়ার পক্ষে পর্যাপ্ত ওজন ধরে না।

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


মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
ম্যাপেল_শ্যাফ্ট

আমি যদি আপনার প্রশ্নটিকে হ্রাস করে দিই, তবে আমি এটি করব কারণ আমাদের প্রথম দুটি উত্তর সত্য উত্তর নয়। ভাষার নতুন সংস্করণ জিনিসগুলি সহজ করে তুলতে নতুন সরঞ্জাম নিয়ে আসে, এটি এই নতুন সংস্করণগুলির একমাত্র উদ্দেশ্য। তৃতীয় উত্তরটি কিন্ডা প্রথম দুটি জঞ্জালের ধ্বংসস্তূপে হারিয়ে গেছে।
Vlasec
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.