但同时我们看到,再新出现一个移动设备这样的通知对象,Microsoft类仍然需要改变,对此我们再做如下重构,在Microsoft中维护一个IObserver列表,同时提供相应的维护方法。
图5 静态UML示例图
Microsoft类的实现代码如下:
public class Microsoft { private List<IObserver> observers = new List<IObserver>(); private String _symbol; private double _price; public void Update() { foreach (IObserver ob in observers) { ob.SendData(this); } } public void AddObserver(IObserver observer) { observers.Add(observer); } public void RemoveObserver(IObserver observer) { observers.Remove(observer); } public String Symbol { get { return _symbol; } set { _symbol = value; } } public double Price { get { return _price; } set { _price = value; } } }
此时客户端的调用代码:
class Program { static void Main(string[] args) { IObserver investor1 = new Investor("Jom"); IObserver investor2 = new Investor("TerryLee"); Microsoft ms = new Microsoft(); ms.Symbol = "Microsoft"; ms.Price = 120.00; ms.AddObserver(investor1); ms.AddObserver(investor2); ms.Update(); Console.ReadLine(); } }
走到这一步,已经有了Observer模式的影子了,Microsoft类不再依赖于具体的Investor,而是依赖于抽象的IOberver。存在着的一个问题是Investor仍然依赖于具体的公司Microsoft,况且公司还会有很多IBM,Google等,解决这样的问题很简单,只需要再对Microsoft类做一次抽象。如下图所示:
图6 静态UML示例图
实现代码如下:
public abstract class Stock { private List<IObserver> observers = new List<IObserver>(); private String _symbol; private double _price; public Stock(String symbol, double price) { this._symbol = symbol; this._price = price; } public void Update() { foreach (IObserver ob in observers) { ob.SendData(this); } } public void AddObserver(IObserver observer) { observers.Add(observer); } public void RemoveObserver(IObserver observer) { observers.Remove(observer); } public String Symbol { get { return _symbol; } } public double Price { get { return _price; } } } public class Microsoft : Stock { public Microsoft(String symbol, double price) : base(symbol, price) { } } public interface IObserver { void SendData(Stock stock); } public class Investor : IObserver { private string _name; public Investor(string name) { this._name = name; } public void SendData(Stock stock) { Console.WriteLine("Notified {0} of {1}'s " + "change to {2:C}", _name, stock.Symbol,stock.Price); } }
客户端程序代码如下:
class Program { static void Main(string[] args) { Stock ms = new Microsoft("Microsoft",120.00); ms.AddObserver(new Investor("Jom")); ms.AddObserver(new Investor("TerryLee")); ms.Update(); Console.ReadLine(); } }
到这里我们可以看到,通过不断的重构,不断地抽象,我们由一开始的很糟糕的设计,逐渐重构为使用Observer模式的这样一个方案。在这个例子里面,IOberser充当了观察者的角色,而Stock则扮演了主题对象角色,在任何时候,只要调用了Stock的Update()方法,它就会通知它的所有观察者对象。同时可以看到,通过Observer模式,取消了直接依赖,变为间接依赖,这样大大提供了系统的可维护性和可扩展性。