টাইপ ম্যাপিং এবং এক্সটেনশন পদ্ধতি সম্পর্কিত সেরা অনুশীলন


15

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

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

আমার মনে 4 সম্ভাব্য সমাধান রয়েছে:

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

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

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

  4. রূপান্তরকারী / ম্যাপার ক্লাস। আমি পৃথক শ্রেণি তৈরি করেছি যা রূপান্তরগুলি পরিচালনা করবে এবং এমন পদ্ধতিগুলি বাস্তবায়িত করবে যা উত্স শ্রেণীর উদাহরণকে যুক্তি হিসাবে গ্রহণ করবে এবং গন্তব্য শ্রেণীর ফিরে আসবে।

সংক্ষেপে বলতে গেলে, আমার সমস্যাটি প্রশ্নের সংখ্যাতে হ্রাস করা যেতে পারে (যা আমি উপরে বর্ণিত তার প্রসঙ্গে):

  1. রূপান্তর পদ্ধতি (পোকো?) অবজেক্টের (যেমন .ToPerson () পদ্ধতিতে গ্রাহক শ্রেণিতে) স্থাপন করা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করে?

  2. (ডিটিও-সদৃশ) শ্রেণিতে রূপান্তরকারী কনস্ট্রাক্টর ব্যবহার করা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করা হয়? বিশেষত যদি এই জাতীয় শ্রেণিকে একাধিক উত্সের ধরণের থেকে রূপান্তর করা যায়, তবে একাধিক রূপান্তরকারী কনস্ট্রাক্টরের প্রয়োজন হবে?

  3. মূল শ্রেণীর উত্স কোড অ্যাক্সেস করার সময় কি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচিত হয়? এই জাতীয় আচরণ যুক্তিকে আলাদা করার জন্য কার্যকর প্যাটার্ন হিসাবে ব্যবহার করা যেতে পারে বা এটি কোনও বিরোধী-নিদর্শন?


Personক্লাসটি কি ডিটিও? এটা কোন আচরণ থাকে?
ইয়াকুব মাসাদ

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

উত্তর:


11

রূপান্তর পদ্ধতি (পোকো?) অবজেক্টের (যেমন .ToPerson () পদ্ধতিতে গ্রাহক শ্রেণিতে) স্থাপন করা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করে?

হ্যাঁ, কারণ ধর্মান্তরকরণ অন্য একটি দায়িত্ব।

(ডিটিও-সদৃশ) শ্রেণিতে রূপান্তরকারী কনস্ট্রাক্টর ব্যবহার করা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করা হয়? বিশেষত যদি এই জাতীয় শ্রেণিকে একাধিক উত্সের ধরণের থেকে রূপান্তর করা যায়, তবে একাধিক রূপান্তরকারী কনস্ট্রাক্টরের প্রয়োজন হবে?

হ্যাঁ, ধর্মান্তরকরণ অন্য একটি দায়িত্ব। আপনি এটি নির্মাণকারীর মাধ্যমে বা রূপান্তর পদ্ধতিগুলির (উদাহরণস্বরূপ ToPerson) মাধ্যমে করলে কোনও তফাত আসে না ।

মূল শ্রেণীর উত্স কোড অ্যাক্সেস করার সময় কি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচিত হয়?

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

এই জাতীয় আচরণ যুক্তিকে আলাদা করার জন্য কার্যকর প্যাটার্ন হিসাবে ব্যবহার করা যেতে পারে বা এটি কোনও বিরোধী-নিদর্শন?

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

আমি আপনাকে রূপান্তর পরিষেবা তৈরি করার পরামর্শ দিচ্ছি। এর জন্য এটির জন্য আপনার একক জেনেরিক ইন্টারফেস থাকতে পারে:

public interface IConverter<TSource,TDestination>
{
    TDestination Convert(TSource source_object);
}

এবং আপনার এর মত রূপান্তরকারী থাকতে পারে:

public class PersonToCustomerConverter : IConverter<Person,Customer>
{
    public Customer Convert(Person source_object)
    {
        //Do the conversion here. Note that you can have dependencies injected to this class
    }
}

এবং আপনি ডিপেন্ডেন্সি ইনজেকশনটি ব্যবহার করতে পারেন কোনও রূপান্তরকারী ইনজেক্ট করতে (উদাহরণস্বরূপ IConverter<Person,Customer>) যে শ্রেণীর মধ্যে Personএবং এর মধ্যে রূপান্তর করার ক্ষমতা প্রয়োজন Customer


যদি আমি ভুল না হয়ে থাকি IConverterতবে ইতিমধ্যে কাঠামোর মধ্যে একটি রয়েছে, কেবল বাস্তবায়নের অপেক্ষায়।
রাবারডাক

@ রাবারডাক, এটি কোথায় আছে?
ইয়াকুব মাসাদ

আমি ভাবছিলাম IConvertable, যা আমরা এখানে খুঁজছি তা নয় । আমার ভুল.
রাবারডাক

আহ হা! আমি @ ইয়াকুব মাসাদ সম্পর্কে যা ভাবছিলাম তা পেয়েছি। কল করার সময় Converterব্যবহার করা হয় । msdn.microsoft.com/en-us/library/kt456a2y(v=vs.110).aspx যদিও ওপিতে এটি কতটা কার্যকর তা আমি জানি না। ListConvertAll
রাবারডাক

প্রাসঙ্গিকও। অন্য যে কেউ আপনাকে এখানে প্রস্তাব দিয়েছেন তা গ্রহণ করেছে। কোডেরভিউ.স্ট্যাক্কেঞ্জঞ্জ
৫১৮৮৯ /

5

রূপান্তর পদ্ধতি (পোকো?) অবজেক্টের ( .ToPerson()কনজিউমার ক্লাসের মত পদ্ধতির ) ভিতরে রাখা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করা হয়?

হ্যাঁ. কোনও Consumerশ্রেণি গ্রাহক সম্পর্কিত ডেটা ধরে রাখার জন্য দায়বদ্ধ (এবং সম্ভবত কিছু ক্রিয়া সম্পাদন করে) এবং নিজেকে অন্য কোনও সম্পর্কযুক্ত সম্পর্কিত রূপান্তর করার জন্য দায়বদ্ধ হওয়া উচিত নয় ।

(ডিটিও-সদৃশ) শ্রেণিতে রূপান্তরকারী কনস্ট্রাক্টর ব্যবহার করা কি একক দায়িত্বের ধরণ ভাঙা বিবেচনা করা হয়? বিশেষত যদি এই জাতীয় শ্রেণিকে একাধিক উত্সের ধরণের থেকে রূপান্তর করা যায়, তবে একাধিক রূপান্তরকারী কনস্ট্রাক্টরের প্রয়োজন হবে?

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

মূল শ্রেণীর উত্স কোড অ্যাক্সেস করার সময় কি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচিত হয়?

সাধারণভাবে, যদিও তারা করতে পারেন overused হবে না। এক্সটেনশন পদ্ধতিগুলির সাহায্যে, আপনি al চ্ছিক এক্সটেনশনগুলি তৈরি করেন যা কোডটি পড়া সহজ করে তোলে। তাদের অসুবিধাগুলি রয়েছে - সংকলকটির সমাধান করা (কখনও কখনও নিঃশব্দে) এবং দ্বিগুণ হওয়া কোডটিকে আরও জটিল করে তুলতে পারে যেহেতু এক্সটেনশন পদ্ধতিটি কোথা থেকে আসছে তা পুরোপুরি সুস্পষ্ট নয়।

আপনার ক্ষেত্রে, একটি রূপান্তরকারী বা ম্যাপার ক্লাসটি সহজতম, সর্বাধিক সরল পদ্ধতির মতো বলে মনে হচ্ছে, যদিও আমি মনে করি না আপনি এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে কোনও ভুল করছেন ।


2

অটোম্যাপার বা কাস্টম ম্যাপার ব্যবহার সম্পর্কে কীভাবে ব্যবহার করা যেতে পারে

MyMapper
   .CreateMap<Person>()
   .To<PersonViewModel>()
   .Map(p => p.Name, vm => vm.FirstName)
   .To<SomeDTO>()
   .Map(...);

ডোমেন থেকে

 db.Persons
   .ToListAsync()
   .Map<PersonViewModel>();

হুডের নীচে আপনি অটোম্যাপার বিমূর্ত করতে পারেন বা আপনার নিজের ম্যাপার রোল করতে পারেন


2

আমি জানি এটি পুরানো, তবে এখনও শ্রদ্ধাবোধজনক। এটি আপনাকে উভয় উপায়ে রূপান্তর করতে দেয়। সত্তা ফ্রেমওয়ার্কের সাথে কাজ করার এবং ভিউ মডেলগুলি (ডিটিও) তৈরি করার সময় আমি এটি সহায়ক মনে করি this

public interface IConverter<TSource, TDestination>
{
    TDestination Convert(TSource source_object);
    TSource Convert(TDestination source_object);
}

public class PersonCustomerConverter : IConverter<Person, Customer>
{
    public Customer Convert(Person source_object)
    {
        //Do the conversion here. Note that you can have dependencies injected to this class
    }
    public Person Convert(Customer source_object)
    {
        //Do the conversion here. Note that you can have dependencies injected to this class
    }
}

আমি সত্যই সাধারণ ম্যাপিং অপারেশন করার জন্য অটোম্যাপারটিকে কিছুটা বেশি বলে মনে করি।

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