发布订阅模型
这样,我们可以将BackAccount类改写为:
简单的观察者模式已经实现了。当然根据业务需求,这段代码还可以再进行抽象,不断提取变化的部分,封装变化的部分。
软件设计是一个动态变化的过程,一个对象的状态发生变化要通知给依赖他的其他对象,并使其他对象能够自动更新。如果这种依赖过于紧密,将使软件不能很好地抵御变化。
我们在取钱的时候,当银行账户里的金额发生变化的时候,需要通知给用户。及一个对象的状态发生变化的时候需要通知给其他对象,让其他的对象得到更新。这里我们应该是当账户金额变化的时候用户的email和手机应该得到通通知,从而更新。代码如下:
class BackAccunt
{
Email email = new Email();
Mobile mobile=new Mobile();
public void SetMoney(int data)
{
//存钱操作,
//....
email.SendEmail();
mobile.SendPhone();
}
}
public class Email
{
public void SendEmail()
{
}
}
public class Mobile
{
public void SendPhone()
{
}
}
这样写当然没错,当我们每次取完钱以后调用相应的方法,通知给其他对象,但是这种写法账户金额这个类与Email类、mobil类是紧耦合的关系,依赖性很强,这样的设计的软件是很不稳定的。并且如果我想增加一个qq,增加一个手机通知类,每次只能重新new,这样做很不利于后期的扩展。也就是说我们要通知的对象不是固定的,而是变化的,只是这些被通知者都有共同的行为,那就是发送相应的数据资源。这个时候我们可以考虑将通知对象提取成一个接口。让其他需要扩展的部分都依赖于该接口。
interface IAccountObserve
{
void SendData(UserAccountArgs args);
}
观察者模式:
观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。(此定义来自百度百科)。
比方说当用户的界面发生变化的时候,那他的业务数据也应该显示在界面上。而且是一对多的关系,也就是说一个对象的变化应该通知给其他多个对象,(和状态模式有区别,状态模式是状态发生变化的时候引起自身行为的变化)。也就是说观察者模式必须有观察者和被观察者,在上面的栗子中,ATM机就是观察者,当他观察到银行的账户金额变化时,通知给其他被观察者对象,手机和邮箱就是被观察者。上面的代码我们可以将需要变化的部分提取成一个接口,让依赖对象都继承自该接口。
public class Email:IAccountObserve
{
public void SendEmail(UserAccountArgs args)
{
string email = args.email;
//......拿到email对象进行操作
}
}
public class Mobile : IAccountObserve
{
public void SendPhone(UserAccountArgs args)
{
string mobile = args.mobile;
//.......拿到mobile对象进行操作
}
}
这样我们的email和mobile类都不在依赖于BackAccount而依赖于稳定的接口。我们建立一个UserAccountArgs类来管理被通知的对象
class UserAccountArgs
{
//需要通知的成员对象。
public string email;
public string mobile;
}
这样,我们可以将BackAccount类改写为:
class BackAccunt
{
List<IAccountObserve> observes = new List<IAccountObserve>();
public void SetMoney(int data)
{
//存钱操作
UserAccountArgs args = new UserAccountArgs();
foreach(var item in observes)
{
item.SendData(args);
}
}
public void AddObserve(IAccountObserve observe)
{
observes.Add(observe);//添加需要通知的成员
}
public void RemoveObserve(IAccountObserve observe)
{
observes.Remove(observe);//移除需要通知的成员
}
}
在该类中,我们只需要用一个集合来管理(添加或者删除)被通知的对象。当需要扩展其他被观察者对象的时候,就可以直接继承该接口。在主函数中调用就只需要管理观察者和被观察者了。
BackAccunt account = new BackAccunt();
Email em = new Email();
account.AddObserve(em);//添加要通知的成员
account.SetMoney(5);//存完5元以后自动通知发送email;
简单的观察者模式已经实现了。当然根据业务需求,这段代码还可以再进行抽象,不断提取变化的部分,封装变化的部分。