একক দায়িত্ব নীতি সম্পর্কে চিন্তা করবেন না। এটি আপনাকে এখানে একটি ভাল সিদ্ধান্ত নিতে সহায়তা করবে না কারণ আপনি বিষয়গতভাবে একটি "ধারণা" হিসাবে একটি নির্দিষ্ট ধারণা চয়ন করতে পারেন। আপনি বলতে পারেন যে শ্রেণীর দায়িত্বটি ডাটাবেসে ডেটা অধ্যবসায় পরিচালনা করা, বা আপনি বলতে পারেন যে এর দায়বদ্ধতা একটি ব্যবহারকারী তৈরি সম্পর্কিত সমস্ত কাজ সম্পাদন করা to এগুলি অ্যাপ্লিকেশনটির আচরণের মাত্র বিভিন্ন স্তরের এবং এগুলি উভয়ই "একক দায়বদ্ধতার" বৈধ ধারণাগত প্রকাশ। সুতরাং আপনার সমস্যা সমাধানের জন্য এই নীতিটি অপ্রয়োজনীয়।
এই ক্ষেত্রে প্রয়োগ করার জন্য সবচেয়ে দরকারী নীতিটি হ'ল কমপক্ষে অবাক হওয়ার নীতি । সুতরাং আসুন প্রশ্নটি জিজ্ঞাসা করা যাক: অবাক করা কি কোনও ডাটাবেসে ডেটা অব্যাহত রাখার প্রাথমিক ভূমিকা সহ একটি ভান্ডার ই-মেলগুলি প্রেরণ করে?
হ্যাঁ, এটা খুব অবাক করা। এটি দুটি সম্পূর্ণ পৃথক পৃথক বাহ্যিক সিস্টেম এবং নামটি SaveChanges
বিজ্ঞপ্তি প্রেরণকে বোঝায় না। আপনি কোনও ইভেন্টে এটি অর্পণ করার বিষয়টি আচরণটি আরও বিস্ময়কর করে তোলে, যেহেতু কোড পড়ার কেউ আরও সহজে কী কী আচরণগুলি চাওয়া হয় তা সহজেই দেখতে পায় না। নির্দেশনা পাঠযোগ্যতার ক্ষতি করে। কখনও কখনও, বেনিফিটগুলি পঠনযোগ্যতার জন্য মূল্য ব্যয় হয়, তবে যখন আপনি স্বয়ংক্রিয়ভাবে একটি অতিরিক্ত বাহ্যিক ব্যবস্থা চালু করেন যা এর ব্যবহারকারীদের শেষ পর্যবেক্ষণের জন্য প্রভাব রাখে। (লগিংটি এখানে বাদ দেওয়া যেতে পারে কারণ এটির প্রভাবটি মূলত ডিবাগিংয়ের উদ্দেশ্যে রেকর্ড করা হয় users শেষ ব্যবহারকারীরা লগটি গ্রাহ্য করে না, তাই সর্বদা লগিংয়ের কোনও ক্ষতি হয় না)) আরও খারাপ বিষয়, এটি সময়কালে নমনীয়তা হ্রাস করে reduces ই-মেইল প্রেরণের, সংরক্ষণ এবং বিজ্ঞপ্তির মধ্যে অন্য ক্রিয়াকলাপকে আন্তঃলিভ করা অসম্ভব করে তোলে।
যদি কোনও ব্যবহারকারী সফলভাবে তৈরি করা হয় আপনার কোডটিতে সাধারণত কোনও বিজ্ঞপ্তি প্রেরণের প্রয়োজন হয়, আপনি এমন একটি পদ্ধতি তৈরি করতে পারেন যা এটি করে:
public void AddUserAndNotify(IUserRepository repo, IEmailNotification notifier, MyUser user)
{
repo.Add(user);
repo.SaveChanges();
notifier.SendUserCreatedNotification(user);
}
তবে এতে মান যুক্ত হয় কিনা তা আপনার অ্যাপ্লিকেশনটির নির্দিষ্টকরণের উপর নির্ভর করে।
আমি আসলেই SaveChanges
পদ্ধতিটির অস্তিত্বকে নিরুৎসাহিত করব । এই পদ্ধতিটি সম্ভবত একটি ডাটাবেস লেনদেনের প্রতিশ্রুতিবদ্ধ হবে, তবে অন্যান্য সংগ্রহাগুলি একই লেনদেনে ডাটাবেসটি পরিবর্তন করতে পারে । এটি তাদের সকলের প্রতিশ্রুতিবদ্ধ সত্যটি আবারও অবাক করা, যেহেতু SaveChanges
ব্যবহারকারী সংগ্রহস্থলের এই উদাহরণটির সাথে বিশেষভাবে আবদ্ধ।
একটি ডাটাবেস লেনদেন পরিচালনার জন্য সবচেয়ে সোজাসুজি প্যাটার্ন হ'ল বাইরের using
ব্লক:
using (DataContext context = new DataContext())
{
_userRepository.Add(context, user);
context.SaveChanges();
notifier.SendUserCreatedNotification(user);
}
এটি প্রোগ্রামারকে স্পষ্ট নিয়ন্ত্রণ দেয় যখন সমস্ত সংগ্রহস্থলের জন্য পরিবর্তনগুলি সংরক্ষণ করা হয়, কোডটি বাধ্যতামূলকভাবে ঘটনার আগে অবশ্যই ঘটে যাওয়া ঘটনার ক্রমটি নথিভুক্ত করতে বাধ্য করে, ত্রুটির উপর একটি রোলব্যাক জারি করা নিশ্চিত করে (রোলব্যাক ইস্যু করে ধরে নেওয়া হয় DataContext.Dispose
) এবং লুকানো এড়ানো রাষ্ট্রীয় শ্রেণীর মধ্যে সংযোগ।
আমি অনুরোধে সরাসরি ইমেলটি না প্রেরণা করব। একটি সারিতে কোনও বিজ্ঞপ্তির প্রয়োজনীয়তা রেকর্ড করা আরও দৃust ় হবে। এটি আরও ভাল ব্যর্থতা পরিচালনা করার অনুমতি দেবে। বিশেষত, যদি ইমেলটি প্রেরণে কোনও ত্রুটি দেখা দেয় তবে ব্যবহারকারীকে বাঁচাতে ব্যর্থ না করে পরে এটি আবার চেষ্টা করা যেতে পারে এবং এটি ব্যবহারকারীকে যেখানে তৈরি করা হয়েছিল তা এড়ানো হয় তবে সাইট দ্বারা ত্রুটি ফিরে আসে।
using (DataContext context = new DataContext())
{
_userRepository.Add(context, user);
_emailNotificationQueue.AddUserCreateNotification(user);
_emailNotificationQueue.Commit();
context.SaveChanges();
}
প্রথমে বিজ্ঞপ্তিটির সীমাবদ্ধতা তৈরি করা ভাল, যেহেতু context.SaveChanges()
কলের গ্রাহকরা ইমেলটি প্রেরণের আগে ব্যবহারকারী কল রয়েছে কিনা তা যাচাই করতে পারে the (অন্যথায়, হাইজেনব্যাগগুলি এড়াতে আপনার একটি দ্বি-পর্যায়ের প্রতিশ্রুতিবদ্ধ কৌশল প্রয়োজন)
নীচের লাইনটি ব্যবহারিক হতে হবে। প্রকৃতপক্ষে কোনও নির্দিষ্ট উপায়ে লেখার কোডের পরিণতিগুলি (ঝুঁকি এবং সুবিধার দিক দিয়ে) এর মাধ্যমে চিন্তা করুন। আমি দেখতে পাই যে "একক দায়িত্বের নীতি" আমাকে প্রায়শই এটি করতে সহায়তা করে না, যখন "নূন্যতম অবাকের নীতি" আমাকে প্রায়শই অন্য বিকাশকারীর মাথায় getুকতে (তাই কথা বলতে) সহায়তা করে এবং কী ঘটতে পারে তা ভাবতে সহায়তা করে।