NET প্রতিক্রিয়াশীল এক্সটেনশনগুলিতে কেন বিষয়গুলি সুপারিশ করা হয় না?


111

আমি বর্তমানে নেট নেট এর রিঅ্যাকটিভ এক্সটেনশানস কাঠামোটি আঁকড়ে ধরছি এবং আমি যে বিভিন্ন ভূমিকা সংস্থান খুঁজে পেয়েছি তার মাধ্যমে কাজ করছি (মূলত: http://www.introtorx.com )

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

আমি যে সংস্থানগুলি পড়ছি তার বেশিরভাগ (সমস্ত না থাকলে) বলেছে যে আমি নিজেই IObservable ইন্টারফেসটি প্রয়োগ করব না তবে প্রদত্ত ফাংশন বা ক্লাসগুলির মধ্যে একটি ব্যবহার করব। আমার গবেষণা থেকে দেখা যাচ্ছে যে একটি তৈরি করা Subject<IBaseFrame>আমাকে যা প্রয়োজন তা সরবরাহ করবে, আমার একক থ্রেড থাকবে যা হার্ডওয়্যার ইন্টারফেস থেকে ডেটা পড়ে এবং তারপরে আমার Subject<IBaseFrame>উদাহরণের অননেক্সট ফাংশনটিকে কল করে । বিভিন্ন IObserver উপাদানগুলি তখন সেই সাবজেক্ট থেকে তাদের বিজ্ঞপ্তিগুলি গ্রহণ করবে।

আমার বিভ্রান্তি এই টিউটোরিয়ালটির পরিশিষ্টে দেওয়া পরামর্শ থেকে আসছে যেখানে এটি বলেছে:

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

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

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

যেকোনো উপদেশ সাদরে গৃহীত হবে।


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

উত্তর:


70

ঠিক আছে, আমরা যদি আমার কৌতূহলমূলক উপায়ে অগ্রাহ্য করি এবং "বিষয়গুলি ভাল / খারাপ" সমস্ত একসাথে উপেক্ষা করি। আসুন সমস্যা স্থানটি দেখুন look

আমি বাজি ধরছি আপনার সিস্টেমে 2 টির মধ্যে 1 স্টাইল রয়েছে যা আপনাকে ইন্টিগ্রেট করতে হবে।

  1. সিস্টেম কোনও ইভেন্ট বা একটি কল পুনরায় উত্থাপন করে যখন কোনও বার্তা আসে
  2. প্রক্রিয়া করার জন্য কোনও বার্তা আছে কিনা তা দেখতে আপনাকে সিস্টেমটি পোল করতে হবে

বিকল্প 1 এর জন্য, সহজ, আমরা এটি কেবল যথাযথ FromEvent পদ্ধতি দিয়ে মুড়ে ফেলি এবং আমাদের কাজ শেষ। পাব!

বিকল্প 2 এর জন্য, এখন আমাদের কীভাবে এটি পোলিং করা হয় এবং কীভাবে এটি কার্যকরভাবে করা যায় তা বিবেচনা করা দরকার। এছাড়াও যখন আমরা মান পাই, আমরা কীভাবে এটি প্রকাশ করব?

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

আমি ধারণা করি এরকম কিছু কাজ করতে পারে। #পরীক্ষিত না

public class MessageListener
{
    private readonly IObservable<IMessage> _messages;
    private readonly IScheduler _scheduler;

    public MessageListener()
    {
        _scheduler = new EventLoopScheduler();

        var messages = ListenToMessages()
                                    .SubscribeOn(_scheduler)
                                    .Publish();

        _messages = messages;
        messages.Connect();
    }

    public IObservable<IMessage> Messages
    {
        get {return _messages;}
    }

    private IObservable<IMessage> ListenToMessages()
    {
        return Observable.Create<IMessage>(o=>
        {
                return _scheduler.Schedule(recurse=>
                {
                    try
                    {           
                        var messages = GetMessages();
                        foreach (var msg in messages)
                        {
                            o.OnNext(msg);
                        }   
                        recurse();
                    }
                    catch (Exception ex)
                    {
                        o.OnError(ex);
                    }                   
                });
        });
    }

    private IEnumerable<IMessage> GetMessages()
    {
         //Do some work here that gets messages from a queue, 
         // file system, database or other system that cant push 
         // new data at us.
         // 
         //This may return an empty result when no new data is found.
    }
}

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


10
আমি এখনই এই উত্তরটি পড়ছি তবে আমার অনুভূত হওয়া উচিত যে আমি কখনই সাবজেক্ট ইন্টারফেসটি প্রকাশের বিষয়টি বিবেচনা করব না! আমি এটি সিল করা ক্লাসের মধ্যে আইওজার্ভেবল <> বাস্তবায়ন সরবরাহ করতে ব্যবহার করছি (যা IObservable <> প্রকাশ করে)। আমি অবশ্যই স্পষ্টভাবে দেখতে পাচ্ছি যে << ইন্টারফেসের বিষয় প্রকাশ করা কেন খারাপ কাজ হবে ™
অ্যান্থনি

আরে, ঘন হওয়ার জন্য দুঃখিত, তবে আমি সত্যিই আপনার কোডটি বুঝতে পারি না। লিসনটোমেসেজ () এবং গেটমেসেজ () কী করছে এবং ফিরে আসছে?
ব্যবহারকারী 10479

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

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

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

38

সাধারণভাবে আপনার ব্যবহার এড়ানো উচিত Subject, তবে আপনি এখানে যা করছেন তার জন্য আমি মনে করি তারা বেশ ভাল কাজ করে। আমি যখন আরএক্স টিউটোরিয়ালের "বিষয়গুলি এড়িয়ে চলুন" বার্তাটি পেলাম তখন আমি একইরকম প্রশ্ন জিজ্ঞাসা করেছি।

ডেভ সেক্সটনের উদ্ধৃতি দিতে (আরএক্সএক্সের)

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

আমি তাদের আরএক্স এন্ট্রি পয়েন্ট হিসাবে ব্যবহার করার ঝোঁক। সুতরাং আমার যদি কিছু কোড থাকে যা বলার দরকার হয় যে 'কিছু ঘটেছে' (যেমন আপনার আছে), আমি একটি ব্যবহার করবSubject এবং কলOnNext । তারপরে IObservableঅন্যদের সাবস্ক্রাইব করার জন্য এটি প্রকাশ করুন ( AsObservable()কেউ আপনার সাবজেক্ট এবং জগাখিচুড়ি বিষয়গুলিতে কাস্ট করতে না পারে তা নিশ্চিত করার জন্য আপনি নিজের বিষয়ে ব্যবহার করতে পারেন )।

আপনি নেট নেট ইভেন্ট এবং ব্যবহারের মাধ্যমে এটি অর্জন করতে পারেন FromEventPattern তবে আমি যদি কেবল IObservableযাইহোক রূপান্তর করতে যাচ্ছি তবে আমি কোনওটির পরিবর্তে কোনও অনুষ্ঠানের সুবিধাটি দেখতে পাচ্ছি না Subject(যার অর্থ হতে পারে যে আমি মিস করছি) এখানে কিছু)

তবে কি আপনি বেশ জোরালোভাবে এড়িয়ে চলা উচিত একটি সাবস্ক্রাইব করা হয় IObservableএকটি সঙ্গে Subject, অর্থাত্ একটি পাস না Subjectমধ্যে IObservable.Subscribeপদ্ধতি।


আপনার রাষ্ট্রের আদৌ দরকার কী? আমার উত্তরের হিসাবে দেখানো হয়েছে, আপনি যদি সমস্যাটিকে আলাদা আলাদা করে ফেলে থাকেন তবে আপনাকে সত্যিকার অর্থে রাষ্ট্র পরিচালনা করতে হবে না। বিষয়গুলি এই ক্ষেত্রে ব্যবহার করা উচিত নয়
ক্যাস্পারআন

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

@ ক্যাস্পারওন - তবে আপনি কেবল এওভারতপ্যাটার্ন দিয়ে মোড়ানোর জন্য কোনও ইভেন্ট তৈরি করবেন না। স্পষ্টতই এটি একটি ভয়ানক ধারণা।
জেমস মুর

3
আমি আমার ব্লগ পোস্টে আরও গভীরতার সাথে আমার উদ্ধৃতি ব্যাখ্যা করেছি ।
ডেভ Sexton

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

31

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

আপনি যখন কিছু অ্যাসিনক্রোনাস ডেটা প্রবাহকে আরএক্স-তে অভিযোজিত করার চেষ্টা করছেন (বা এমন একটি থেকে অ্যাসিনক্রোনাস ডেটা প্রবাহ তৈরি করুন যা বর্তমানে অ্যাসিনক্রোনাস নয়) সবচেয়ে সাধারণ ক্ষেত্রে সাধারণত:

  • ডেটার উত্স একটি ইভেন্ট : লি যেমন বলেছেন, এটি সর্বাধিক সহজ ঘটনা: ফ্রি-এভেন্ট ব্যবহার করুন এবং পাবে যাবেন।

  • ডেটা উত্স একটি সংক্রামক ক্রিয়াকলাপ থেকে এবং আপনি পোল আপডেট চান , (উদাহরণস্বরূপ একটি ওয়েব সার্ভিস বা ডাটাবেস কল): এই ক্ষেত্রে আপনি লি এর প্রস্তাবিত পদ্ধতির ব্যবহার করতে পারেন, বা সাধারণ ক্ষেত্রে, আপনি এর মতো কিছু ব্যবহার করতে পারেন Observable.Interval.Select(_ => <db fetch>)। আপনি যখন সোর্স ডেটাতে কিছু পরিবর্তন করেনি তখন আপডেট প্রকাশনা রোধ করতে আপনি ডিসট্রিন্ট ইউটিটিল চেঞ্জড () ব্যবহার করতে পারেন।

  • তথ্যের উত্স হ'ল একরকম অ্যাসিনক্রোনাস এপিআই যা আপনার কলব্যাককে কল করে: এক্ষেত্রে পর্যবেক্ষককে অননেক্সট / অনআরআর / অনকমল্ট কল করতে আপনার কলব্যাকটি হুক করতে অবজার্ভেশন ব্যবহার করুন re

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

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

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

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


1
পর্যবেক্ষণযোগ্য সম্পর্কে খুব স্পষ্ট ব্যাখ্যা re ধন্যবাদ!
ইভান মরান

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

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

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

9

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

এখানেই আপনি সমস্যায় পড়েছেন; এই দায়িত্বগুলি একে অপরের থেকে পৃথক এবং পৃথক হওয়া উচিত।

এটি বলেছিল, আপনার নির্দিষ্ট ক্ষেত্রে আমি আপনাকে সুপারিশ করব যে আপনি আপনার উদ্বেগকে ছোট ছোট ভাগে ভাগ করুন।

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

আসুন এটি সংজ্ঞায়িত করুন EventArgsযে আপনার ইভেন্টটি জ্বালিয়ে দেবে।

// The event args that has the information.
public class BaseFrameEventArgs : EventArgs
{
    public BaseFrameEventArgs(IBaseFrame baseFrame)
    {
        // Validate parameters.
        if (baseFrame == null) throw new ArgumentNullException("IBaseFrame");

        // Set values.
        BaseFrame = baseFrame;
    }

    // Poor man's immutability.
    public IBaseFrame BaseFrame { get; private set; }
}

এখন, ক্লাস যে ঘটনা আগুন হবে। মনে রাখবেন, এই একটি স্ট্যাটিক বর্গ হতে পারে (যেহেতু আপনি সবসময় একটি থ্রেড হার্ডওয়্যার বাফার পর্যবেক্ষণ চলমান), অথবা কিছু অন-ডিমান্ড যা সদস্যতা কল যে । আপনি এটি যথাযথ হিসাবে পরিবর্তন করতে হবে।

public class BaseFrameMonitor
{
    // You want to make this access thread safe
    public event EventHandler<BaseFrameEventArgs> HardwareEvent;

    public BaseFrameMonitor()
    {
        // Create/subscribe to your thread that
        // drains hardware signals.
    }
}

সুতরাং এখন আপনার কাছে একটি ক্লাস রয়েছে যা একটি ইভেন্ট প্রকাশ করে। পর্যবেক্ষণগুলি ইভেন্টগুলির সাথে ভালভাবে কাজ করে। তাই অনেক তাই (একটি ঘটনা একাধিক গুলির যেমন একটি ঘটনা প্রবাহের মনে করি) ঘটনা প্রবাহের রূপান্তরের জন্য প্রথম শ্রেণীর সমর্থন মধ্যে যে সেখানে IObservable<T>বাস্তবায়নের আপনি মাধ্যমে মান ঘটনা প্যাটার্ন অনুসরণ স্ট্যাটিক FromEventPatternপদ্ধতি উপর Observableবর্গ

আপনার ইভেন্টগুলির উত্স এবং FromEventPatternপদ্ধতির সাহায্যে আমরা একটি IObservable<EventPattern<BaseFrameEventArgs>>সহজেই তৈরি করতে পারি ( EventPattern<TEventArgs>ক্লাসটি একটি। নেট ইভেন্টে আপনি কী দেখতে চান তা উল্লেখযোগ্যভাবে, উত্পন্ন উদাহরণ EventArgsএবং প্রেরকের প্রতিনিধিত্বকারী কোনও বস্তু), এর মতো:

// The event source.
// Or you might not need this if your class is static and exposes
// the event as a static event.
var source = new BaseFrameMonitor();

// Create the observable.  It's going to be hot
// as the events are hot.
IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
    FromEventPattern<BaseFrameEventArgs>(
        h => source.HardwareEvent += h,
        h => source.HardwareEvent -= h);

অবশ্যই, আপনি একটি চান IObservable<IBaseFrame>তবে এটি সহজ, প্রজেকশন তৈরি করতে ক্লাসে Selectএক্সটেনশন পদ্ধতিটি ব্যবহার করে Observable(যেমন আপনি লিনিকিউতে চান, এবং আমরা এগুলি সব সহজে ব্যবহারের পদ্ধতিতে গুটিয়ে রাখতে পারি):

public IObservable<IBaseFrame> CreateHardwareObservable()
{
    // The event source.
    // Or you might not need this if your class is static and exposes
    // the event as a static event.
    var source = new BaseFrameMonitor();

    // Create the observable.  It's going to be hot
    // as the events are hot.
    IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
        FromEventPattern<BaseFrameEventArgs>(
            h => source.HardwareEvent += h,
            h => source.HardwareEvent -= h);

    // Return the observable, but projected.
    return observable.Select(i => i.EventArgs.BaseFrame);
}

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

@ অ্যান্টনি আপনি যদি তার কোড নমুনাটি কাজ করতে পারেন তবে দুর্দান্ত, তবে আমি যেমন মন্তব্য করেছি, তাতে কোনও লাভ হয় না। "ভুল" বোধ করার জন্য, কেন জানি না কেন যৌক্তিক অংশগুলিতে জিনিসগুলি বিভক্ত করা "ভুল" বলে মনে হয় তবে আপনি কীভাবে IObservable<T>কোনও তথ্য হিসাবে এটি কীভাবে সেরা অনুবাদ করবেন তা নির্দেশ করার জন্য আপনি আপনার মূল পোস্টে পর্যাপ্ত বিবরণ দেননি ' বর্তমানে সেই তথ্য দিয়ে সংকেত দেওয়া হয়েছে।
ক্যাস্পারনি

@ ক্যাস্পারওন আপনার মতে, সাবজেক্টের ব্যবহার কোনও বার্তা বাস / ইভেন্ট অ্যাগ্রিগেটরের জন্য উপযুক্ত হবে?
কিটসুন

1
@ কিটসুন না, তারা কেন করবে তা আমি দেখতে পাচ্ছি না। আপনি যদি "অপ্টিমাইজেশন" ভাবছেন তবে সমস্যাটি কিনা তা আপনি যদি জিজ্ঞাসা করতেই থাকেন তবে আপনি কি Rx কে সমস্যার কারণ হিসাবে পরিমাপ করেছেন?
ক্যাস্পারওন

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

0

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

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

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

আপনি যদি অন্যরা কোনও সম্পত্তি পরিবর্তনের বিষয়ে শোনার / সাবস্ক্রাইব করতে চান তবে এটি ব্যবহার করা সবচেয়ে ভাল।

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