ভাল না খারাপ অনুশীলন? গেটরে বস্তুর সূচনা করা হচ্ছে


167

আমার এক অদ্ভুত অভ্যাস আছে বলে মনে হচ্ছে ... কমপক্ষে আমার সহকর্মীর মতে। আমরা একসাথে একটি ছোট প্রকল্পে কাজ করছি। আমি ক্লাসগুলি যেভাবে লিখেছি তা হ'ল (সরল উদাহরণ):

[Serializable()]
public class Foo
{
    public Foo()
    { }

    private Bar _bar;

    public Bar Bar
    {
        get
        {
            if (_bar == null)
                _bar = new Bar();

            return _bar;
        }
        set { _bar = value; }
    }
}

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

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

এই অভ্যাসের বিরুদ্ধে কি ব্যক্তিগত পছন্দ ব্যতীত কোনও আপত্তি আছে?

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

কনস:

  • থ্রেড সুরক্ষার সমস্যা
  • পাস করা মান শূন্য হলে কোনও "সেটার" অনুরোধ মানা হচ্ছে না
  • মাইক্রো-অপ্টিমাইজেশন
  • ব্যতিক্রম হ্যান্ডলিংটি কোনও কনস্ট্রাক্টরে স্থান নেওয়া উচিত
  • ক্লাস 'কোড নাল জন্য পরীক্ষা করা প্রয়োজন

পেশাদাররা:

  • মাইক্রো-অপ্টিমাইজেশন
  • সম্পত্তিগুলি কখনই শূন্য হয় না
  • "ভারী" জিনিসগুলি লোড করতে বা বিলম্ব করুন avoid

বেশিরভাগ কনস আমার বর্তমান লাইব্রেরিতে প্রযোজ্য নয়, তবে "মাইক্রো-অপ্টিমাইজেশন" আসলে কিছু আদৌ অনুকূলিত করছে কিনা তা পরীক্ষা করে দেখতে হবে।

সর্বশেষ আপডেট:

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


14
এটি অলস-লোড প্যাটার্ন, এটি আপনাকে এখানে একটি দুর্দান্ত সুবিধা দেয় না তবে এটি এখনও একটি ভাল জিনিস im
মেশিনারিয়াস

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


7
@ পিএলবি এটি কোনও একক প্যাটার্ন নয়।
কলিন ম্যাকেয়ে

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

উত্তর:


170

আপনার এখানে যা আছে তা হ'ল - নিষ্প্রভ - "অলস সূচনা" এর বাস্তবায়ন implementation

সংক্ষিপ্ত উত্তর:

নিঃশর্ত অলস সূচনা ব্যবহার করা ভাল ধারণা নয়। এর জায়গাগুলি রয়েছে তবে এই সমাধানটির যে প্রভাব রয়েছে তা বিবেচনা করতে হবে।

পটভূমি এবং ব্যাখ্যা:

কংক্রিট বাস্তবায়ন:
আসুন প্রথমে আপনার কংক্রিটের নমুনাটি দেখুন এবং কেন আমি এর বাস্তবায়ন নিষ্পাপ বিবেচনা করি:

  1. এটি ন্যূনতম আশ্চর্যের নীতি লঙ্ঘন করে (পিওএলএস) । যখন কোনও সম্পত্তিকে একটি মান বরাদ্দ করা হয়, তখন প্রত্যাশা করা হয় যে এই মানটি ফিরে এসেছে। আপনার প্রয়োগে এটি ক্ষেত্রে হয় না null:

    foo.Bar = null;
    Assert.Null(foo.Bar); // This will fail
    
  2. এটি বেশ কয়েকটি থ্রেডিংয়ের সমস্যা উপস্থাপন করে: foo.Barবিভিন্ন থ্রেডে দু'জন কলার সম্ভাব্যভাবে দুটি পৃথক দৃষ্টান্ত পেতে পারে Barএবং তার মধ্যে একটি Fooউদাহরণের সাথে সংযোগ ছাড়াই হবে । এই Barদৃষ্টান্তে করা কোনও পরিবর্তন নিঃশব্দে হারিয়ে যায়।
    এটি পিওএলএস লঙ্ঘনের আরেকটি মামলা। যখন কোনও সম্পত্তির কেবল সঞ্চিত মান অ্যাক্সেস করা হয় তখন এটি থ্রেড-নিরাপদ হবে বলে আশা করা যায়। যখন আপনি তর্ক করতে পারেন যে ক্লাসটি কেবল থ্রেড-নিরাপদ নয় - আপনার সম্পত্তি প্রাপ্তি সহ - আপনাকে সাধারণভাবে এটি ডকুমেন্ট করতে হবে কারণ এটি সাধারণ ঘটনা নয় that's তবুও এই সমস্যাটির ভূমিকা অপ্রয়োজনীয় কারণ আমরা শীঘ্রই দেখব।

সাধারণভাবে:
এখন সাধারণভাবে অলস সূচনাটি দেখার সময় হয়েছে:
অলস সূচনাটি সাধারণত এমন অবজেক্টগুলির নির্মাণে বিলম্ব করতে ব্যবহৃত হয় যা নির্মাণে দীর্ঘ সময় নেয় বা সম্পূর্ণরূপে নির্মাণের পরে অনেক স্মৃতি লাগে
অলস প্রারম্ভিককরণ ব্যবহারের জন্য এটি একটি খুব বৈধ কারণ।

তবে, এই ধরণের বৈশিষ্ট্যগুলিতে সাধারণত সেটটার থাকে না, যা উপরে উল্লিখিত প্রথম ইস্যু থেকে মুক্তি পায়।
তদ্ব্যতীত, Lazy<T>দ্বিতীয় সমস্যাটি এড়ানোর জন্য একটি থ্রেড-নিরাপদ বাস্তবায়ন ব্যবহৃত হবে - যেমন -।

এমনকি অলস সম্পত্তি বাস্তবায়নের ক্ষেত্রে এই দুটি বিষয় বিবেচনা করার পরেও নিম্নলিখিত পয়েন্টগুলি এই ধরণের সাধারণ সমস্যা:

  1. বস্তুটির নির্মাণ ব্যর্থ হতে পারে, ফলস্বরূপ কোনও সম্পত্তি প্রাপ্তির ব্যতিক্রম। এটি POLS এর অন্য একটি লঙ্ঘন এবং তাই এড়ানো উচিত। এমনকি "ক্লাস লাইব্রেরিগুলির বিকাশের জন্য ডিজাইন গাইডলাইনস" এর বৈশিষ্ট্যগুলির বিভাগটিও স্পষ্টভাবে বলেছে যে সম্পত্তি প্রাপ্তদের ব্যতিক্রমগুলি ছোঁড়া উচিত নয়:

    সম্পত্তি প্রাপ্তদের থেকে ব্যতিক্রম ছোঁড়া এড়িয়ে চলুন।

    সম্পত্তি প্রাপ্তিরা কোনও পূর্বশর্ত ছাড়াই সাধারণ ক্রিয়াকলাপ হওয়া উচিত। যদি কোনও গ্রাহক কোনও ব্যতিক্রম ছুঁড়ে ফেলতে পারে তবে সম্পত্তিটিকে পুনরায় নকশাকে একটি পদ্ধতি হিসাবে বিবেচনা করুন।

  2. সংকলক দ্বারা স্বয়ংক্রিয় অপ্টিমাইজেশানগুলি আহত হয়, যথা ইনলাইনিং এবং শাখার পূর্বাভাস। বিস্তারিত ব্যাখ্যার জন্য দয়া করে বিল কে এর উত্তর দেখুন

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

এই প্যাটার্নটির নিজস্ব জায়গা রয়েছে, তবে ক্লাসগুলি প্রয়োগ করার সময় এটি কোনও সাধারণ সেরা অনুশীলন নয়। উপরোক্ত কারণগুলির কারণে এটি নিঃশর্ত ব্যবহার করা উচিত নয়


এই বিভাগে আমি শর্তহীনভাবে অলস সূচনাটি ব্যবহারের পক্ষে যুক্তি হিসাবে অন্যরা যে বিষয়গুলি নিয়ে এসেছিল সেগুলি নিয়ে কিছু আলোচনা করতে চাই:

  1. সিরিয়ালাইজেশন:
    এরিকজে এক মন্তব্যে বলেছেন:

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

    এই যুক্তি নিয়ে বেশ কয়েকটি সমস্যা রয়েছে:

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

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

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

4
@ জন উইলেমস: এটি আপনার আর্কিটেকচারের সমস্যা। আপনার ক্লাসগুলি এমনভাবে করা উচিত যাতে তারা আরও ছোট এবং আরও বেশি কেন্দ্রীভূত হয়। 5 টি আলাদা জিনিস / কাজের জন্য একটি শ্রেণি তৈরি করবেন না। পরিবর্তে 5 ক্লাস তৈরি করুন।
ড্যানিয়েল হিলগারথ

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

2
+1, এটি 95% শ্রেণীর জন্য একটি ভাল নকশা পছন্দ নয়। অলস সূচনাটির উপকার রয়েছে তবে সমস্ত বৈশিষ্ট্যের জন্য সাধারণ করা উচিত নয়। এটি জটিলতা যুক্ত করে, কোডটি পড়তে অসুবিধা, থ্রেড সুরক্ষা সমস্যাগুলি ... 99% ক্ষেত্রে কোনও উপলব্ধিযোগ্য অনুকূলতার জন্য নয়। সলিউশন যোগী যেমন একটি মন্তব্য হিসাবে বলেছিলেন, ওপির কোডটি বগি, যা প্রমাণ করে যে এই প্যাটার্নটি প্রয়োগ করা তুচ্ছ নয় এবং অলস সূচনাটির প্রয়োজন না হলে এড়ানো উচিত avoided
ken2k

2
@ ড্যানিয়েলহিলগার্থ এই নিদটিকে নিঃশর্ত ব্যবহার করে সমস্ত কিছু লিখে (প্রায়) ভুল করার জন্য ধন্যবাদ। দারূন কাজ!
অ্যালেক্স

1
@ ড্যানিয়েলহিলগার্থ আচ্ছা হ্যাঁ এবং না। লঙ্ঘন এখানে সমস্যা তাই হ্যাঁ। তবে 'না' কারণ পলস হ'ল এই নীতিটি হ'ল আপনি সম্ভবত কোড দ্বারা অবাক হবেন না । যদি ফু আপনার প্রোগ্রামের বাইরে প্রকাশ না করা হয়, তবে এটি ঝুঁকিপূর্ণ আপনি নিতে বা নিতে পারেন না। এই ক্ষেত্রে, আমি প্রায় গ্যারান্টি দিতে পারি যে আপনি অবশেষে অবাক হয়ে যাবেন , কারণ সম্পত্তিগুলি যেভাবে অ্যাক্সেস করা হয় তা আপনি নিয়ন্ত্রণ করেন না। ঝুঁকিটি কেবল বাগ হয়ে গেছে, এবং nullকেস সম্পর্কে আপনার যুক্তি আরও জোরদার হয়ে উঠেছে। :-)
আটলাস্ট

49

এটি একটি ভাল নকশা পছন্দ। লাইব্রেরি কোড বা কোর ক্লাসগুলির জন্য দৃ recommended়ভাবে প্রস্তাবিত।

এটিকে কিছু "অলস সূচনা" বা "বিলম্বিত আরম্ভকরণ" বলে ডাকা হয় এবং এটি সাধারণত সকলকে একটি ভাল ডিজাইনের পছন্দ হিসাবে বিবেচনা করা হয়।

প্রথমত, আপনি যদি শ্রেণি স্তরের ভেরিয়েবল বা কনস্ট্রাক্টরের ঘোষণার সূচনা করে থাকেন, তারপরে যখন আপনার অবজেক্টটি নির্মিত হয়, আপনার এমন একটি উত্স তৈরির ওভারহেড থাকে যা কখনই ব্যবহার করা যায় না।

দ্বিতীয়ত, প্রয়োজন হলে রিসোর্স তৈরি হয়।

তৃতীয়ত, আপনি আবর্জনা ব্যবহার করবেন না এমন কোনও জিনিস সংগ্রহ করা এড়াতে পারেন।

শেষ অবধি, শ্রেণিতে স্তরের ভেরিয়েবল বা কনস্ট্রাক্টর আরম্ভের সময় যে ব্যতিক্রমগুলি সম্পত্তিতে ঘটে থাকতে পারে সেগুলির ব্যতিক্রমগুলি পরিচালনা করা সহজ।

এই নিয়মের ব্যতিক্রম আছে।

"পান" সম্পত্তিটিতে আরম্ভের জন্য অতিরিক্ত চেকের কর্মক্ষমতা যুক্তি সম্পর্কিত, এটি তুচ্ছ নয়। কোনও বস্তুর সূচনা এবং নিষ্পত্তি হ'ল লাফ দিয়ে সাধারণ নাল পয়েন্টার চেকের চেয়ে আরও কার্যকর পারফরম্যান্স হিট।

Http://msdn.microsoft.com/en-US/library/vstudio/ms229042.aspxক্লাস লাইব্রেরিগুলি বিকাশের জন্য নকশার নির্দেশিকা

সংক্রান্ত Lazy<T>

জেনেরিক Lazy<T>শ্রেণিটি পোস্টারটি যা চায় তার জন্যই তৈরি করা হয়েছিল, http://msdn.microsoft.com/en-us/library/dd997286(v=vs.100).aspxঅলস সূচনা দেখুন । আপনার কাছে .NET- র পুরানো সংস্করণগুলি থাকলে, আপনাকে প্রশ্নের বর্ণিত কোড প্যাটার্নটি ব্যবহার করতে হবে। এই কোড প্যাটার্নটি এতটাই সাধারণ হয়ে উঠেছে যে প্যাটার্নটি কার্যকর করা আরও সহজ করার জন্য মাইক্রোসফ্ট সর্বশেষ .NET লাইব্রেরিতে একটি শ্রেণি অন্তর্ভুক্ত করতে উপযুক্ত বলে মনে করেছিল। এছাড়াও, যদি আপনার বাস্তবায়নের জন্য থ্রেড সুরক্ষা প্রয়োজন হয়, তবে আপনাকে এটি যুক্ত করতে হবে।

প্রাথমিক তথ্য প্রকার এবং সহজ ক্লাস

অবিশ্বাস্য, আপনি আদিম ডেটা টাইপ বা সাধারণ শ্রেণীর ব্যবহারের মতো অলস-সূচনা ব্যবহার করতে যাচ্ছেন না List<string>

অলস সম্পর্কে মন্তব্য করার আগে

Lazy<T> .NET 4.0 এ চালু হয়েছিল, সুতরাং দয়া করে এই ক্লাস সম্পর্কে আরও একটি মন্তব্য যুক্ত করবেন না।

মাইক্রো-অপটিমাইজেশন সম্পর্কে মন্তব্য করার আগে

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

ব্যবহারকারী ইন্টারফেস সম্পর্কে

আপনি ক্লাসগুলির জন্য অলস সূচনাটি ব্যবহার করতে যাচ্ছেন না যা সরাসরি ব্যবহারকারী-ইন্টারফেস দ্বারা ব্যবহৃত হয়। গত সপ্তাহে আমি কম্বো-বাক্সের জন্য ভিউ-মডেলটিতে ব্যবহৃত আটটি সংগ্রহের অলস লোডিং সরিয়ে দিনের আরও ভাল অংশ ব্যয় করেছি। আমার কাছে এমন একটি আছে LookupManagerযা কোনও ব্যবহারকারী-ইন্টারফেস উপাদান দ্বারা প্রয়োজনীয় অলস লোডিং এবং সংগ্রহগুলি ক্যাশে করে।

"Setters"

আমি কোনও অলস বোঝা সম্পত্তির জন্য কোনও সেট-সম্পত্তি ("সেটটার") ব্যবহার করি নি। অতএব, আপনি কখনও অনুমতি দেবেন না foo.Bar = null;। আপনার যদি সেট করার দরকার হয় Barতবে আমি একটি পদ্ধতি তৈরি করব যা SetBar(Bar value)অলস-সূচনা ব্যবহার করবে না

সংগ্রহগুলি

শ্রেণি সংগ্রহের বৈশিষ্ট্যগুলি সর্বদা ঘোষিত হওয়ার পরে শুরু করা হয় কারণ সেগুলি কখনই শূন্য হওয়া উচিত নয়।

কমপ্লেক্স ক্লাস

আমাকে এটির অন্যভাবে পুনরাবৃত্তি করতে দিন, আপনি জটিল ক্লাসগুলির জন্য অলস-সূচনাটি ব্যবহার করেন। সাধারণত, খারাপভাবে ডিজাইন করা ক্লাস হয়।

সর্বশেষে

আমি কখনই সব ক্লাস বা সব ক্ষেত্রে এটি করার কথা বলিনি said এটি একটি খারাপ অভ্যাস।


6
যদি আপনি কোনও হস্তক্ষেপকারী মান বিন্যাস ব্যতীত বিভিন্ন থ্রেডে একাধিকবার foo.Bar কল করতে পারেন তবে বিভিন্ন মান পেতে পারেন, তবে আপনার কাছে একটি দরিদ্র শ্রেণি রয়েছে।
মিথ্যা রায়ান

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

10
"শ্রেণীর স্তরের ভেরিয়েবল বা কনস্ট্রাক্টর শুরুর সময় যে ব্যতিক্রমগুলি সম্পত্তি হতে পারে সেগুলির ব্যতিক্রমগুলি পরিচালনা করা সহজ" " - ঠিক আছে, এটা বোকা। যদি কোনও কারণে কোনও বস্তুর সূচনা করা যায় না, তবে আমি ASAP জানতে চাই। অর্থাত্ এটি নির্মাণের সাথে সাথে। অলস সূচনাটি ব্যবহারের জন্য ভাল যুক্তি রয়েছে তবে আমার মনে হয় না যে এটি ব্যাপকভাবে ব্যবহার করা ভাল ধারণা ।
মিলিমুজ

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

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

17

আপনি ব্যবহার করে যেমন প্যাটার্ন বাস্তবায়ন বিবেচনা Lazy<T>?

অলস-বোঝা বস্তুগুলির সহজ তৈরির পাশাপাশি, আপনি বস্তুর সূচনা হওয়ার সময় থ্রেড সুরক্ষা পাবেন:

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


ধন্যবাদ, আমি এটি এখনই বুঝতে পেরেছি এবং আমি অবশ্যই Lazy<T>এখনই সন্ধান করব এবং আমি যেভাবে সর্বদা করতাম তা ব্যবহার করা থেকে বিরত থাকব।
জন উইলেমস

1
আপনি যাদু থ্রেড সুরক্ষা পাবেন না ... আপনার এখনও এটি সম্পর্কে চিন্তা করতে হবে। এমএসডিএন থেকে:Making the Lazy<T> object thread safe does not protect the lazily initialized object. If multiple threads can access the lazily initialized object, you must make its properties and methods safe for multithreaded access.
এরিক জে।

@EricJ। অবশ্যই অবশ্যই. আপনি কেবল বস্তুর সূচনা করার সময় থ্রেড-সুরক্ষা পাবেন, তবে পরে আপনাকে অন্য কোনও বস্তুর মতো সিঙ্ক্রোনাইজেশনকে মোকাবেলা করতে হবে।
মাতাস ফিডেমাইজার

9

আমি মনে করি এটি আপনি কী শুরু করছেন তার উপর নির্ভর করে। আমি সম্ভবত এটি কোনও তালিকার জন্য করব না কারণ নির্মাণ ব্যয়টি খুব কম, সুতরাং এটি নির্মাত্রে যেতে পারে। তবে এটি যদি একটি প্রাক-জনবহুল তালিকা ছিল তবে আমি প্রথমবারের জন্য এটির প্রয়োজন না হওয়া পর্যন্ত সম্ভবত না করতাম।

মূলত, যদি প্রতিটি অ্যাক্সেসে শর্তসাপেক্ষ চেক করার জন্য নির্মাণের ব্যয় বেশি হয় তবে অলস এটি তৈরি করুন। যদি তা না হয় তবে কনস্ট্রাক্টরে এটি করুন।


ধন্যবাদ! এটা বোধগম্য.
জন উইলেমস

9

আমি যে খারাপ দিকটি দেখতে পাচ্ছি তা হ'ল আপনি যদি জিজ্ঞাসা করতে চান যে বারগুলি নাল কিনা, এটি কখনই হবে না এবং আপনি সেখানে তালিকা তৈরি করবেন।


আমি মনে করি না যে এটি একটি খারাপ দিক।
পিটার পোরফি

কেন এটা একটা খারাপ দিক? শূন্যের পরিবর্তে যে কোনওটির সাথে কেবল পরীক্ষা করুন। যদি (! Foo.Bars.Any ())
s.meijer

6
@ পিটারপোর্ফি: এটি পোলস লঙ্ঘন করে । আপনি null,োকান, কিন্তু এটি ফিরে পাবেন না। সাধারণত, আপনি ধরে নিবেন যে আপনি কোনও সম্পত্তি হিসাবে রেখেছেন সেই একই মান ফিরে পাবেন।
ড্যানিয়েল হিলগারথ

@ ড্যানিয়েলহিলগার্থ আবার ধন্যবাদ। এটি একটি খুব বৈধ যুক্তি যা আমি আগে বিবেচনা করি নি।
জন উইলেমস

6
@ এমিসিকো: এটি কোনও তৈরি ধারণা নয়। ঠিক একইভাবে যে সামনের দরজার পাশের বোতামটি চাপানো একটি ডোরবেল বাজবে বলে মনে করা হয়, বৈশিষ্ট্যগুলির মতো দেখতে এমন জিনিসগুলি সম্পত্তিগুলির মতো আচরণ করবে বলে আশা করা যায়। আপনার পায়ের নীচে একটি ফাঁদ দরজা খোলার একটি বিস্ময়কর আচরণ, বিশেষত যদি বোতামটি তেমন লেবেলযুক্ত না থাকে।
ব্রায়ান বোয়েচার

8

অলস তাত্পর্য / সূচনা একটি পুরোপুরি কার্যকর প্যাটার্ন। তবে মনে রাখবেন যে আপনার সাধারণ API হিসাবে গ্রাহকরা শেষ ব্যবহারকারী পিওভির (বা ব্যর্থ হওয়ার) থেকে বিচক্ষণ সময় নেওয়ার আশা করেন না get


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

8

আমি সবেমাত্র ড্যানিয়েলের উত্তরে একটি মন্তব্য করতে যাচ্ছিলাম তবে আমি সত্যই বলে মনে করি না যে এটি যথেষ্ট পরিমাণে যায়।

যদিও এটি নির্দিষ্ট পরিস্থিতিতে ব্যবহারের জন্য খুব ভাল প্যাটার্ন (উদাহরণস্বরূপ, যখন বস্তুটি ডেটাবেস থেকে শুরু করা হয়), এটি প্রবেশ করার একটি ভৌতিক অভ্যাস।

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

ক্লাস SafeClass
{
    স্ট্রিং নাম = "";
    পূর্ণসংখ্যার বয়স = 0;

    পাবলিক অকার্যকর সেটনাম (স্ট্রিং নিউনাম)
    {
        দাবি (নতুন নাম! = নাল)
        name = newName;
    } // বয়সের জন্য এই ধরণটি অনুসরণ করুন
    ...
    পাবলিক স্ট্রিং টু স্ট্রিং () {
        স্ট্রিং s = "নিরাপদ শ্রেণীর নাম রয়েছে:" + নাম + "এবং বয়স:" + বয়স
    }
}

আপনার নিদর্শন দিয়ে, টাস্টস্ট্রিং পদ্ধতিটি দেখতে এইরকম হবে:

    যদি (নাম == নাল)
        নতুন অবৈধ স্টেট এক্সেপশন নিক্ষেপ করুন ("সেফক্লাস একটি অবৈধ অবস্থায় পড়েছে! নামটি নাল")
    যদি (বয়স == নাল)
        নতুন অবৈধ স্টেট এক্সেপশন নিক্ষেপ করুন ("SafeClass একটি অবৈধ অবস্থায় পড়েছে! বয়স শূন্য")

    পাবলিক স্ট্রিং টু স্ট্রিং () {
        স্ট্রিং s = "নিরাপদ শ্রেণীর নাম রয়েছে:" + নাম + "এবং বয়স:" + বয়স
    }

কেবল এটিই নয়, আপনার ক্লাসে যে জিনিসটি সম্ভবত আপনি ব্যবহার করতে পারেন সেখানে নাল চেকগুলি দরকার (আপনার ক্লাসের বাইরে গেটে নাল চেকের কারণে নিরাপদ তবে আপনার ক্লাসের সদস্যদের বেশিরভাগই ক্লাসের অভ্যন্তরে ব্যবহার করা উচিত)

এছাড়াও আপনার বর্গটি স্থিরভাবে একটি অনিশ্চিত অবস্থায় থাকে - উদাহরণস্বরূপ আপনি যদি কিছু টীকাগুলি যোগ করে সেই শ্রেণিকে হাইবারনেট শ্রেণিতে পরিণত করার সিদ্ধান্ত নেন, আপনি কীভাবে এটি করবেন?

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

ব্রান্স পূর্বাভাস সমস্যার একটি উদাহরণের জন্য (যা আপনি বারবার ব্যয় করছেন, কেবল একবার নস্ট করেছেন), এই দুর্দান্ত প্রশ্নের প্রথম উত্তরটি দেখুন: একটি বাছাই করা অ্যারের চেয়ে বাছাই করা অ্যারে প্রক্রিয়া করা কেন দ্রুত?


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

আমি আসলে তা বুঝতে পারি না। এটি বোঝায় যে আপনি আপনার সদস্যদের যে ক্লাসগুলিতে সঞ্চিত আছেন সেগুলি ব্যবহার করছেন না - আপনি কেবল ক্লাসগুলি ডেটা স্ট্রাকচার হিসাবে ব্যবহার করছেন। যদি এটি হয় তবে আপনি javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html পড়তে চাইতে পারেন যা আপনার কোডটি কীভাবে বাহ্যিকভাবে হস্তান্তর অবজেক্টের পরিস্থিতি এড়াতে উন্নত করা যায় তার একটি ভাল বিবরণ রয়েছে। আপনি যদি এগুলি অভ্যন্তরীণভাবে চালিত করে থাকেন তবে বারবার সমস্ত কিছু নাল-চেক না করে আপনি কীভাবে তা করেন?
বিল কে

এই উত্তরের অংশগুলি ভাল, তবে অংশগুলি স্বীকৃত বলে মনে হচ্ছে। সাধারণত এই প্যাটার্নটি ব্যবহার toString()করার সময় getName(), কল করবে , nameসরাসরি ব্যবহার করবে না ।
ইজকাটা

@ বিল্ক হ্যাঁ, ক্লাসগুলি একটি বিশাল ডেটা কাঠামো। সমস্ত কাজ স্থির শ্রেণিতে করা হয়। আমি লিঙ্কে নিবন্ধটি চেক করব। ধন্যবাদ!
জন উইলেমস

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

4

আমি কেবল অন্যদের দ্বারা তৈরি অনেক ভাল পয়েন্টগুলিতে আরও একটি পয়েন্ট যুক্ত করি ...

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

এটি সমস্যা হতে পারে বা নাও হতে পারে (পার্শ্ব প্রতিক্রিয়াগুলির উপর নির্ভর করে) তবে সচেতন হওয়ার মতো বিষয়।


2

আপনি কি নিশ্চিতরূপে ফু কোনও কিছু ইনস্ট্যান্ট করা উচিত?

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

তবে যদি ফু এর উদ্দেশ্য হ'ল বার টাইপের উদাহরণ তৈরি করা হয় তবে অলসভাবে এটি করাতে আমি কোনও ভুল দেখতে পাচ্ছি না।


4
পুনঃটুইট করেছেন এবং শ্রদ্ধার সাথে, এমনকি তা হলেও, আপনি কোন বিন্দু তৈরি করার চেষ্টা করছেন?
কাপ্তজনকোল্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.