কোনও শ্রেণীর অনন্য দৃষ্টান্ত নিশ্চিত করার উপায়?


14

প্রদত্ত শ্রেণীর প্রতিটি উদাহরণ একটি স্বতন্ত্ররূপে চিহ্নিতযোগ্য উদাহরণ হিসাবে তা নিশ্চিত করার জন্য আমি বিভিন্ন উপায়ে সন্ধান করছি।

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

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

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

এটি অর্জনের অন্যান্য উপায় আছে?


1
আপনি একটি সিঙ্গলটন

5
আপনার প্রথমটির সাথে আরও ভালভাবে যাওয়া উচিত: - স্ট্যাটিক কারখানা
রোহিত জৈন

16
পছন্দ করেছেন তার একই শ্রেণীর অনেক উদাহরণ থাকতে পারে তবে এই দৃষ্টান্তগুলি অবশ্যই সনাক্তযোগ্য।

1
@ মার্কবি আমি সিঙ্গলটন প্যাটার্ন সম্পর্কে অবগত তবে আমি ভেবেছিলাম যে ক্লাসের কেবলমাত্র একটি উদাহরণ সম্ভব? আমি একাধিক উদাহরণ, বিভিন্ন মান চাই। দুঃখিত যদি প্রশ্নটি পরিষ্কার না করে থাকে সম্পাদনা: পোস্ট করার আগে কেবল প্রথম মন্তব্য দেখেছি।
চিনাবাদাম

2
I'm aware that one way of doing this is to have a static factory that holds a Map...তাহলে কেন আপনি এটি এভাবে করতে চান না?
হতাশ

উত্তর:


13

আসলে আপনি ইতিমধ্যে আপনার প্রশ্নের উত্তর দিয়েছেন। আপনার প্রথম উপায়টি এখানে আরও কার্যকর হওয়া উচিত। আপনি static factoryযেদিকেই constructorভাবতে পারেন তার চেয়ে ব্যবহার সর্বদা পছন্দনীয় । সুতরাং, আপনি Constructorএই ক্ষেত্রে ব্যবহারটি এড়াতে পারবেন , অন্যথায় throw some exceptionযদি কোনও উদাহরণ ইতিমধ্যে প্রদত্ত নামের সাথে উপস্থিত থাকে।

সুতরাং, আপনি একটি স্থিতিশীল কারখানার পদ্ধতি তৈরি করতে পারেন: - getInstanceWithName(name)যা এই নামের সাথে ইতিমধ্যে উপলব্ধ উদাহরণটি পাবেন এবং যদি এটি বিদ্যমান না থাকে তবে এটি একটি নতুন উদাহরণ তৈরি করবে এবং আপনার constructorব্যক্তিগত তৈরি করবে, এটি বেশিরভাগ ক্ষেত্রে যেমন কাজ করা উচিত তখনই করা উচিত static factories

এছাড়াও, তার জন্য আপনাকে একটি স্ট্যাটিক Listবা Mapআপনার Factoryক্লাসে তৈরি সমস্ত অনন্য দৃষ্টান্ত বজায় রাখতে হবে ।

সম্পাদনা : -

আপনার অবশ্যই অবশ্যই যেতে হবে - কার্যকর জাভা - আইটেম # 1: কনস্ট্রাক্টরগুলির উপর স্ট্যাটিক কারখানাগুলি বিবেচনা করুন । আপনি এই বইয়ের চেয়ে ভাল ব্যাখ্যা পেতে পারেন না।


1
এটি এমন কিছু যা ওপ ইতিমধ্যে ভেবেছিল।
বিগুরুং

লিঙ্কটির জন্য +1, যা ওপির কিছু উদ্বেগকে স্পষ্টভাবে সম্বোধন করে বলে মনে হচ্ছে।
রবার্ট হার্ভে

@RobertHarvey। হ্যাঁ এই বইয়ের মতো বেশিরভাগ বিষয়ের সেরা উত্স। এবং এটি আসলে প্রথম আইটেম। :)
রোহিত জৈন

কার্যকর জাভা জন্য +1, আমার কাছে এখন বইটি আছে, আমার ব্যাগটিতে এখন বসে আছে :) তবে স্থির কারখানা / স্থির পদ্ধতি এবং কনস্ট্রাক্টরের ব্যতিক্রম বাদে স্বতন্ত্রতা অর্জনের অন্যান্য উপায়গুলি সম্পর্কে আমি কেবল আগ্রহী ছিলাম । যদি কিছু না থাকে তবে আমি এটি গ্রহণ করব।
চিনাবাদাম

@চিনাবাদাম. অবশ্যই। আরও তথ্য পাওয়ার জন্য এটি খননের সর্বোত্তম উত্স।
রোহিত জৈন

5

কার্যকর জাভা উল্লেখ উল্লেখযোগ্যভাবে অনেক বিশ্বাসযোগ্যতা যোগ করে তাই এই উত্তরটি আঁকা:

  • কার্যকর জাভা আইটেম 8: ওভাররাইডিং সমান হলে সাধারণ চুক্তি মেনে চলুন
  • কার্যকর জাভা আইটেম 9: আপনি যখন সমান ওভাররাইড করবেন তখন সর্বদা হ্যাশকোডকে ওভাররাইড করুন
  • কার্যকর জাভা আইটেম 15: পরিবর্তনকে হ্রাস করুন

আমি একটি পদক্ষেপ ফিরে নেব এবং এই নাম অবজেক্টের একাধিক উদাহরণ থাকলে আপনি কেন যত্ন করছেন তা প্রশ্ন করব।

আমার এই জাতীয় অবজেক্ট পুলিং খুব কমই করা দরকার। আমার অনুমান যে ওপি এটি করছে তাই তারা কেবল তাদের Nameবস্তুর সাথে তুলনা করতে পারে ==। অথবা কী বা এর অনুরূপ Nameঅভ্যন্তরীণ অবজেক্টগুলি ব্যবহার করুন HashMap

যদি তাই হয় তবে এটি সঠিকভাবে প্রয়োগেরequals() মাধ্যমে সমাধান করা যেতে পারে ।

তাই ভালো:

public final class Name {
  private final String name;

  public Name(String name) {
    if (name == null) {
      name = ""; //or exception if you like
    }
    this.name = name;
  }

  public String getName() {
    return name;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Name)) {
      return false;
    }
    Name other = (Name) o;
    return other.name.equals(name);
  }

  @Override
  public int hashCode() {
    return name.hashCode();
  }
}

একবার হয়ে গেলে নিম্নলিখিতটি সত্য:

Name a = new Name("weston");
Name b = new Name("weston");
assert(a.equals(b)); //same but:
assert(a!=b); //not the same instance
//test out the Name instances in a hashmap:
HashMap<Name,Object> map = new HashMap<Name,Object>();
Object detailsIn = new Object();
map.put(a,detailsIn);
Object detailsOut = map.get(b);
assert(detailsIn==detailsOut); //the map returned the same details object
//even though we put with `a` and got with `b` thanks to our correct equals implementation

আমি আপনার লক্ষ্যটি অনুমান করছি, তবে আপনি এইভাবে Nameক্লাশটি হ্যাশ মানচিত্র ইত্যাদিতে ব্যবহার করতে পারেন এবং সেগুলি হুবহু একই উদাহরণ হতে হবে না


উদাহরণস্বরূপ, দয়া করে।
রবার্ট হার্ভে

@ রবার্টহার্ভে সঠিক প্রয়োগের উদাহরণ?
ওয়েস্টন

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

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

অনন্য অবজেক্টগুলির প্রয়োজনীয়তার একটি বৈধ কারণ হ'ল আপনি যদি মনিটরের হিসাবে অবজেক্টটি ব্যবহার করতে একটি সিঙ্ক্রোনাইজড ব্লক চান। দুটি বস্তু যা .মানু () একে অপরের কাজ করবে না।
লে মধ্যে Caldwell

3
  • মেক Nameএকটি ইন্টারফেস
  • একটি ইন্টারফেস তৈরি করুন NameFactoryএকটি পদ্ধতি সহ একটিName getByName(String)
  • এর একটি বাস্তবায়ন তৈরি করুন NameFactoryMap<String,WeakReference<Name>>এটি একটি অভ্যন্তর দিয়ে একটি
  • synchronize ভিতরে মানচিত্রে ভিতরে getByNameনতুন উদাহরণ তৈরির আগে পদ্ধতিরName
  • Ptionচ্ছিকভাবে, Nameআপনার প্রয়োগের অভ্যন্তরে ইন্টারফেসের একটি স্ট্যাটিক প্রাইভেট বাস্তবায়ন ব্যবহার করুনNameFactory

এই পদ্ধতি আপনাকে নিশ্চিত করতে দেয় যে:

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

ফ্যাক্টরি পদ্ধতিতে আপনার মেমরি ফাঁস হয় না, যদি আপনি throwকোনও বস্তু ফেরতের পরিবর্তে অভিন্ন নাম উপস্থিত থাকেন, বা আপনি কোনও nullবস্তু ফিরিয়ে দেন তবে ।
রবার্ট হার্ভে

@ রবার্টহারভে বলতে আমি বোঝাচ্ছি যে লিকগুলি আসলে ফাঁস নয়, তবে বৈধ অবজেক্টস (তথাকথিত "অন্তর্বাস")। একটি সাধারণ স্থিতিশীল মানচিত্রটি তার মান অবজেক্টগুলি প্রকাশ হতে বাধা দিতে পারে, অন্যদিকে দুর্বল উল্লেখগুলির মানচিত্রটি যতক্ষণ অন্য লাইভ রেফারেন্সগুলি অস্তিত্বশীল কেবল ততক্ষণ স্মৃতিতে ধরে রাখতে পারে।
dasblinkenlight

আহ, আমি কি বলতে চাইছি। এটি বিরল দৃষ্টান্তগুলির মধ্যে একটি destructorহতে পারে যেখানে কোনও কাজে লাগে।
রবার্ট হার্ভে

1
খুব জটিল। এটি @ ওয়েস্টন জবাবের মতো করা যায়, সমানকে ওভাররাইড করে এবং কারখানায় নাম সংগ্রহ করা যায়।
তুলাইনস কর্ডোভা

@ user1598390 কে যতটা সম্ভব জিনিস সহজ করা উচিত, তবে কোনও সহজ নয়। ওয়েস্টনের "সমাধান" ওপির সমস্যা সমাধান করে না (কোনও মানচিত্র নেই), এবং নাম সংগ্রহ একটি দীর্ঘস্থায়ী মেমরি ফাঁস তৈরি করে (হ্যাঁ, জাভাতে মেমরি ফাঁস রয়েছে)।
dasblinkenlight

1

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


প্রশ্নের তৃতীয় অনুচ্ছেদে আমি যা বলেছি তা আপনি পুনরাবৃত্তি করেছেন। আমি বিকল্প উপায় পরে ছিল।
চিনাবাদাম

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

1

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

class UniqueName
    {
        private string Name;
        public int ID;
        private static int Count=0;
        static List<UniqueName> lt=new List<UniqueName>();

        private UniqueName(string Name)
        {
            this.Name = Name;
            ID = ++Count;
        }

        public static UniqueName GetUniqueueInstance(string Name)
        {
            foreach (UniqueName un in lt)
            {
                if ( string.Compare( un.Name,Name,StringComparison.InvariantCultureIgnoreCase)==0)
                    return un;
            }

            UniqueName temp=new UniqueName(Name);
            lt.Add(temp);
            return temp;
        }
    }

এই জাভা না? আপনি কি ছদ্ম-কোড লিখেছেন? বা, অন্য কোন ভাষায়? দয়া করে এটি স্পষ্টভাবে নির্দিষ্ট করুন।
রোহিত জৈন

দেখে মনে হচ্ছে সি #। অক্ষয়, আপনি ছাড়া অন্য সংগ্রহ শিখতে হবে List। এই জন্য ভাল ফিট হবে Dictionary<string,UniqueName>
ওয়েস্টন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.