در ادامه مطلب قبلی، یکی از مشکلاتی که طراحی Builder از آن رنج میبرد، نقض کردن قانون command query separation است که در ادامه دربارهی این اصل بیشتر بحث خواهیم کرد.
اصل Command query separation یا به اختصار CQS، در کتاب Object-Oriented Software Construction توسط Bertrand Meyer معرفی شدهاست. بر اساس آن، عملیاتهای سیستم باید یا Command باشند و یا Query و نه هر دوی آنها. وقتی یک کلاینت به امضای یک متد توجه میکند، اینکه این متد چه کاری را انجام میدهد Commands نام داشته و به شیء فرمان میدهد تا کاری را انجام بدهد. این عملیات وضعیت خود شیء و یا اشیاء دیگر را تغییر میدهد. در اینجا Queries به شیء فرمان میدهند تا نتیجهی سؤال ( ویا درخواست) را برگرداند.
در آن سوی دیگر، متدهایی را که وضعیت شیء را تغییر میدهند، به عنوان Command در نظر میگیریم (بدون آنکه مقداری را برگردانند). اگر این نوع متدها، مقداری را برگردانند، باعث سردرگمی کلاینت میشوند؛ زیرا کلاینت نمیداند این متد باعث تغییر شیء شدهاست و یا Query؟
public class FileStore { public string WorkingDirectory { get; set; } public string Save(int id, string message) { var path = Path.Combine(this.WorkingDirectory + id + ".txt"); File.WriteAllText(path, message); return path; } public event EventHandler<MessageEventArgs> MessageRead; public void Read(int id) { var path = Path.Combine(this.WorkingDirectory + id + ".txt"); var msg = File.ReadAllText(path); this.MessageRead(this, new MessageEventArgs { Message = msg }); } }
public string Read(int id) { var path = Path.Combine(this.WorkingDirectory + id + ".txt"); var msg = File.ReadAllText(path); this.MessageRead(this, new MessageEventArgs { Message = msg }); return msg; }
public void Save(int id, string message) { var path = Path.Combine(this.WorkingDirectory + id + ".txt"); File.WriteAllText(path, message); }
public class FileStore { public string WorkingDirectory { get; set; } public void Save(int id, string message) { var path = GetFileName(id); //ok to query from Command File.WriteAllText(path, message); } public string Read(int id) { var path = GetFileName(id); var msg = File.ReadAllText(path); return msg; } public string GetFileName(int id) { return Path.Combine(this.WorkingDirectory , id + ".txt"); } }
چکیده:
هدف اصلی از طراحی نرم افزار، غالب شدن بر پیچیدگیها میباشد. اصل CQS متدها را به دو دستهی Command و Query تقسیم میکند که Query ، اطلاعاتی را از وضعیت سیستم بر میگرداند، ولی command وضعیت سیستم را تغییر میدهد و مهمترین دستاورد CQS ما را به سمت کدی تمیزتر و با قابلیت درک بهتر میرساند.