এনাম (জাভাতে) দিয়ে সিঙ্গেলটন প্রয়োগ করছে


178

আমি পড়েছি যে Singletonজাভাতে Enumযেমন ব্যবহার করে এটি প্রয়োগ করা সম্ভব :

public enum MySingleton {
     INSTANCE;   
}

কিন্তু, উপরের কাজটি কীভাবে হয়? বিশেষত, একটি Objectতাত্ক্ষণিক করা উচিত। এখানে কীভাবে MySingletonতাত্পর্য করা হচ্ছে? কে করছে new MySingleton()?


24
কে নতুন মাইসিংটন করছেন () জেভিএম হ'ল।
সোটিরিওস ডেলিমনোলিস

37
INSTANCEহিসাবে একই public static final MySingleton INSTANCE = new MySingleton();
Pshemo

6
ENUM - একটি গ্যারান্টিযুক্ত সিঙ্গলটন।
বাগ নেই

Dzone.com/articles/java-singletons- using-enum পড়ুন , কেন এনাম ব্যবহার করবেন এবং অন্যান্য পদ্ধতিগুলি নয়। সংক্ষিপ্ত: সিরিয়ালাইজেশন এবং প্রতিবিম্ব ব্যবহার করার সময় সমস্যা শুরু হয়।
মিয়াগি

উত্তর:


203

এই,

public enum MySingleton {
  INSTANCE;   
}

একটি অন্তর্নিহিত খালি নির্মাণকারী আছে। পরিবর্তে এটি স্পষ্ট করুন,

public enum MySingleton {
    INSTANCE;
    private MySingleton() {
        System.out.println("Here");
    }
}

এরপরে যদি আপনি অন্য main()পদ্ধতির মতো একটি পদ্ধতি যুক্ত করেন

public static void main(String[] args) {
    System.out.println(MySingleton.INSTANCE);
}

আপনি দেখতে পাবেন

Here
INSTANCE

enumক্ষেত্রগুলি সময় স্থিরকারীগুলি সংকলন করে তবে সেগুলি তাদের enumধরণের উদাহরণ । এবং যখন এনাম টাইপটি প্রথমবারের জন্য উল্লেখ করা হয় তখন সেগুলি তৈরি করা হয় ।


13
আপনার যুক্ত করা উচিত যে ডিফল্টভাবে এনামগুলিতে নিখুঁত প্রাইভেট কনস্ট্রাক্টর থাকে এবং স্পষ্টভাবে একটি প্রাইভেট কনস্ট্রাক্টর যুক্ত করার প্রয়োজন নেই যদি না আপনার কাছে সেই কনস্ট্রাক্টরে চালানোর দরকারের কোড না থাকে
নিমরোদ দয়ান

প্রতিটি এনাম ক্ষেত্র একবারে একটি দৃষ্টান্ত তৈরি করে, তাই প্রাইভেট কনস্ট্রাক্টর তৈরি করার দরকার নেই।
প্রবত পান্ডা

2
মাইসিংলেটন {ইনস্ট্যান্স, ইনস্ট্যান্স ১; } এবং তারপরে System.out.println (MySingleton.INSTANCE.hashCode ()); System.out.println (MySingleton.INSTANCE1.hashCode ()); এটি বিভিন্ন হ্যাশকোডগুলি প্রিন্ট করে। এর অর্থ কী মাইসিংলেটনের দুটি বস্তু তৈরি হয়েছে?
স্কট মাইল

@ স্কটমাইলস হ্যাঁ কারণ আপনার দুটি উদাহরণ রয়েছে। সংজ্ঞা অনুসারে একটি সিঙ্গলটন রয়েছে।
এলিয়ট ফ্রিশ্চ

privateপরিবর্তক একটি জন্য কোন অর্থ enumকন্সট্রাকটর এবং সম্পূর্ণরূপে অপ্রয়োজনীয়।
দিমিত্রি নেস্টারুক

76

একটি enumটাইপ একটি বিশেষ ধরণের class

আপনার enumউইলটি আসলে এরকম কিছুতে সংকলিত হয়েছে

public final class MySingleton {
    public final static MySingleton INSTANCE = new MySingleton();
    private MySingleton(){} 
}

যখন আপনার কোডটি প্রথম অ্যাক্সেস করে INSTANCE, ক্লাসটি MySingletonJVM দ্বারা লোড করা এবং আরম্ভ করা হবে। এই প্রক্রিয়াটি একবারে (অলসভাবে) staticউপরের ক্ষেত্রটি আরম্ভ করে ।


এই ক্লাসে কি প্রাইভেট কনস্ট্রাক্টর () থাকতে পারে? আমার মনে হয় এটি হবে
ইয়াসির শাব্বির চৌধুরী

public enum MySingleton { INSTANCE,INSTANCE1; }এবং তারপরে System.out.println(MySingleton.INSTANCE.hashCode()); System.out.println(MySingleton.INSTANCE1.hashCode());এটি বিভিন্ন হ্যাশকোডগুলি প্রিন্ট করে। এর অর্থ কী মাইসিংলেটনের দুটি বস্তু তৈরি হয়েছে?
স্কট মাইল 17

2
@ স্কটমাইলস হ্যাঁ, এটি কেবলমাত্র দুটি পার্থক্যযুক্ত enumস্থির।
সোটিরিওস ডেলিমনোলিস

2
@ ক্যাফ, নিশ্চিত এখানে দেখুন: docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3
সোটিরিওস ডেলিমনলিস

@ সোরিরিওসডেলিমনোলিস, এনাম থ্রেডযুক্ত এই পদ্ধতিটি কি নিরাপদ?
abg

63

জোশুয়া ব্লচের এই জাভা সেরা অনুশীলনের বইয়ে , আপনি ব্যাখ্যা করতে পারেন যে আপনি কেন একটি বেসরকারী কনস্ট্রাক্টর বা এনাম টাইপের সাহায্যে সিঙ্গলটন সম্পত্তি প্রয়োগ করবেন। অধ্যায়টি বেশ দীর্ঘ, সুতরাং এটি সংক্ষিপ্ত রেখে:

একটি ক্লাস তৈরি করে সিঙ্গলটন তার ক্লায়েন্টদের পরীক্ষা করা কঠিন করে তুলতে পারে, কারণ এটি যদি কোনও ইন্টারফেস প্রয়োগ না করে তবেই সিঙ্গলটনের জন্য মক বাস্তবায়ন করা অসম্ভব। প্রস্তাবিত পদ্ধতিটি সিগলেটগুলি বাস্তবায়িত করে কেবল একটি উপাদান দিয়ে একটি এনাম টাইপ করে:

// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}

এই পদ্ধতির কার্যক্ষমতা জনসাধারণের ক্ষেত্রের পদ্ধতির সমতুল্য, এটি আরও সংক্ষিপ্ততর ব্যতীত, সিরিয়ালাইজেশন যন্ত্রপাতি বিনামূল্যে সরবরাহ করে এবং পরিশীলিত সিরিয়ালাইজেশন বা প্রতিবিম্বের আক্রমণগুলির মধ্যেও একাধিক তাত্পর্য বিরুদ্ধে আইরনক্ল্যাড গ্যারান্টি সরবরাহ করে।

যদিও এই পদ্ধতির এখনও ব্যাপকভাবে গ্রহণ করা সম্ভব হয়নি, তবে একটি একক উপাদান এনাম প্রকারটি সিঙ্গলটন বাস্তবায়নের সর্বোত্তম উপায়।


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

9

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

স্থির সূচনা করার সময় উদাহরণগুলি তৈরি করা হয়, যা জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন, বিভাগ 12.4-এ সংজ্ঞায়িত হয়েছে ।

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


6

যেহেতু সিঙ্গেলন প্যাটার্নটি একটি প্রাইভেট কনস্ট্রাক্টর রয়েছে এবং getInstanceএনামগুলিতে ইনস্ট্যান্টেশনগুলি নিয়ন্ত্রণ করার জন্য কিছু পদ্ধতি কল করার (যেমন কিছু ), ইতিমধ্যে আমাদের একটি অন্তর্ভুক্ত প্রাইভেট কনস্ট্রাক্টর রয়েছে।

আমি ঠিক জানি না কীভাবে জেভিএম বা কিছু ধারক আমাদের দৃষ্টান্তগুলি নিয়ন্ত্রণ করে Enums, তবে মনে হয় এটি ইতিমধ্যে একটি অন্তর্নিহিত ব্যবহার করেছে Singleton Pattern, পার্থক্যটি আমরা একটি কল করি না getInstance, আমরা কেবল এনামকে কল করি।


3

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

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

public enum MySingleton {
    INSTANCE;

    public void doSomething() { ... }

    public synchronized String getSomething() { return something; }

    private String something;
}

আপনি এই লাইন বরাবর একক এর পদ্ধতি অ্যাক্সেস:

MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();

ক্লাসের পরিবর্তে এনামের ব্যবহার হ'ল অন্যান্য জবাবগুলিতে যেমন উল্লেখ করা হয়েছে, বেশিরভাগ ক্ষেত্রে সিঙ্গলটনের থ্রেড-সেফ ইনস্ট্যান্টেশন এবং গ্যারান্টি যে এটি সর্বদা কেবল একটি অনুলিপি থাকবে।

এবং, সম্ভবত, সবচেয়ে গুরুত্বপূর্ণ, এই আচরণটি নিজেই জেভিএম এবং জাভা স্পেসিফিকেশন দ্বারা গ্যারান্টিযুক্ত।

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

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

লক্ষণীয় যে তাত্ক্ষণিকতার পরে কোনও থ্রেড-সুরক্ষা সংক্রান্ত উদ্বেগগুলি সিঙ্ক্রোনাইজড কীওয়ার্ড ইত্যাদির সাথে অন্য কোনও শ্রেণীর মতো হ্যান্ডেল করতে হবে etc.

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