رادکام
الگوی Observer یکی از الگوهای رفتاری می باشد. همان طور که از نام این الگو مشخص است، در این الگو برخی اشیا عملکرد شی خاصی را مشاهده یا رصد می کنند و هر گونه تغییر در وضعیت شی مورد نظر بر روی اشیا ناظر تاثیر گذار خواهد بود. به این ترتیب وابستگی بین اشیا ناظر و شی هدف وجود دارد و نیاز است که همه اشیا ناظر از هر گونه تغییر حالت شی هدف اطلاع پیدا کنند. یکی از راه حل هایی که برای این سناریو وجود دارد استفاده از حلقه For می باشد. اما این راه حل هزینه بر بوده و کارایی را کاهش می دهد. لذا در چنین مواردی استفاده از الگوی Observer بسیار کمک کننده خواهد بود. این الگوی طراحی بسیار کاربردی می باشد و از ارتباط Broadcast پشتیبانی می کند. Observer یکی از مهمترین بخش های معماری MVC محسوب می شود.
الگوی Observer را می توان در موارد زیر استفاده نمود:
در مواردی پس از ایجاد تغییر در یک شیء قرار باشد که به سایر اشیاء بدون توجه به نوع و نحوه پیاده سازی آن ها اطلاع رسانی شود.
برای ارتباط بین Subject و Observer دو روش وجود دارد:
همان طور که در دیاگرام مشخص است نمودار کلاس الگوی Observer شامل کلاس های زیر است:
در ادامه، پیاده سازی این الگو را در یک مثال توضیح می دهیم:
همان طور که می دانیم، در بورس شرکت ها و سهامداران مختلفی وجود دارند و هر کدام از سهامداران ممکن است سهام یک یا چندین شرکت را داشته باشند. بنابراین تغییر در قیمت هر کدام از شرکت ها برای شهامداران آن شرکت مهم بوده و نیاز دارند که از تغییرات شرکت خود اطلاع داشته باشند. در صورتی که بخواهیم اطلاع رسانی برای هر سهامدار در هر شرکت را با استفاده از عملگرهای کنترلی حلقه ها پیاده سازی نماییم ممکن است کاری پر هزینه باشد اما این سناریو به راحتی می تواند با استفاده از الگوی طراحی Observer پیاده سازی شود.
کلاس Stock که در واقع کلاس هدف می باشد و پیاده سازی آن به صورت زیر انجام می شود:
abstract class Stock
{
private string _symbol;
private double _price;
private List _investors = new List();
public Stock(string symbol, double price)
{
this._symbol = symbol;
this._price = price;
}
public void Attach(IInvestor investor)
{
_investors.Add(investor);
}
public void Detach(IInvestor investor)
{
_investors.Remove(investor);
}
public void Notify()
{
foreach (IInvestor investor in _investors)
{
investor.Update(this);
}
Console.WriteLine("");
}
public double Price
{
get { return _price; }
set
{
if (_price != value)
{
_price = value;
Notify();
}
}
}
public string Symbol
{
get { return _symbol; }
}
}
}
برای هر کدام از شرکت ها مثلا IBM که نقش ConcreteSubject را داشته می توان کلاسی به صورت زیر پیاده سازی نمود که از کلاس Subject ارث بری می کند:
class IBM : Stock
{
public IBM(string symbol, double price)
: base(symbol, price)
{
}
}
Interfaceی برای سهامداران که در واقع به عنوان مشاهده کننده در نظر گرفته می شود تا تغییرات را پیاده سازی نماید و به صورت زیر می باشد:
interface IInvestor
{
void Update(Stock stock);
}
کلاس سهامداران که نقش ConcreteObserver را داشته و از کلاس IInvestor ارث بری نموده است. این کلاس به صورت زیر پیاده سازی می شود:
class Investor : IInvestor
{
private string _name;
private Stock _stock;
// Constructor
public Investor(string name)
{
this._name = name;
}
public void Update(Stock stock)
{
Console.WriteLine("Notified {0} of {1}'s " +
"change to {2:C}", _name, stock.Symbol, stock.Price);
}
// Gets or sets the stock
public Stock Stock
{
get { return _stock; }
set { _stock = value; }
}
}
بنابراین در برنامه می توان پس از تعریف شرکت های مختلف و اختصاص سهامداران مختلف به آن ها، با هر بار تغییر قیمت، بدون درگیر شدن برای پیاده سازی اطلاع رسانی، به سهامداران اطلاع رسانی نمود:
IBM ibm = new IBM("IBM", 120.00);
ibm.Attach(new Investor("Sorros"));
ibm.Attach(new Investor("Berkshire"));
ibm.Price = 120.10;
ibm.Price = 121.00;
ibm.Price = 120.50;
ibm.Price = 120.75;
4,347بازدید
دیدگاه کاربران
هنوز دیدگاهی ثبت نشده است.
شما میتوانید درباره این مقاله، دیدگاه خود را ثبت کنید.