আমার কি নির্ভরশীল ইনজেকশন বা স্থিতিশীল কারখানাগুলি ব্যবহার করা উচিত?


81

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

  • কারখানাগুলি একটি বেদনাকে পরীক্ষা করে এবং বাস্তবায়নের পক্ষে সহজেই অদলবদল করতে দেয় না। তারা নির্ভরতাগুলিও আপাত করে না (উদাহরণস্বরূপ আপনি কোনও পদ্ধতি পরীক্ষা করছেন, এটি একটি বিস্মৃত যে এটি কোনও পদ্ধতিকে কল করে এমন একটি পদ্ধতি যা কল করে এমন একটি পদ্ধতি যা একটি ডেটাবেস ব্যবহার করে) calls
  • ডিপেন্ডেসি ইনজেকশনটি ব্যাপকভাবে নির্মাণকারীর যুক্তি তালিকার স্ফীত হয় এবং এটি আপনার কোডের সমস্ত দিকগুলিকে ঘ্রাণ দেয়। প্রায় অর্ধশতাধিক শ্রেণীর নির্মাতারা এ জাতীয় দেখায় এমন সাধারণ পরিস্থিতি(....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)

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

আমি কীভাবে এ জাতীয় সমস্যা মোকাবিলা করব ??


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

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

সমাধানটি এখানে যুক্তি হ্রাস করা উচিত নয়। পরিবর্তে বিমূর্ততাগুলি তৈরি করুন যা একটি উচ্চ স্তরের অবজেক্ট তৈরি করে যা বস্তুটিতে সমস্ত কাজ করে এবং আপনাকে সুবিধা দেয়।
অ্যালেক্স

উত্তর:


74

নির্ভরতা ইনজেকশন ব্যবহার করুন, তবে যখনই আপনার কনস্ট্রাক্টর যুক্তি তালিকাগুলি খুব বড় হয়ে যায়, তখন ফ্যাসিড পরিষেবা ব্যবহার করে এটি রিফ্যাক্টর । ধারণাটি হ'ল কিছু নির্মাতাকে যুক্তিযুক্ত করে একত্রিত করে একটি নতুন বিমূর্তি প্রবর্তন করা।

উদাহরণস্বরূপ, আপনি একটি নতুন ধরণের SessionEnvironmentএনপ্যাপুলেটিং এ DBSessionProvider, UserSessionও এবং বোঝা প্রবর্তন করতে পারেন Descriptions। কোন বিমূর্ততা সর্বাধিক বোধ করে তা জানার জন্য, আপনার প্রোগ্রামের বিশদ জানতে হবে।

অনুরূপ প্রশ্ন ইতিমধ্যে এখানে এসও জিজ্ঞাসা করা হয়েছিল ।


9
+1: আমি মনে করি ক্লাসে কনস্ট্রাক্টর আর্গুমেন্টগুলি গ্রুপ করা একটি খুব ভাল ধারণা। এটি আপনাকে এই যুক্তি আরও অর্থ কাঠামোতে সংগঠিত করতে বাধ্য করে।
জর্জিও

5
তবে ফলাফলটি যদি কোনও অর্থবহ কাঠামো না হয় তবে আপনি কেবল এসআরপি লঙ্ঘনকারী জটিলতাগুলি এড়িয়ে চলেছেন। এক্ষেত্রে একটি ক্লাস রিফ্যাক্টরিং করা উচিত।
দানিদাচর

1
@ জর্জিও আমি একটি সাধারণ বক্তব্যের সাথে একমত নই যে "ক্লাসে কনস্ট্রাক্টর যুক্তি গোষ্ঠীকরণ একটি খুব ভাল ধারণা"। আপনি যদি এই "এই দৃশ্যে" এর সাথে যোগ্যতা অর্জন করেন তবে এটি আলাদা।
tymtam

19

ডিপেন্ডেসি ইনজেকশনটি ব্যাপকভাবে নির্মাণকারীর যুক্তি তালিকার স্ফীত হয় এবং এটি আপনার কোডের সমস্ত দিকগুলিকে ঘ্রাণ দেয়।

সেখান থেকে, আপনি ডিআই-কে যথাযথভাবে বুঝতে পেরেছেন বলে মনে হচ্ছে না - ধারণাটি হ'ল কোনও কারখানার ভিতরে অবজেক্ট ইনস্ট্যান্টেশন প্যাটার্নটি উল্টানো।

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

অন্য পদ্ধতির একটি ব্যতিক্রম কারখানা হবে, যা তাদের নির্মাণকারীদের মাধ্যমে বস্তুগুলিতে প্রেরণ করা হয়। নতুন ব্যতিক্রম ছোঁড়ার পরিবর্তে ক্লাসটি কারখানার কোনও পদ্ধতিতে (উদাঃ) ফেলে দিতে পারে throw PrettyExceptionFactory.createException(data)

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


1
আমি কোথাও পড়েছি যে যখন আপনার প্যারামিটারের তালিকাটি দীর্ঘ হয়ে যায় তখন এটি নির্ভর করে না যে আপনি নির্ভরতা ইনজেকশন ব্যবহার করছেন তবে আপনার আরও নির্ভরতা ইনজেকশন প্রয়োজন।
জর্জিও

এটি অন্যতম কারণ হতে পারে - সাধারণত ভাষার উপর নির্ভর করে আপনার নির্মাতাকে 6--৮ টির বেশি যুক্তি থাকতে হবে না এবং নির্দিষ্ট প্যাটার্ন (প্যাটার্নের মতো Builder) ব্যতীত এগুলির মধ্যে ৩-৪ টির বেশি হওয়া উচিত নয় objects এটি হুকুম দেয়। যদি আপনি আপনার নির্মাতার কাছে প্যারামিটারগুলি পার করছেন কারণ আপনার বস্তুটি অন্য অবজেক্টগুলিকে তাত্ক্ষণিক করে তোলে, এটি আইওসির জন্য একটি স্পষ্ট কেস।
জোনাথন ধনী

12

আপনি ইতিমধ্যে স্থিতিশীল কারখানার প্যাটার্নগুলির অসুবিধাগুলি বেশ ভালভাবে তালিকাভুক্ত করেছেন, তবে নির্ভরতা ইনজেকশন প্যাটার্নের অসুবিধার সাথে আমি পুরোপুরি একমত নই:

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

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

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

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

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

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


এই. আমি ডিবি আঘাত করার প্রয়োজনীয়তা দেখতে পায় না নিক্ষেপ একটি ব্যতিক্রম।
কালেথ

1

নির্ভরতা ইনজেকশন ব্যবহার করুন। স্ট্যাটিক কারখানাগুলি ব্যবহার করা Service Locatorঅ্যান্টিপ্যাটার্নের একটি কর্মসংস্থান । মার্টিন ফাউলারের কাছ থেকে সেমিনাল কাজটি এখানে দেখুন - http://martinfowler.com/articles/inication.html

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


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

1
জানতে আগ্রহী। আমি সবসময় শুনেছি এটি এন্টি প্যাটার্ন হিসাবে উল্লেখ করা হয়।
স্যাম

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

এক্সএমএল টাইপ নিরাপদ নয়। অন্যান্য প্রতিটি পদ্ধতির ব্যর্থ হওয়ার পরে আমি এটিকে একটি পরিকল্পনা z হিসাবে বিবেচনা করব
রিচার্ড টিঙ্গল

1

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

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

আপনি যে আরও পদক্ষেপে যেতে চাইতে পারেন সেটি হ'ল Aspect-Orimented প্রোগ্রাম্মনিগ, যা অনেকগুলি বড় ফ্রেমওয়ার্কগুলিতে প্রয়োগ করা হয়। এটি আপনাকে ক্লাসের নির্মাতা বা অ্যাস্পেক্টজে টার্মিনোলজিটি ব্যবহার করার জন্য "পরামর্শ দিতে" বা অনুমতি দিতে পারে, কোনও বিশেষ বৈশিষ্ট্য দেওয়া হলেও প্রাসঙ্গিক বৈশিষ্ট্যগুলি ইনজেক্ট করতে পারে।


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

1
সম্পত্তি সেটারের মাধ্যমে ডিআই চ্ছিক নির্ভরতার জন্য আদর্শ। লগিং একটি ভাল উদাহরণ। আপনার যদি লগিং দরকার হয়, তবে লগার সম্পত্তি সেট করুন, যদি না হয় তবে সেট করুন না।
প্রেস্টন

1

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

আমি বেশ রাজি হই না। কমপক্ষে সাধারণভাবে না।

সাধারণ কারখানা:

public IFoo GetIFoo()
{
    return new Foo();
}

সাধারণ ইনজেকশন:

myDependencyInjector.Bind<IFoo>().To<Foo>();

উভয় স্নিপেট একই উদ্দেশ্যে পরিবেশন করে, তারা IFooএবং এর মধ্যে একটি লিঙ্ক স্থাপন করে Foo। অন্য সব কিছুই কেবল সিনট্যাক্স।

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

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


ডিপেন্ডেসি ইনজেকশনটি ব্যাপকভাবে নির্মাণকারীর যুক্তি তালিকার স্ফীত হয় এবং এটি আপনার কোডের সমস্ত দিকগুলিকে ঘ্রাণ দেয়।

এ কারণেই কিছু লোক নির্মাতাদের মধ্যে স্পষ্টভাবে নির্ভরতা পুনরুদ্ধার করতে পছন্দ করে:

public MyService()
{
    _myFoo = DependencyFramework.Get<IFoo>();
}

আমি আর্গুমেন্ট প্রো শুনেছি (কোনও নির্মাণকারী ব্লাট নয়), আমি আর্গুমেন্ট কন শুনেছি (কনস্ট্রাক্টর ব্যবহার করে আরও ডিআই অটোমেশন সক্ষম করে)।

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

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


পার্শ্ব নোট হিসাবে, নির্ভরতা ইনজেকশন এবং কারখানাগুলি পারস্পরিক একচেটিয়া নয় । আমার ক্ষেত্রে এমন ঘটনা ঘটেছে যেখানে নির্ভরতা serোকানোর পরিবর্তে, আমি এমন একটি কারখানা প্রবেশ করিয়েছি যা নির্ভরতা উত্পন্ন করে (এনআইজেক্ট ভাগ্যক্রমে আপনাকে ব্যবহারের অনুমতি দেয় Func<IFoo>যাতে আপনার প্রকৃত কারখানার শ্রেণি তৈরি করার প্রয়োজন হয় না)।

এর জন্য ব্যবহারের ক্ষেত্রে বিরল তবে সেগুলি বিদ্যমান।


স্থির কারখানা সম্পর্কে ওপি জিজ্ঞাসা করে । stackoverflow.com/questions/929021/…
বাসিলিভস

@ বাসিলিভস "প্রশ্নটি হল, আমি অন্যান্য উপাদানগুলিতে এই উপাদানগুলি সরবরাহ করতে কীভাবে যাব?"
অ্যান্টনি রাটলেজ

1
@ বাসিলিভস পার্শ্ব নোট ব্যতীত আমি যা কিছু বলেছিলাম তা স্থির কারখানায়ও প্রযোজ্য। আপনি কী নির্দিষ্টভাবে উল্লেখ করতে চাইছেন তা আমি নিশ্চিত নই। রেফারেন্সে লিঙ্কটি কী?
উত্তেজনাপূর্ণ

কারখানায় ইনজেকশনের ক্ষেত্রে এরকম একটি ব্যবহারের ক্ষেত্রে কী এমন ঘটনা ঘটতে পারে যেখানে কেউ একটি বিমূর্ত এইচটিটিপি অনুরোধ শ্রেণি তৈরি করেছিল এবং জিইটি, পোষ্ট, পুট, প্যাচ এবং ডিএলটিইটির জন্য একটি পাঁচটি বহুতল শিশু ক্লাস কৌশলগত করে? তুমি জানো করতে পারবেন কোন HTTP পদ্ধতি প্রতিটি সময় যখন একটি MVC টাইপ রাউটার (যা একটি HTTP অনুরোধ বর্গ উপর অংশে নির্ভর করতে পারে বলেন বর্গ অনুক্রমের সংহত করার চেষ্টা ব্যবহার করা হবে PSR-7 HTTP- র বার্তা ইন্টারফেস কুশ্রী
এন্থনি রাতলিজের

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

0

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

<?php
namespace TFWD\Factories;

/**
 * A class responsible for instantiating
 * InboundHttpRequest objects (PHP 7.x)
 * 
 * @author Anthony E. Rutledge
 * @version 2.0
 */
class InboundHttpRequestFactory 
{
    private const GET = 'GET';
    private const POST = 'POST';
    private const PUT = 'PUT';
    private const PATCH = 'PATCH';
    private const DELETE = 'DELETE';

    private static $di;
    private static $method;

    // public function __construct(Injector $di, Validator $httpRequestValidator)
    // {
    //    $this->di = $di;
    //    $this->method = $httpRequestValidator->getMethod();
    // }

    public static function setInjector(Injector $di)
    {
        self::$di = $di;
    }    

    public static setMethod(string $method)
    {
        self::$method = $method;
    }

    public static function getRequest()
    {
        if (self::$method == self::GET) {
            return self::$di->get('InboundGetHttpRequest');
        } elseif ((self::$method == self::POST) && empty($_FILES)) {
            return self::$di->get('InboundPostHttpRequest');
        } elseif (self::$method == self::POST) {
            return self::$di->get('InboundFilePostHttpRequest');
        } elseif (self::$method == self::PUT) {
            return self::$di->get('InboundPutHttpRequest');
        } elseif (self::$method == self::PATCH) {
            return self::$di->get('InboundPatchHttpRequest');
        } elseif (self::$method == self::DELETE) {
            return self::$di->get('InboundDeleteHttpRequest');
        } else {
            throw new \RuntimeException("Unexpected HTTP request. Invalid request.");
        }
    }
}

সেন্ট্রালাইজডের মধ্যে একটি এমভিসি টাইপ সেটআপের জন্য ক্লায়েন্ট কোডটি index.phpনিম্নলিখিতগুলির মতো দেখতে পাওয়া যাবে (বৈধতা বাদ দেওয়া)।

InboundHttpRequestFactory::setInjector($di);
InboundHttpRequestFactory::setMethod($httpRequestValidator->getMethod());
$di->set('InboundHttpRequest', InboundHttpRequestFactory::getRequest());
$router = $di->get('Router');  // The Router class depends on InboundHttpRequest objects.
$router->dispatch(); 

বিকল্পভাবে, আপনি কারখানার স্থির প্রকৃতি (এবং কীওয়ার্ড) মুছে ফেলতে পারেন এবং নির্ভরতা ইনজেক্টরকে পুরো জিনিসটি পরিচালনা করার অনুমতি দিতে পারেন (অতএব, মন্তব্যটি নির্মাণকারীর বাইরে)। তবে আপনাকে ক্লাস মেম্বার রেফারেন্সের কিছু (কনস্ট্যান্ট নয়) পরিবর্তন করতে হবে ( self) উদাহরণ সদস্যদের ( $this)।


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