আমরা কি নির্মাণকারী ছাড়া বাঁচতে পারি?


25

আসুন কোনও কারণে বলা যাক যে সমস্ত অবজেক্টগুলি এইভাবে তৈরি করা হয়েছে $জেজক = ক্লাস :: getInstance ()। তারপরে আমরা সেটারগুলি ব্যবহার করে নির্ভরতা ইনজেকশন করি এবং $ obj-> initInstance () ব্যবহার করে সূচনা শুরু করি; এমন কোনও বাস্তব সমস্যা বা পরিস্থিতি রয়েছে, যা সমাধান করা যায় না, যদি আমরা নির্মাতাকে মোটেই ব্যবহার না করি?

এইভাবে অবজেক্ট তৈরির কারণটি হ'ল আমরা কিছু নিয়ম অনুসারে getInstance () এর অভ্যন্তর শ্রেণি প্রতিস্থাপন করতে পারি।

আমি পিএইচপি মধ্যে কাজ করছি, যদি ব্যাপার


কি প্রোগ্রামিং ভাষা?
gnat

2
পিএইচপি (কেন এটি গুরুত্বপূর্ণ?)
এক্সেল ফোলি

8
দেখে মনে হচ্ছে যে আপনি যা করতে চান তা কারখানার নিদর্শন ব্যবহার করে অর্জন করা যেতে পারে।
সুপার

1
ঠিক যেমন একটি দ্রষ্টব্য: উল্লিখিত কারখানার প্যাটার্ন @ সুপারম হ'ল ইনভার্শন অফ কন্ট্রোল (ডিপেন্ডেন্সি ইনজেকশন) প্রয়োগের এক উপায় another
জোচিম সৌর

জাভাস্ক্রিপ্ট বস্তুগুলির সাথে কি প্রায় এটিই হয় না?
থিজার

উত্তর:


44

আমি বলব যে এটি আপনার ডিজাইনের জায়গাকে মারাত্মকভাবে বাধা দেয়।

কনস্ট্রাক্টররা পাস করা প্যারামিটারগুলি আরম্ভ এবং বৈধ করার জন্য এক দুর্দান্ত জায়গা If আপনি যদি আর সেগুলির জন্য ব্যবহার না করতে পারেন তবে আরম্ভকরণ, স্টেট হ্যান্ডলিং (বা "ভাঙা" বস্তুর নির্মাণকারীর অস্বীকৃতি) অনেক বেশি শক্ত এবং আংশিক অসম্ভব হয়ে ওঠে।

উদাহরণস্বরূপ, যদি প্রতিটি Fooবস্তুর একটি প্রয়োজন হয় Frobnicatorতবে এটি তার নির্মাতাকে চেক করতে পারে যদি এটি Frobnicatorনাল নয়। আপনি যদি কনস্ট্রাক্টর কেড়ে নেন তবে তা পরীক্ষা করা শক্ত হয়। আপনি এটি যেখানে ব্যবহৃত হবে সেখানে প্রতিটি চেক করেন? একটি init()পদ্ধতিতে (কার্যকরভাবে নির্মাণকারী পদ্ধতি বহিরাগত)? কখনই এটি যাচাই করবেন না এবং সর্বোত্তম আশা করবেন?

আপনি সম্ভবত এখনও সব কিছু কার্যকর করতে পেরেছিলেন (সর্বোপরি, আপনি এখনও সম্পূর্ণরূপে ট্যুর করছেন), কিছু জিনিস করা খুব কঠিন হবে।

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


"বা" ভাঙ্গা "অবজেক্টস" এর নির্মাতাকে অস্বীকার করে আপনি কী বোঝাতে চেয়েছেন?
গীক

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

1
আমি মনে করি যে ওপি কেবল ভিতরে কনস্ট্রাক্টরের বহিরাগতকরণের বর্ণনা দিচ্ছিল init(), যা সম্পূর্ণ সম্ভব — যদিও এটি কেবল রক্ষণাবেক্ষণের বোঝা আরোপ করে।
পিটার

26

নির্মাতাদের 2 টি সুবিধা:

কনস্ট্রাক্টররা বস্তুর নির্মাণের পদক্ষেপগুলি পরমাণুর সাথে সম্পন্ন করার অনুমতি দেয়।

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

যদি কোনও উদাহরণ তৈরি করার Fooজন্য 3 টি বৈশিষ্ট্য নির্ধারণের প্রয়োজন হয় তবে কনস্ট্রাক্টর 3 টির জন্য একটি রেফারেন্স নিতে পারে, তাদের বৈধ করে এবং যদি তারা অবৈধ হয় তবে একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে।

encapsulation

সম্পূর্ণ সেটারের উপর নির্ভর করে, বোঝা কোনও জিনিসটির গ্রাহককে এটিকে সঠিকভাবে তৈরি করতে হয়। বৈধ বৈশিষ্ট্যগুলির বিভিন্ন সংমিশ্রণ থাকতে পারে।

উদাহরণস্বরূপ, যে Fooউদাহরণস্বরূপ পারেন একটি দৃষ্টান্ত দরকার Barযেমন সম্পত্তি barবা একটি দৃষ্টান্ত BarFinderহিসাবে সম্পত্তি barFinder। এটি একটি ব্যবহার করতে পারেন। আপনি প্রতিটি বৈধ প্যারামিটার সেটগুলির জন্য কনস্ট্রাক্টর তৈরি করতে পারেন এবং কনভেনশনগুলি সেভাবে কার্যকর করতে পারেন।

অবজেক্টের জন্য যুক্তি এবং শব্দার্থবিদ্যা বস্তুর মধ্যেই বাস করে। এটি ভাল encapsulation।


15

হ্যাঁ, আপনি নির্মাণকারী ছাড়া বাঁচতে পারেন।

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

তবে না, আপনার নিজের নির্মাণকারীর কঠোরভাবে প্রয়োজন নেই don't অবশ্যই, আপনি হয় কঠোরভাবে 'প্রয়োজন' না ক্লাস এবং অবজেক্ট, হয়।

এখন যদি আপনার লক্ষ্য অবজেক্ট তৈরির জন্য কোনও ধরণের কারখানার প্যাটার্ন ব্যবহার করা হয়, যা আপনার অবজেক্টগুলি আরম্ভ করার সময় কনস্ট্রাক্টরগুলি ব্যবহার করার ক্ষেত্রে পারস্পরিক একচেটিয়া নয়।


একেবারে। এমনকি শুরুতে ক্লাস এবং অবজেক্ট ছাড়া কেউ বাঁচতে পারে।
JensG

5
সমস্ত শক্তিশালী সমাবেশকারীকে শোক!
avorড্রালো

9

কনস্ট্রাক্টরগুলি ব্যবহারের সুবিধা হ'ল এটি নিশ্চিত করা আপনার পক্ষে সহজ করে তোলে যে আপনার কখনই কোনও অবৈধ অবজেক্ট থাকবে না।

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

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

একটি কার্যকারণ হ'ল কেবলমাত্র একটি কারখানা-পদ্ধতির মাধ্যমে অবজেক্ট তৈরি করা যা কলারের কাছে ফেরত দেওয়ার আগে বৈধতার জন্য তৈরি করা প্রতিটি বস্তু পরীক্ষা করে।


3

$ obj = CLASS :: getInstance ()। তারপরে আমরা সেটারগুলি ব্যবহার করে নির্ভরতা ইনজেকশন করি এবং $ obj-> initInstance () ব্যবহার করে সূচনা শুরু করি;

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

$obj = new CLASS(array(
    'Frobnicator' => (),
    'Foonicator' => (),
));

এবং কনস্ট্রাক্টরের মধ্যে, আপনি এর মতো ধারাবাহিকতা নিশ্চিত করতে পারেন:

if (!array_key_exists('Frobnicator', $args)) {
    throw new Exception('Frobnicator required');
}
if (!array_key_exists('Foonicator', $args)) {
    $args['Foonicator'] = new DefaultFoonicator();
}

$args তারপরে প্রয়োজনীয় হিসাবে ব্যক্তিগত সদস্য সেট করতে ব্যবহার করা যেতে পারে।

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


2

আমি আসলে একই জিনিস সম্পর্কে চিন্তা ছিল।

আমি যে প্রশ্নটি জিজ্ঞাসা করেছি তা হ'ল "কনস্ট্রাক্টর কি করে এবং এটি কি অন্যভাবে করা সম্ভব?" আমি এই সিদ্ধান্তে পৌঁছেছি:

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

  • বৈশিষ্ট্যগুলি বৈধ কিনা তা নিশ্চিত করে। দৃ easily় শর্ত দ্বারা এটি সহজেই অর্জন করা যেতে পারে। আবার আপনি ঠিক সঠিক অবস্থার সাথে বৈশিষ্ট্যগুলি বর্ননা করবেন। কিছু ভাষা ইতিমধ্যে এটি করে।

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

সুতরাং আপনার প্রশ্নের উত্তর দিতে: হ্যাঁ, আমি বিশ্বাস করি এটি সম্ভব। তবে এর জন্য ভাষার নকশায় কিছু বড় পরিবর্তন প্রয়োজন।

এবং আমি কেবল লক্ষ্য করেছি যে আমার উত্তরটি বেশ ওটি।


2

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

আধুনিক ভাষায় (আমি এখানে সি # যা আমি প্রোগ্রাম করি সে সম্পর্কে এখানে কথা বলব) আপনি কোডের কিছু অংশ সীমাবদ্ধ করতে পারেন যা কেবলমাত্র একটি নির্মাণকারীতে চালানো যেতে পারে । আপনাকে ধন্যবাদ যে আপনি আনাড়ি ভুল এড়াতে পারেন। এ জাতীয় একটি বিষয় কেবল পঠনযোগ্য পরিবর্তনকারী :

public class A {
    readonly string rostring;

    public A(string arg) {
        rostring = arg;
    }

    public static A CreateInstance(string arg) {
        var result = new A();
        A.rostring = arg;  // < because of this the code won't compile!
        return result;
    }
}

হিসাবে আগে জোছিম Sauer দ্বারা প্রস্তাবিত পরিবর্তে Factoryডিজাইন প্যাটার ব্যবহার ব্যবহার করুন Dependency Injection। আমি মার্ক সিমেন দ্বারানেট এ ডিপেন্ডেন্সি ইনজেকশন পড়ার পরামর্শ দেব ।


1

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

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

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


1

দাবি সহ অন্যান্য উত্তরগুলির মধ্যে কিছু ভারসাম্য বজায় রাখতে:

একজন কনস্ট্রাক্টর আপনাকে অবজেক্টের সমস্ত সদস্য ভেরিয়েবলগুলি একটি বৈধ স্থিতিতে সেট করার সুযোগ দেয় ... আপনার কোনও অবৈধ অবজেক্ট কখনই পাবেন না, যা আপনাকে প্রচুর বাগ থেকে রক্ষা করবে।

এবং

কোনও কনস্ট্রাক্টরের সাথে, কোনও বস্তুর নিজস্ব নির্মাণ যুক্তির মালিকানা রয়েছে যাতে এটি নিশ্চিত করা যায় যে এই জাতীয় শ্রেণীর কোনও অবৈধ দৃষ্টান্ত নেই।

এই জাতীয় বক্তব্য মাঝে মাঝে এই ধারণাটিকে বোঝায় যে:

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

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


0

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

স্থগিত করা যায় এমন যে কোনও কিছু, আমি কনস্ট্রাক্টর থেকে ছাড়ি (আউটপুট মানগুলি প্রস্তুত করা, ইত্যাদি)। এই পদ্ধতির সাথে, আমি নির্বিঘ্নে ইনজেকশনটি বোধগম্য হলেও কোনও কিছুর জন্য কনস্ট্রাক্টর ব্যবহার করছি না বলে মনে করি।

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

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