পরিবেষ্টক প্রসঙ্গে বনাম নির্মাণকারী ইঞ্জেকশন ection


9

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

আমি দুটি সম্ভাব্য বাস্তবায়ন করেছি। মূল শ্রেণি যা তিনটি শ্রেণীর সাথে আইএম্বিয়েন্টকন্টেক্সট গ্রহণ করে বা তিনটি শ্রেণীর জন্য সমস্ত ইনজেকশন দেয়।

public interface ISessionContext 
{
    ...
}

public class MySessionContext: ISessionContext 
{
    ...
}

public interface ILogManager 
{

}

public class MyLogManager: ILogManager 
{
    ...
}

public interface IService 
{
    ...
}

public class MyService: IService
{
    ...
}

প্রথম সমাধান:

public class AmbientContext
{
    private ISessionContext sessionContext;
    private ILogManager logManager;
    private IService service;

    public AmbientContext(ISessionContext sessionContext, ILogManager logManager, IService service)
    {
        this.sessionContext = sessionContext;
        this.logManager = logManager;
        this.service = service;
    }
}


public class MyCoreClass(AmbientContext ambientContext)
{
    ...
}

দ্বিতীয় সমাধান (পরিবেষ্টনবিহীন)

public MyCoreClass(ISessionContext sessionContext, ILogManager logManager, IService service)
{
    ...
}

এই ক্ষেত্রে সবচেয়ে ভাল সমাধান কি?


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

উত্তর:


4

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

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

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

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


4

প্রশ্ন থেকে পরিভাষাটি উদাহরণ কোডের সাথে সত্যিই মেলে না। Ambient Contextসম্ভব হিসাবে সহজ কোন মডিউল কোনো ক্লাস থেকে নির্ভরশীলতার দখল করতে নির্ভরতা ইন্টারফেস গ্রহণ করতে প্রত্যেক বর্গ দূষণ, কিন্তু এখনও নিয়ন্ত্রণের বিপর্যয় ধারণা পালন ছাড়া ব্যবহার করা একটি প্যাটার্ন নেই। এই ধরনের নির্ভরতা সাধারণত লগিং, সুরক্ষা, সেশন ম্যানেজমেন্ট, লেনদেন, ক্যাশিং, নিরীক্ষার জন্য নিবেদিত থাকে যাতে অ্যাপ্লিকেশনটির যে কোনও ক্রস কাটা উদ্বেগ থাকে। এটি একটি যোগ করার জন্য একরকম বিরক্তিকর ILogging, ISecurity, ITimeProviderকনস্ট্রাকটর প্রয়োজন এবং অধিকাংশ সময় সব শ্রেণীর একই সময়ে সব প্রয়োজন, আমি আপনার প্রয়োজন বুঝতে তাই।

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

IAmbientContextপ্রশ্নে যে কন্সট্রাকটর দূষণ না সমস্যা সমাধানের নেই। আপনাকে এখনও এটি নির্মাণকারীর স্বাক্ষরে ব্যবহার করতে হবে, অবশ্যই, এই সময়টি কেবল একবার।

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

MyCore দেখতে এখন এরকম কিছু something

public class MyCoreClass
{
    public void BusinessFeature(string data)
    {
        LoggerContext.Current.Log(data);

        _repository.SaveProcessedData();

        SessionContext.Current.SetData(data);
        ...etc
    }
}

এই প্যাটার্ন এবং সম্ভব বাস্তবায়নের বিস্তারিত মার্ক Seemann দ্বারা বর্ণিত হয়েছে এই নিবন্ধটি । এমন কোনও বাস্তবায়ন হতে পারে যা আপনি নিজেরাই ব্যবহার করেন আইওসি ধারকটির উপর নির্ভর করে।

আপনি এড়াতে চান AmbientContext.Current.Logger, AmbientContext.Current.Sessionএকই কারণে উপরে বর্ণিত।

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


3

আমি এড়াতে চাই AmbientContext

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

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

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

চতুর্থত, এর মধ্যে সংহতি নেই এবং একক দায়িত্বের নীতি লঙ্ঘন করা হয়েছে। এ কারণেই এর নাম "অ্যাম্বিয়েন্টকন্টেক্সট" এর মতো রয়েছে কারণ এটি প্রচুর সম্পর্কহীন কাজ করে এবং এটি যা করে তা অনুসারে এর নামকরণের কোনও উপায় নেই।

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


2

দ্বিতীয় (ইন্টারফেস মোড়ক ছাড়াই)

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

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