আলগা দম্পতি কোডের জন্য ইন্টারফেস ব্যবহার করে


10

পটভূমি

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

  1. একটি সি # প্রকল্পে একটি ইন্টারফেস সংজ্ঞায়িত করুন IDevice
  2. অন্য সি # প্রকল্পে সংজ্ঞায়িত লাইব্রেরিতে একটি কংক্রিট রাখুন, এটি ডিভাইসটির প্রতিনিধিত্ব করতে ব্যবহৃত হবে।
  3. কংক্রিট ডিভাইসটি IDeviceইন্টারফেসটি প্রয়োগ করুন ।
  4. IDeviceইন্টারফেস পদ্ধতি থাকতে পারে GetMeasurementবা SetRange
  5. অ্যাপ্লিকেশনটিকে কংক্রিট সম্পর্কে জ্ঞান তৈরি করুন এবং কংক্রিটটিকে অ্যাপ্লিকেশন কোডটিতে পাস করুন যা ডিভাইসটি ব্যবহার করে ( প্রয়োগ নয় ) IDevice

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

আমার মনে একটাই সন্দেহ, এখন অ্যাপ্লিকেশন এবং ডিভাইসের কংক্রিট ক্লাস উভয়ই লাইব্রেরির উপর নির্ভর করে যা IDeviceইন্টারফেসটি অন্তর্ভুক্ত করে । তবে, এটা কি খারাপ জিনিস?

ডিভাইসটি IDeviceএকই নামস্থানে না থাকলে অ্যাপ্লিকেশনটির কীভাবে ডিভাইস সম্পর্কে জানতে হবে না তাও আমি দেখতে পাই না ।

প্রশ্ন

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


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

@ কিলিয়ানফথ হ্যাঁ আমার একটা অনুভূতি ছিল, আমার প্রশ্নের একটি অংশ যুক্ত করতে ভুলে গেছেন। # 5 দেখুন।
স্নুপ

উত্তর:


5

আমি মনে করি আপনি ডিউপলড সফ্টওয়্যারটি কীভাবে কাজ করে তার একটি খুব ভাল বোঝা পেয়েছেন :)

আমার মনে একটাই সন্দেহ, এখন অ্যাপ্লিকেশন এবং ডিভাইসের কংক্রিট ক্লাস উভয়ই লাইব্রেরির উপর নির্ভর করে যা আইডেভাইস ইন্টারফেস ধারণ করে। তবে, এটা কি খারাপ জিনিস?

এটি হওয়ার দরকার নেই!

ডিভাইস এবং আইডেভাইস একই নামস্থানে না থাকলে অ্যাপ্লিকেশনটির কীভাবে ডিভাইস সম্পর্কে জানতে হবে না তাও আমি দেখতে পাচ্ছি না।

আপনি প্রকল্প কাঠামো দিয়ে এই সমস্ত উদ্বেগ মোকাবেলা করতে পারেন ।

আমি সাধারণত যেভাবে এটি করি:

  • আমার সমস্ত বিমূর্ত জিনিস একটি Commonপ্রকল্পে রাখুন । কিছু একটা MyBiz.Project.Common। অন্যান্য প্রকল্পগুলি এটির রেফারেন্সে নির্দ্বিধায়, তবে এটি অন্যান্য প্রকল্পগুলিকে উল্লেখ করতে পারে না।
  • যখন আমি কোনও বিমূর্তির একটি কংক্রিট বাস্তবায়ন তৈরি করি তখন আমি এটিকে একটি পৃথক প্রকল্পে রাখি। কিছু একটা MyBiz.Project.Devices.TemperatureSensors। এই প্রকল্পটি প্রকল্পটি উল্লেখ করবে Common
  • আমার তখন আমার Clientপ্রকল্পটি যা আমার আবেদনের প্রবেশদ্বার (এমন কিছু MyBiz.Project.Desktop)। প্রারম্ভকালে, অ্যাপ্লিকেশনটি বুটস্ট্র্যাপিং প্রক্রিয়াটির মধ্য দিয়ে যায় যেখানে আমি বিমূর্ততা / কংক্রিট-প্রয়োগকরণ ম্যাপিং কনফিগার করি। আমি আমার কংক্রিট instantiate করতে IDevicesমত WaterTemperatureSensorএবং IRCameraTemperatureSensorএখানে, অথবা আমি কারখানা অথবা একটি আইওসি ধারক মত পরিষেবাগুলিতে কনফিগার পরে আমার জন্য সঠিক কংক্রিট ধরনের instantiate করতে পারেন।

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

আলতোভাবে সংযুক্ত কোড এফটিডব্লু :)


2
ডিআই এখান থেকে প্রাকৃতিকভাবে অনুসরণ করে। এটি মূলত একটি প্রকল্প / কোড কাঠামোর উদ্বেগও। আইওসি পাত্রে থাকা ডিআই-তে সহায়তা করতে পারে তবে এটি পূর্বশর্ত নয়। আপনি নিজে নিজে নির্ভরতা ইনজেকশন দিয়ে ডিআই অর্জন করতে পারেন!
মেটাফাইট

1
@ স্টেভিভ হ্যাঁ, যদি আপনার অ্যাপ্লিকেশনটির মধ্যে ফু অবজেক্টের আইডিওয়াইসের প্রয়োজন হয় তবে নির্ভরতা বিপর্যয় এটিকে কোনও কনস্ট্রাক্টরের মাধ্যমে ইনজেকশন দেওয়ার মতোই সহজ হতে পারে new Foo(new DeviceA());, বরং ফু ইনস্ট্যানিয়েট ডিভাইসএ ( private IDevice idevice = new DeviceA();) এর মধ্যে একটি ব্যক্তিগত ক্ষেত্র থাকার চেয়ে - আপনি এখনও ডিআই অর্জন করবেন, Foo প্রথম ক্ষেত্রে ডিভাইসএ সম্পর্কে অজানা
ডেভ

2
@ অন্যদিকে আপনার এবং মেটাফাইট ইনপুটটি খুব সহায়ক ছিল was
স্নুপ

1
@ স্টেভিভ যখন আপনি সময় পাবেন, এখানে স্প্রিংয়ের মতো নিয়ন্ত্রণ / ডিপেনসি ইনজেকশন ফ্রেমওয়ার্কের বিপরীত থেকে আলাদা ("চাচা বব" মার্টিনের কাছ থেকে, ধারণা হিসাবে) ডিপেন্ডেনসি ইনভার্সনের একটি দুর্দান্ত ভূমিকা রয়েছে or সি ওয়ার্ল্ডে জনপ্রিয় উদাহরণ :))
আরেকটি ডেভ

1
@ অ্যানডোরডেভ অবশ্যই তা পরীক্ষা করে নেওয়ার পরিকল্পনা করছেন, আপনাকে আবারও ধন্যবাদ।
স্নুপ

3

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

যদি আপনি উদ্বিগ্ন হন যে ডিভাইসগুলি সর্বদা ইন্টারফেসটি প্রয়োগ না করে, যে কোনও কারণেই হোক না কেন, আপনি অ্যাডাপ্টারের প্যাটার্নটি ব্যবহার করতে পারেন এবং ডিভাইসগুলির কংক্রিটের প্রয়োগটিকে ইন্টারফেসের সাথে মানিয়ে নিতে পারেন।

সম্পাদনা

আপনার পঞ্চম উদ্বেগের সমাধানের জন্য, এই জাতীয় কাঠামোর কথা চিন্তা করুন (আমি ধরে নিচ্ছি যে আপনি আপনার ডিভাইস সংজ্ঞায়িত করার নিয়ন্ত্রণ করছেন):

আপনার একটি কোর লাইব্রেরি আছে। এটিতে আইডিভাইস নামে একটি ইন্টারফেস রয়েছে।

আপনার ডিভাইস লাইব্রেরিতে আপনার কাছে আপনার মূল লাইব্রেরির একটি উল্লেখ রয়েছে এবং আপনি একটি ডিভাইসগুলির একটি সিরিজ সংজ্ঞায়িত করেছেন যা সমস্ত আইডিভাইস প্রয়োগ করে। আপনার একটি কারখানা রয়েছে যা জানে যে কীভাবে বিভিন্ন ধরণের আইডিভাইস তৈরি করতে হয়।

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

আপনার উদ্বেগের সমাধানের এটি সম্ভাব্য কয়েকটি উপায়গুলির মধ্যে একটি।

উদাহরণ:

namespace Core
{
    public interface IDevice { }
}


namespace Devices
{
    using Core;

    class DeviceOne : IDevice { }

    class DeviceTwo : IDevice { }

    public class Factory
    {
        public IDevice CreateDeviceOne()
        {
            return new DeviceOne();
        }

        public IDevice CreateDeviceTwo()
        {
            return new DeviceTwo();
        }
    }
}

// do not implement IDevice
namespace ThirdrdPartyDevices
{

    public class ThirdPartyDeviceOne  { }

    public class ThirdPartyDeviceTwo  { }

}

namespace DeviceAdapters
{
    using Core;
    using ThirdPartyDevices;

    class ThirdPartyDeviceAdapterOne : IDevice
    {
        private ThirdPartyDeviceOne _deviceOne;

        // use the third party device to adapt to the interface
    }

    class ThirdPartyDeviceAdapterTwo : IDevice
    {
        private ThirdPartyDeviceTwo _deviceTwo;

        // use the third party device to adapt to the interface
    }

    public class AdapterFactory
    {
        public IDevice CreateThirdPartyDeviceAdapterOne()
        {
            return new ThirdPartyDeviceAdapterOne();
        }

        public IDevice CreateThirdPartyDeviceAdapterTwo()
        {
            return new ThirdPartyDeviceAdapterTwo();
        }
    }
}

namespace Application
{
    using Core;
    using Devices;
    using DeviceAdapters;

    class App
    {
        void RunInHouse()
        {
            var factory = new Factory();
            var devices = new List<IDevice>() { factory.CreateDeviceOne(), factory.CreateDeviceTwo() };
            foreach (var device in devices)
            {
                // call IDevice  methods.
            }
        }

        void RunThirdParty()
        {
            var factory = new AdapterFactory();
            var devices = new List<IDevice>() { factory.CreateThirdPartyDeviceAdapterOne(), factory.CreateThirdPartyDeviceAdapterTwo() };
            foreach (var device in devices)
            {
                // call IDevice  methods.
            }
        }
    }
}

সুতরাং এই বাস্তবায়নের সাথে, কংক্রিটটি কোথায় যায়?
স্নুপ

আমি যা করতে চাই তা কেবল তার জন্যই বলতে পারি। আপনি যদি ডিভাইসগুলির নিয়ন্ত্রণে থাকেন তবে আপনি এখনও কংক্রিট ডিভাইসগুলিকে তাদের নিজস্ব লাইব্রেরিতে রেখে দিতেন। আপনি যদি ডিভাইসগুলির নিয়ন্ত্রণে না থাকেন তবে আপনি অ্যাডাপ্টারের জন্য অন্য একটি লাইব্রেরি তৈরি করবেন।
মূল্য জোন্স 17

আমার অনুমান একটাই, অ্যাপ্লিকেশনটি আমার যে নির্দিষ্ট কংক্রিটের প্রয়োজন তা অ্যাক্সেস পাবে?
স্নুপ

একটি সমাধান হ'ল আইডিভাইসগুলি তৈরি করতে বিমূর্ত কারখানার প্যাটার্নটি ব্যবহার করা।
মূল্য জোন্স

1

আমার মনে একটাই সন্দেহ, এখন অ্যাপ্লিকেশন এবং ডিভাইসের কংক্রিট ক্লাস উভয়ই লাইব্রেরির উপর নির্ভর করে যা আইডেভাইস ইন্টারফেস ধারণ করে। তবে, এটা কি খারাপ জিনিস?

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

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

কেবল হ্যাঁ

কীভাবে কংক্রিটটি অ্যাপ্লিকেশনটিতে আসে

অ্যাপ্লিকেশনটি রানটাইমের সময় কংক্রিটের সমাবেশ (dll) লোড করতে পারে। দেখুন: /programming/465488/can-i-load-a-net-assembly-at-runtime-and-instantiate-a-type- ज्ञान-- মাত্র-the-na

আপনার যদি এমন একটি "ড্রাইভার" গতিশীলভাবে আনলোড / লোড করতে হয় তবে আপনাকে অ্যাসেম্বলিটি একটি পৃথক অ্যাপডোমাইনে লোড করতে হবে ।


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

দুঃখিত, একটি অংশ যুক্ত করতে ভুলে গেছেন (কংক্রিটটি আসলে অ্যাপটিতে কীভাবে আসে)। আপনি কি সম্বোধন করতে পারেন? # 5 দেখুন।
স্নুপ

রান-টাইমে DLL গুলি লোড করে আপনি কী আসলে আপনার অ্যাপসটি করেন?
স্নুপ

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