আমার কাজের লক্ষ্যটি একটি ছোট সিস্টেম ডিজাইন করা যা তফসিল পুনরাবৃত্ত কাজগুলি চালাতে পারে। একটি পুনরাবৃত্ত টাস্ক এমন একটি বিষয় যা "সোমবার থেকে শুক্রবার থেকে সকাল 8:00 টা থেকে বিকাল 5:00 পর্যন্ত প্রতি ঘন্টা প্রশাসকের কাছে একটি ইমেল প্রেরণ করুন"।
আমার একটি বেস ক্লাস রয়েছে যা রিচারিংটাস্ক বলে ।
public abstract class RecurringTask{
// I've already figured out this part
public bool isOccuring(DateTime dateTime){
// implementation
}
// run the task
public abstract void Run(){
}
}
এবং আমার বেশ কয়েকটি ক্লাস রয়েছে যা রিকারিং টাস্ক থেকে উত্তরাধিকার সূত্রে প্রাপ্ত । এর মধ্যে একটির নাম সেন্ডইমেইল টাস্ক ।
public class SendEmailTask : RecurringTask{
private Email email;
public SendEmailTask(Email email){
this.email = email;
}
public override void Run(){
// need to send out email
}
}
এবং আমার একটি ইমেল সার্ভিস রয়েছে যা আমাকে ইমেল প্রেরণে সহায়তা করতে পারে।
শেষ শ্রেণিটি রিকারিং টাস্কসিডুলার , এটি ক্যাশে বা ডাটাবেস থেকে কাজগুলি লোড করার জন্য এবং কার্যটি চালনার জন্য দায়ী।
public class RecurringTaskScheduler{
public void RunTasks(){
// Every minute, load all tasks from cache or database
foreach(RecuringTask task : tasks){
if(task.isOccuring(Datetime.UtcNow)){
task.run();
}
}
}
}
এখানে আমার সমস্যা: আমার ইমেল পরিষেবা কোথায় রাখা উচিত ?
OPTION1 : উদ্বুদ্ধ EmailService মধ্যে SendEmailTask
public class SendEmailTask : RecurringTask{
private Email email;
public EmailService EmailService{ get; set;}
public SendEmailTask (Email email, EmailService emailService){
this.email = email;
this.EmailService = emailService;
}
public override void Run(){
this.EmailService.send(this.email);
}
}
আমাদের কোনও সত্তাকে কোনও পরিষেবা ইনজেকশন করা উচিত কিনা তা নিয়ে ইতিমধ্যে কিছু আলোচনা রয়েছে এবং বেশিরভাগ মানুষ সম্মত হন যে এটি একটি ভাল অনুশীলন নয়। এই নিবন্ধটি দেখুন ।
বিকল্প 2: যদি ... পুনরাবৃত্তি টাস্কশেল্ডারে অন্যথায়
public class RecurringTaskScheduler{
public EmailService EmailService{get;set;}
public class RecurringTaskScheduler(EmailService emailService){
this.EmailService = emailService;
}
public void RunTasks(){
// load all tasks from cache or database
foreach(RecuringTask task : tasks){
if(task.isOccuring(Datetime.UtcNow)){
if(task is SendEmailTask){
EmailService.send(task.email); // also need to make email public in SendEmailTask
}
}
}
}
}
আমাকে বলা হয়েছে যদি ... উপরের মতো অন্যরকম castালাই ওও হয় না, এবং আরও সমস্যা আনবে।
বিকল্প 3: রানের স্বাক্ষর পরিবর্তন করুন এবং পরিষেবাবান্ডেল তৈরি করুন ।
public class ServiceBundle{
public EmailService EmailService{get;set}
public CleanDiskService CleanDiskService{get;set;}
// and other services for other recurring tasks
}
এই ক্লাসটি পুনরাবৃত্তকারী টাস্কশেল্ডুলারে ইনজেক্ট করুন
public class RecurringTaskScheduler{
public ServiceBundle ServiceBundle{get;set;}
public class RecurringTaskScheduler(ServiceBundle serviceBundle){
this.ServiceBundle = ServiceBundle;
}
public void RunTasks(){
// load all tasks from cache or database
foreach(RecuringTask task : tasks){
if(task.isOccuring(Datetime.UtcNow)){
task.run(serviceBundle);
}
}
}
}
চালান পদ্ধতি SendEmailTask হবে
public void Run(ServiceBundle serviceBundle){
serviceBundle.EmailService.send(this.email);
}
এই পদ্ধতির সাথে আমি কোনও বড় সমস্যা দেখছি না।
বিকল্প 4 : দর্শনার্থীর প্যাটার্ন।
প্রাথমিক ধারণাটি এমন একটি দর্শনার্থী তৈরি করা যা পরিষেবাবান্ডেলের মতো পরিষেবাগুলিকে সজ্জিত করবে ।
public class RunTaskVisitor : RecurringTaskVisitor{
public EmailService EmailService{get;set;}
public CleanDiskService CleanDiskService{get;set;}
public void Visit(SendEmailTask task){
EmailService.send(task.email);
}
public void Visit(ClearDiskTask task){
//
}
}
এবং আমাদের রান পদ্ধতির স্বাক্ষরও পরিবর্তন করতে হবে । চালান পদ্ধতি SendEmailTask হয়
public void Run(RecurringTaskVisitor visitor){
visitor.visit(this);
}
এটা তোলে ভিজিটর প্যাটার্ন একটি আদর্শ বাস্তবায়ন, এবং পরিদর্শক মধ্যে ইনজেকশনের করা হবে RecurringTaskScheduler ।
সংক্ষেপে: এই চারটি পদ্ধতির মধ্যে কোনটি আমার দৃশ্যের জন্য সেরা? এবং এই সমস্যার জন্য অপশন 3 এবং অপশন 4 এর মধ্যে কোনও বড় পার্থক্য রয়েছে?
অথবা আপনার এই সমস্যা সম্পর্কে আরও ভাল ধারণা আছে? ধন্যবাদ!
5/22/2015 আপডেট করুন : আমি মনে করি অ্যান্ডির উত্তরটি আমার উদ্দেশ্যটিকে খুব ভালভাবে সংক্ষেপ করে; যদি আপনি এখনও সমস্যাটি সম্পর্কে নিজেই বিভ্রান্ত হন তবে আমি প্রথমে তার পোস্টটি পড়ার পরামর্শ দিই।
আমি সবেমাত্র জানতে পেরেছিলাম যে আমার সমস্যা বার্তা প্রেরণের সমস্যার সাথে খুব মিল , যা অপশন 5-এ নিয়ে যায়।
বিকল্প 5 : আমার সমস্যাটিকে বার্তা প্রেরণে রূপান্তর করুন ।
আমার সমস্যা এবং বার্তা প্রেরণের সমস্যাটির মধ্যে একটি থেকে একের ম্যাপিং রয়েছে :
বার্তা প্রেরণকারী : ইম্যাসেজ গ্রহণ করুন এবং তাদের সম্পর্কিত হ্যান্ডলারের কাছে চিত্রের সাব ক্লাস প্রেরণ করুন । Ur পুনরাবৃত্তি টাস্ক শিডুলার
ভাবনা : একটি ইন্টারফেস বা বিমূর্ত শ্রেণি। Ur রিকারিং টাস্ক
MessageA থেকে বর্ধিত করে iMessage , কিছু অতিরিক্ত তথ্য হচ্ছে। → সেন্ডইমেইল টাস্ক
MessageB : আরেকটি উপশ্রেণী iMessage । → ক্লিনডিস্কটাস্ক
ম্যাসেজএইচ্যান্ডলার : ম্যাসেজএ গ্রহণ করার পরে , এটি হ্যান্ডেল করুন → সেন্ডইমেলটাস্কহ্যান্ডলার, এতে ইমেল সার্ভিস রয়েছে, এবং যখন এটি ইমেল পাঠাবে তখন ইমেলটি প্রেরণ করবে
MessageBHandler : হিসাবে একই MessageAHandler কিন্তু হাতল MessageB পরিবর্তে। → ক্লিনডিস্কটাস্কহ্যান্ডলার
সবচেয়ে শক্তিশালী অংশটি হ'ল বিভিন্ন হ্যান্ডলারের কাছে বিভিন্ন ধরণের ইমেসেজ প্রেরণ করা যায় । এখানে একটি দরকারী লিঙ্ক ।
আমি সত্যিই এই পদ্ধতির পছন্দ করি, এটি পরিষেবা সহ আমার সত্তাকে কলুষিত করে না এবং এর কোনও God শ্বর শ্রেণি নেই।
SendEmailTask
আমার কাছে সত্তার চেয়েও কোনও সেবার মতো মনে হয়। আমি দ্বিধা এবং দ্বিধা ছাড়াই বিকল্প 1 এ যাব।
accept
দর্শকদের শ্রেণিবদ্ধ কাঠামো । দর্শনার্থীর জন্য অনুপ্রেরণা হ'ল আপনার কয়েকটি সামগ্রীতে অনেক শ্রেণির ধরণের রয়েছে যা দেখার দরকার এবং প্রতিটি নতুন কার্যকারিতা (অপারেশন) এর জন্য তাদের কোডটি সংশোধন করা সুবিধাজনক নয়। আমি এখনও এই সামগ্রিক অবজেক্টগুলি কী তা দেখতে পাচ্ছি না এবং ভিজিটর উপযুক্ত নয় বলে মনে করি। যদি এটি হয় তবে আপনার প্রশ্নটি সম্পাদনা করা উচিত (যা দর্শকদের বোঝায়)।