একক দায়িত্ব নীতি প্রযোজ্য


40

আমি সম্প্রতি একটি আপাতদৃষ্টিতে তুচ্ছ স্থাপত্য সমস্যা দ্বারা এসেছি। আমার কোডটিতে আমার একটি সাধারণ সংগ্রহস্থল ছিল যা এই জাতীয় নামে পরিচিত (কোডটি সি # তে রয়েছে):

var user = /* create user somehow */;
_userRepository.Add(user);
/* do some other stuff*/
_userRepository.SaveChanges();

SaveChanges একটি সাধারণ মোড়ক ছিল যা ডাটাবেসে পরিবর্তিত হয়:

void SaveChanges()
{
    _dataContext.SaveChanges();
    _logger.Log("User DB updated: " + someImportantInfo);
}

তারপরে, কিছু সময়ের পরে, আমার নতুন যুক্তি প্রয়োগ করা দরকার যা প্রতিবার সিস্টেমটিতে ব্যবহারকারী তৈরি হওয়ার সময় ইমেল বিজ্ঞপ্তি প্রেরণ করবে। যেহেতু সিস্টেমে _userRepository.Add()এবং তার SaveChangesআশেপাশে প্রচুর কল ছিল , তাই আমি এইভাবে আপডেট করার সিদ্ধান্ত নিয়েছি SaveChanges:

void SaveChanges()
{
    _dataContext.SaveChanges();
    _logger.Log("User DB updated: " + someImportantInfo);
    foreach (var newUser in dataContext.GetAddedUsers())
    {
       _eventService.RaiseEvent(new UserCreatedEvent(newUser ))
    }
}

এইভাবে, বাহ্যিক কোড ইউজারক্রিটড এভেন্টের সাবস্ক্রাইব করতে পারে এবং প্রয়োজনীয় ব্যবসায়ের যুক্তি হ্যান্ডল করতে পারে যা বিজ্ঞপ্তি প্রেরণ করবে।

তবে এটি আমার দিকে ইঙ্গিত করা হয়েছিল যে আমার পরিবর্তনটি SaveChangesএকক দায়িত্বের নীতি লঙ্ঘন করেছে এবং এটি SaveChangesকেবল কোনও ইভেন্টকে বাঁচাতে এবং অগ্নিসংযোগ না করা উচিত।

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


22
আপনার প্রতিবেদনটি হ'ল: "ঠিক আছে, আপনি কীভাবে এটি লিখবেন যাতে এটি এসআরপি লঙ্ঘন করে না তবে তবুও একক বিন্দু পরিবর্তনের অনুমতি দেয়?"
রবার্ট হার্ভে

43
আমার পর্যবেক্ষণ হ'ল কোনও ইভেন্ট উত্থাপন কোনও অতিরিক্ত দায়িত্ব যুক্ত করে না। আসলে, একেবারে বিপরীত: এটি অন্য কোথাও দায়িত্ব অর্পণ করে।
রবার্ট হার্ভে

আমি মনে করি আপনার সহকর্মী সঠিক, তবে আপনার প্রশ্নটি বৈধ এবং কার্যকর, তাই উত্সাহিত!
আন্দ্রেস এফ

16
একক দায়িত্বের সুনির্দিষ্ট সংজ্ঞা হিসাবে এমন কোনও জিনিস নেই। যে ব্যক্তি এটি নির্দেশ করে যে এটি এসআরপি লঙ্ঘন করেছে তাদের ব্যক্তিগত সংজ্ঞা ব্যবহার করে সঠিক এবং আপনি নিজের সংজ্ঞাটি ব্যবহার করে সঠিক। আমি মনে করি আপনার নকশাটি সতর্কতার সাথে পুরোপুরি সূক্ষ্ম this ধারাবাহিকতা এসআরপি-র মতো কিছু অস্পষ্ট গাইডলাইনটির চেয়ে মনোযোগ দেওয়া অনেক বেশি গুরুত্বপূর্ণ, যা চূড়ান্ত পর্যায়ে পৌঁছেছিল এমন ক্লাসগুলি বোঝার জন্য যে খুব সহজেই শেষ হয়েছিল, কোনও পদ্ধতিতে কীভাবে কাজ করা যায় তা কেউ জানে না।
ডাব

উত্তর:


14

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

তাই হ্যাঁ , ঘটনা বলবিজ্ঞান এনকোডিং লগিং সেইসাথে এক পদ্ধতি মধ্যে সংরক্ষণ সেইসাথে SRP লঙ্ঘন করে । প্রচুর মামলার ক্ষেত্রে এটি সম্ভবত একটি গ্রহণযোগ্য লঙ্ঘন, বিশেষত যখন কেউ কখনই "পরিবর্তনগুলি সংরক্ষণ করুন" রক্ষণাবেক্ষণের দায়িত্বগুলি বিভিন্ন দল / রক্ষণাবেক্ষণকারীগুলিতে বিতরণ করতে চায় না। তবে একদিন ধরে নেওয়া যাক যে কেউ একেবারে এটি করতে চায়, এটি কি সহজ পদ্ধতিতে সমাধান করা যেতে পারে, those উদ্বেগের কোডটি বিভিন্ন শ্রেণির পাঠাগারগুলিতে রেখে?

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

// In EventFiringUserRepo:
public void SaveChanges()
{
  _basicRepo.SaveChanges();
   FireEventsForNewlyAddedUsers();
}

private void FireEventsForNewlyAddedUsers()
{
  foreach (var newUser in _basicRepo.DataContext.GetAddedUsers())
  {
     _eventService.RaiseEvent(new UserCreatedEvent(newUser))
  }
}

@ পিটারের সর্বাধিক ভোট দেওয়া উত্তরের পংক্তিতে আপনি প্রক্সি ক্লাসকে আ কল করতে পারেন NotifyingRepositoryবা ObservableRepositoryযদি চান তবে (যা আসলে এসআরপি লঙ্ঘন কীভাবে সমাধান করা যায় তা কেবল জানায় না, কেবল লঙ্ঘনটি ঠিক আছে)।

ক্লাসিক প্রক্সি প্যাটার্ন বর্ণনায় বর্ণিত , নতুন এবং পুরানো সংগ্রহস্থল শ্রেণীর উভয়ই একটি সাধারণ ইন্টারফেস থেকে নেওয়া উচিত ।

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

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

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


3
এই উত্তর ছাড়াও। প্রক্সিগুলির বিকল্প রয়েছে, যেমন এওপি
লাইভ

1
আমি মনে করি আপনি এই বিষয়টিটি মিস করেছেন, এটি এমন নয় যে কোনও ইভেন্ট উত্থাপনের ফলে এসআরপি এটি ভেঙে যায় যে কেবল "নতুন" ব্যবহারকারীদের জন্য একটি ইভেন্ট উত্থাপনের জন্য "নতুন আমার সাথে যুক্ত হওয়া" পরিবর্তে "নতুন" ব্যবহারকারীর গঠন কী তা জানার জন্য রেপোকে দায়বদ্ধ করা উচিত not "ব্যবহারকারী
ইওয়ান

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

2
এটি সেরা / সঠিক উত্তর আইএমও। এটি কেবল এসআরপি বজায় রাখে তা নয়, এটি ওপেন / ক্লোজড নীতিও বজায় রাখে। এবং ক্লাসের মধ্যে পরিবর্তনগুলি ভেঙে যেতে পারে এমন সমস্ত স্বয়ংক্রিয় পরীক্ষার কথা ভাবেন of নতুন কার্যকারিতা যুক্ত করার সময় বিদ্যমান পরীক্ষাগুলি সংশোধন করা বড় গন্ধ।
কিথ পায়েন

1
যদি কোনও লেনদেন প্রক্রিয়াধীন থাকে তবে এই সমাধানটি কীভাবে কাজ করবে? যখন এটি চলছে, SaveChanges()আসলে ডাটাবেস রেকর্ড তৈরি করে না এবং এটি আবার ঘূর্ণায়মান হয়ে উঠতে পারে। দেখে মনে হচ্ছে আপনাকে AcceptAllChangesলেনদেন কমপ্লিট ইভেন্টটি ওভাররাইড বা সাবস্ক্রাইব করতে হবে।
জন উ

29

অবিরাম ডেটা স্টোর পরিবর্তিত হয়েছে এমন একটি বিজ্ঞপ্তি পাঠানো সংরক্ষণ করার সময় কোনও বুদ্ধিমান জিনিস বলে মনে হচ্ছে।

অবশ্যই আপনার অ্যাডকে একটি বিশেষ কেস হিসাবে বিবেচনা করা উচিত নয় - আপনাকে সংশোধন এবং মুছার জন্য ইভেন্টগুলি চালিয়ে যেতে হবে। এটি "অ্যাড" মামলার বিশেষ চিকিত্সা যা দুর্গন্ধযুক্ত, পাঠককে কেন এটি গন্ধে তা বোঝাতে বাধ্য করে এবং শেষ পর্যন্ত কোডটির কিছু পাঠককে এই সিদ্ধান্তে পৌঁছে দেয় যে এটি এসআরপি লঙ্ঘন করতে হবে।

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


তবে একটি "নোটিফিং" ভান্ডার আসলে কী আপনার প্রয়োজন? আপনি সি # এর উল্লেখ করেছেন: অনেক লোক একমত হবে যে যখন আপনি যখন প্রয়োজন তখন তার System.Collections.ObjectModel.ObservableCollection<>পরিবর্তে ব্যবহার করা System.Collections.Generic.List<>হ'ল সব ধরণের খারাপ এবং ভুল, তবে অল্প কিছু লোক তত্ক্ষণাত এসআরপিকে নির্দেশ করবে।

আপনি এখন যা করছেন তা UserList _userRepositoryএকটি দিয়ে আপনার অদলবদল করছে ObservableUserCollection _userRepository। যদি এটি কর্মের সেরা কোর্স না হয় তবে আবেদনের উপর নির্ভর করে। তবে এটি নিঃসন্দেহে _userRepositoryযথেষ্ট কম লাইটওয়েট করে তোলে , আমার বিনীত মতে এটি এসআরপি লঙ্ঘন করে না।


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

@ ডকব্রাউন আমি পরিচিত ক্লাসগুলি ObservableCollection<>এবং List<>তুলনা এবং প্রসঙ্গের জন্য প্রার্থনা করেছি । আমি অভ্যন্তরীণ বাস্তবায়ন বা বাহ্যিক ইন্টারফেসের জন্য প্রকৃত ক্লাসগুলি ব্যবহার করার সুপারিশ করার অর্থ চাইনি।
পিটার

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

16

হ্যাঁ, এটি একক দায়িত্বের নীতি এবং একটি বৈধ পয়েন্ট লঙ্ঘন।

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

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

সংগ্রহস্থলটি জানেন না যে আপনি যুক্ত করা ব্যবহারকারী একজন নতুন ব্যবহারকারী। এর দায়বদ্ধতাটি কেবল ব্যবহারকারীকে সংরক্ষণ করা।

এটি সম্ভবত নীচের মন্তব্যে প্রসারিত মূল্যবান।

সংগ্রহস্থলটি জানেন না যে আপনি যুক্ত করেছেন এমন একটি নতুন ব্যবহারকারী - হ্যাঁ এটি করে, এটিতে অ্যাড নামে একটি পদ্ধতি রয়েছে। এর শব্দার্থক শব্দগুলি বোঝায় যে সমস্ত যুক্ত ব্যবহারকারীরা নতুন ব্যবহারকারী। সেভ কল করার আগে অ্যাডে পাস হওয়া সমস্ত যুক্তি একত্রিত করুন - এবং আপনি সমস্ত নতুন ব্যবহারকারী পান

ত্রুটিপূর্ণ. আপনি "সংগ্রহস্থলীতে যুক্ত হয়েছেন" এবং "নতুন" কে কনফ্লেট করছেন।

"সংগ্রহস্থলীতে যুক্ত হয়েছে" এর অর্থ যা বলা হয় ঠিক তার অর্থ। আমি বিভিন্ন সংগ্রহস্থলে ব্যবহারকারীদের যুক্ত করতে এবং অপসারণ করতে এবং পুনরায় যুক্ত করতে পারি।

"নতুন" ব্যবসায়ের নিয়ম দ্বারা সংজ্ঞায়িত ব্যবহারকারীর একটি রাষ্ট্র।

বর্তমানে ব্যবসায়ের নিয়মটি হতে পারে "নতুন == কেবলমাত্র সংগ্রহস্থলটিতে যুক্ত করা হয়েছে", তবে এর অর্থ এই নয় যে এই নিয়মটি সম্পর্কে জানতে এবং প্রয়োগ করা কোনও পৃথক দায়িত্ব নয়।

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

এই উত্তরটি আইএমএইচও হ'ল যথেষ্ট বিন্দু: রেপো হ'ল কোডের একমাত্র কেন্দ্রীয় স্থান যা নতুন ব্যবহারকারী যুক্ত হওয়ার সময় জানে

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

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


11
ভান্ডারটি জানেন না যে আপনি যুক্ত করা ব্যবহারকারী একজন নতুন ব্যবহারকারী - হ্যাঁ এটি করে, এর একটি পদ্ধতি বলা হয় Add। এর শব্দার্থক শব্দগুলি বোঝায় যে সমস্ত যুক্ত ব্যবহারকারীরা নতুন ব্যবহারকারী। Addকল করার আগে পাস হওয়া সমস্ত যুক্তি একত্রিত করুন Save- এবং আপনি সমস্ত নতুন ব্যবহারকারী পান।
আন্দ্রে বোর্জেস ২

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

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

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

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

7

এটি কি বৈধ পয়েন্ট?

হ্যাঁ এটি হ'ল যদিও এটি আপনার কোডের কাঠামোর উপর অনেক বেশি নির্ভর করে। আমার সম্পূর্ণ প্রসঙ্গ নেই তাই আমি সাধারণভাবে কথা বলার চেষ্টা করব।

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

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

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

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

এখন আপনার নির্দিষ্ট উদাহরণ ফিরে। যদি আপনাকে অবশ্যই কোনও বিজ্ঞপ্তি প্রেরণ করতে হবে যখনই কোনও ব্যবহারকারী তৈরি হবে এবং সম্ভবত আরও আরও বিশেষায়িত ক্রিয়াকলাপ সম্পাদন করা উচিত, তবে আপনি একটি পৃথক পরিষেবা তৈরি করতে পারেন UserCreationServiceযা এই প্রয়োজনীয়তাটি সজ্জিত করে, এমন একটি পদ্ধতি যা একটি পদ্ধতি প্রকাশ করে Add(user), যা উভয় স্টোরেজ পরিচালনা করে (কল আপনার সংগ্রহস্থলটিতে) এবং একক ব্যবসায়ের ক্রিয়া হিসাবে বিজ্ঞপ্তি। বা পরে এটি আপনার আসল স্নিপেটে করুন_userRepository.SaveChanges();


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

2
If the purpose of my event would be to send new user data to Google Analytics - then disabling it would have the same business effect as disabling logging: not critical, but pretty upsetting । আপনি যদি অকাল "নিউজ" তৈরির অকাল ঘটনাগুলিতে গুলি চালাচ্ছেন তবে কি হবে। বিশ্লেষণগুলি "ব্যবহারকারীদের" বিবেচনায় নিচ্ছে যা শেষ পর্যন্ত ডিবি লেনদেনের সাথে ত্রুটির কারণে তৈরি হয়নি? যদি সংস্থাটি মিথ্যা প্রাঙ্গণে সিদ্ধান্ত গ্রহণ করে থাকে, অবৈধ ডেটা দ্বারা সমর্থিত? আপনি ইস্যুটির প্রযুক্তিগত দিকটি সম্পর্কে খুব বেশি মনোনিবেশ করেছেন। "কখনও কখনও আপনি গাছের জন্য কাঠ দেখতে পারবেন না"
লাইভ

@ লাইভ, আপনি একটি বৈধ পয়েন্ট দিচ্ছেন, তবে এটি আমার প্রশ্নের বা এই উত্তরের বিষয় নয়। প্রশ্নটি এসআরপি প্রসঙ্গে এটি একটি বৈধ সমাধান কিনা, তাই ধরে নেওয়া যাক কোনও ডিবি লেনদেনের ত্রুটি নেই।
আন্দ্রে বোর্জেস

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

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

4

SRP, তত্ত্বগতভাবে সম্পর্কে, মানুষ যেমন আঙ্কেল বব তার প্রবন্ধে ব্যাখ্যা করে, একক দায়িত্ব নীতিরবার্ট হার্ভে আপনার মন্তব্যে এটি প্রদানের জন্য ধন্যবাদ।

সঠিক প্রশ্নটি হ'ল:

কোন "অংশীদার" "ইমেল প্রেরণ" প্রয়োজনীয়তা যুক্ত করেছেন?

যদি সেই স্টেকহোল্ডার ডেটা অধ্যবসায় দায়িত্বে থাকে (সম্ভাব্য তবে সম্ভব) তবে এটি এসআরপি লঙ্ঘন করে না। অন্যথায়, এটা না।


2
আকর্ষণীয় - এসআরপি-র এই ব্যাখ্যাটি আমি কখনও শুনিনি। এই ব্যাখ্যা সম্পর্কে আপনার আরও তথ্য / সাহিত্যের কোনও পয়েন্টার রয়েছে?
স্লেজ

2
@ স্লেসকে: আঙ্কেল বব নিজে থেকে : "এবং এটি একক দায়িত্বের নীতিমালার কাছে পৌঁছেছে This এই নীতিটি লোকদের সম্পর্কে you একটি একক ব্যক্তি, বা বরং, একক সংকীর্ণ সংজ্ঞায়িত ব্যবসায়িক ক্রিয়াকলাপ উপস্থাপন করে এমন একক দৃ coup়ভাবে যুগল লোক group "
রবার্ট হার্ভে

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

1
হাঁ। REST শব্দটির ক্ষেত্রে এটিই ঘটেছিল। এমনকি রায় ফিল্ডিংও বলেছেন যে লোকেরা এটিকে ভুল ব্যবহার করছে।
রবার্ট হার্ভে

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

2

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

কোনও ব্যবহারকারী তৈরি করা, কোনও নতুন ব্যবহারকারী কী এবং তার অধ্যবসায় 3 ভিন্ন জিনিস তা স্থির করে নেওয়া

আমার প্রেমেস

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

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

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

এটি কি বৈধ পয়েন্ট?

এটা হতে পারে. তবে, আমি এটা বলতে সাহস করব যে এটি কেবল এসআরপি (প্রযুক্তিগতভাবে বলতে হবে) এটি নয়, এটি সুবিধার বিষয়ও (কার্যকরীভাবে বলা))

  • ব্যবসায়ের ক্রিয়াকলাপটি অব্যাহত রয়েছে এমন উপাদানগুলি থেকে ব্যবসায়িক অনুষ্ঠানগুলি চালিত করা কি সুবিধাজনক?
  • তারা কি সঠিক জায়গাটি করার মতো সঠিক মুহুর্তের প্রতিনিধিত্ব করে?
  • আমি কি এই উপাদানগুলিকে এই জাতীয় বিজ্ঞপ্তির মাধ্যমে আমার ব্যবসায়িক যুক্তি অর্কেস্টেট করার অনুমতি দেব?
  • আমি কি অকাল ঘটনার ফলে তৈরি পার্শ্ব প্রতিক্রিয়াগুলি বাতিল করতে পারি? 2

আমার কাছে মনে হচ্ছে যে এখানে ইভেন্ট উত্থাপন করা লগিংয়ের মতো একই জিনিস

একেবারে না. লগিংয়ের কোনও পার্শ্ব প্রতিক্রিয়া না হওয়ার অর্থ, তবে, যেমন আপনি প্রস্তাব করেছিলেন ইভেন্টটি UserCreatedসম্ভবত অন্যান্য ব্যবসায়িক ক্রিয়াকলাপ ঘটাতে পারে। বিজ্ঞপ্তি পছন্দ। 3

এটি কেবল বলেছে যে এই জাতীয় যুক্তি অন্যান্য ক্লাসে আবদ্ধ করা উচিত, এবং কোনও সংগ্রহস্থলের জন্য এই অন্যান্য ক্লাসগুলি কল করা ঠিক হবে

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


1: পর্যাপ্ত পরিমাণে নামকরণ করাও গুরুত্বপূর্ণ।

2: বলুন আমরা UserCreatedপরে প্রেরণ করেছি _dataContext.SaveChanges();, তবে সংযোগ সমস্যা বা লঙ্ঘনের কারণে বাছাইয়ের পরে পুরো ডাটাবেস লেনদেন ব্যর্থ হয়েছিল। অকাল সময়ের সম্প্রচারের সাথে সতর্ক থাকুন, কারণ এর পার্শ্ব প্রতিক্রিয়াগুলি পূর্বাবস্থায় ফেলা শক্ত হতে পারে (যদি তা এমনকি সম্ভব হয়))

3: পর্যাপ্ত পরিমাণে চিকিত্সা না করা বিজ্ঞপ্তি প্রক্রিয়াগুলি আপনাকে নোটিফিকেশনগুলিতে ফেলা হতে পারে যা পূর্বাবস্থায় ফেরা / সাপ> করা যায় না


1
+1 লেনদেনের সময়কাল সম্পর্কে খুব ভাল পয়েন্ট। ব্যবহারকারী তৈরি করা হয়েছে তা জোর দিয়ে বলা অকাল হতে পারে, কারণ রোলব্যাকগুলি ঘটতে পারে; এবং কোনও লগের বিপরীতে, সম্ভবত অ্যাপটির অন্য কোনও অংশ ইভেন্টটির সাথে কিছু করে।
আন্দ্রেস এফ

2
যথাযথভাবে। ইভেন্টগুলি নিশ্চিততা বোঝায়। কিছু ঘটল কিন্তু শেষ।
লাইভ

1
@ লাইভ: বাদে যখন তারা না করে। মাইক্রোসফ্টের সমস্ত ধরণের ইভেন্টের উপসর্গ রয়েছে Beforeবা Previewযা নিশ্চিততার কোনও নিশ্চয়তা দেয় না।
রবার্ট হার্ভে

1
@ jpmc26: বিকল্প ছাড়া আপনার পরামর্শটি কার্যকর নয়।
রবার্ট হার্ভে

1
@ জেএমপিসি 26: সুতরাং আপনার উত্তরটি হল "সরঞ্জাম এবং পারফরম্যান্সের বৈশিষ্ট্যগুলির সম্পূর্ণ ভিন্ন সেট সহ সম্পূর্ণ ভিন্ন বিকাশ বাস্তুতন্ত্রে পরিবর্তন"। আমাকে বিপরীতে কল করুন, তবে আমি কল্পনা করব যে এটি বিপুল সংখ্যক উন্নয়ন প্রচেষ্টার জন্য অপরিবর্তনীয়।
রবার্ট হার্ভে

1

না এটি এসআরপি লঙ্ঘন করে না।

অনেকে মনে করেন সিঙ্গল দায়বদ্ধতার নীতিমালার অর্থ একটি ফাংশনটি কেবল "একটি জিনিস" করা উচিত এবং তারপরে "একটি জিনিস" কী কী তা নিয়ে আলোচনায় জড়িয়ে পড়ে।

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

তবে কোনও ইভেন্টে গুলি চালানো তখন এসআরপি লঙ্ঘন করে না, যেহেতু ইভেন্টটি কেবল ব্যবহারকারীকে বাঁচাতে নির্ভর করে, অন্য কোনও উদ্বেগের উপর নয়। ইভেন্টগুলি আসলে এসআরপি সমুন্নত রাখার একটি দুর্দান্ত উপায়, যেহেতু আপনি মেল দ্বারা - বা এমনকি জেনেও জেনে না রেজিস্ট্রি দ্বারা প্রভাবিত না হয়ে সেভ দ্বারা ইমেলটি ট্রিগার করতে পারেন।


1

একক দায়িত্ব নীতি সম্পর্কে চিন্তা করবেন না। এটি আপনাকে এখানে একটি ভাল সিদ্ধান্ত নিতে সহায়তা করবে না কারণ আপনি বিষয়গতভাবে একটি "ধারণা" হিসাবে একটি নির্দিষ্ট ধারণা চয়ন করতে পারেন। আপনি বলতে পারেন যে শ্রেণীর দায়িত্বটি ডাটাবেসে ডেটা অধ্যবসায় পরিচালনা করা, বা আপনি বলতে পারেন যে এর দায়বদ্ধতা একটি ব্যবহারকারী তৈরি সম্পর্কিত সমস্ত কাজ সম্পাদন করা 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ুকতে (তাই কথা বলতে) সহায়তা করে এবং কী ঘটতে পারে তা ভাবতে সহায়তা করে।


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

4
আপনি মূলত "ইভেন্টগুলি ব্যবহার করবেন না" যুক্তিটি তৈরি করছেন।
রবার্ট হার্ভে

3
[শ্রাগ] বেশিরভাগ ইউআই ফ্রেমওয়ার্কের জন্য ইভেন্টগুলি কেন্দ্রীয় হয়। ইভেন্টগুলি মুছে ফেলুন এবং সেই ফ্রেমওয়ার্কগুলি কোনওভাবেই কাজ করে না।
রবার্ট হার্ভে

2
@ jpmc26: একে এএসপি.এনইটি ওয়েবফর্ম বলে। এটি স্তন্যপান।
রবার্ট হার্ভে

2
My repository is not sending emails. It just raises an eventকারণ ঘটে. সংগ্রহস্থলটি বিজ্ঞপ্তি প্রক্রিয়াটি ট্রিগার করছে।
লাইভ

0

বর্তমানে SaveChangesআছে দুই জিনিস: তবে পরিবর্তনটি সংরক্ষণ এবং এটি তাই আছে লগ করা হয়। এখন আপনি এটিতে আরও একটি জিনিস যুক্ত করতে চান: ইমেল বিজ্ঞপ্তিগুলি প্রেরণ করুন।

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

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

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


-1

কোডটি ইতিমধ্যে এসআরপি লঙ্ঘন করেছে - একই শ্রেণি ডেটা প্রসঙ্গে এবং লগিংয়ের সাথে যোগাযোগের জন্য দায়বদ্ধ ছিল।

আপনি কেবল এটি 3 টি দায়িত্ব নিয়ে আপগ্রেড করেছেন।

জিনিসগুলিকে ১ টি দায়িত্ব থেকে ফিরানোর একটি উপায় হ'ল বিমূর্ত করা _userRepository; এটি একটি কমান্ড-সম্প্রচারক করুন।

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

এখন, বেশিরভাগ কমান্ডের মধ্যে কেবলমাত্র 1 শ্রোতা থাকতে পারে (ডেটা প্রসঙ্গে)। আপনার পরিবর্তনগুলির পূর্বে SaveChanges এর 2 টি রয়েছে - ডেটা প্রসঙ্গ এবং তারপরে লগার।

আপনার পরিবর্তনগুলি পরে পরিবর্তনগুলি সংরক্ষণ করতে অন্য শ্রোতাকে যুক্ত করে, যা ইভেন্ট পরিষেবাতে নতুন ব্যবহারকারীর তৈরি ইভেন্টগুলি বাড়ানো।

এটির কয়েকটি সুবিধা রয়েছে। আপনি এখন আপনার বাকী কোড কেয়ারিং ছাড়া লগিং কোডটি সরিয়ে, আপগ্রেড করতে বা প্রতিলিপি করতে পারবেন। এটির প্রয়োজন মতো আরও কিছু জিনিসগুলির জন্য সংরক্ষণের পরিবর্তনগুলিতে আপনি আরও ট্রিগার যুক্ত করতে পারেন।

এগুলি যখন _userRepositoryতৈরি হয় এবং তারে আপ হয় (বা, সম্ভবত, সেই অতিরিক্ত বৈশিষ্ট্যগুলি ফ্লাইতে যুক্ত করা / মুছে ফেলা হয়; অ্যাপ্লিকেশন চলাকালীন লগিং যোগ / বর্ধন করতে সক্ষম হওয়া) এর সবগুলিই স্থির হয়ে যায় ।

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