不知不觉已经进入了设计模式璀璨的迷宫,早先偶然进入,it is so far that I can't understanding anthing .最近的项目应用和书上讲解的对比,昨天有偶然看到了李建忠老师的讲座,感觉自己开始真正成为了一个淘金者,而这条路的方向看似慢慢明朗起来。
李建忠最鲜明的主张是,设计模式是一种结果,而不是要去套用的规则。所以讲座从我们最常规的思维开始,逐步演化,让循序渐进在此充发挥了他的作用。感受非常深刻!也很感动。
观察者模式的存在的必要:
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
动机:
依赖抽象,实现软件体系结构松耦合
手段:利用面向对象,形成稳定的依赖
原则:依赖倒置:具体细节依赖抽象,不稳定依赖稳定
意图:
得到一对多的依赖关系,当一个对象的状态发生改变,依赖他的对象得到统统自动更新
要点:
独立地改变(扩展、继承接口)目标和观察者
接口概念:1.稳定;2.表达了契约合同,不一定用Inerface表现
事件和observer模式的关系:
事件中所使用的程序接口(用委托来实现),
委托比接口更加松耦合
委托(约定)要求:参数类型和返回值类型一致就可以
接口要求:方法名称也必须相同
委托将一些功能实现了,例如add,用+=实现了;遍历,隐含实现了;
从紧耦合到松耦合的演化:(自然的未经设计模式的代码)
public class BandAccount
{
Emailer emailer;
Mobile mobile;
public void withdraw(int data)
{
//...
emailer.SendEmail(userEmail);
mobile.SendNotification(phoneNumber);
}
}
public class Emailer
{
//希望通知到用户帐户emil
//发送通知。让自己得到更新
public void SendEmail(sting userEmail)//未将参数提取出来
{
//..
}
}
public class Mobile
{
//发送通知。让自己得到更新
public void SendNotification(string phoneNumber) //未将参数提取出来
{
//..
}
}
第一步:分化B
public class UserAccountArgs //用户信息类,这个类的信息将用作参数传递,args将是一个数组
{
public string moble;
public string email;
public UserAccountArgs()
{
}
}
public class BandAccount //A还没有分化
{
//一对一依赖关系-------------------
IAccountObserver emailer; //弱依赖关系
public void Withdraw(int data)
{
//...
UserAccountArgs args = new UserAccountArgs();//构造参数
//...
args.email = data // 此处将args的email属性赋值,没有这句,实现不了
emailer.Update(args);
}
}
重要改进: Mobile mobile = new Mobile(); Email email = new Email(); public void withdraw(UserAccountArgs args) //传递的是参数和接口相同,实现了真正的参数抽象化 { |
//------------------------------------
public interface IAccountObserver
{
void Update(UserAccountArgs args); //args中包含了用户信息,例如用户手机号,email地址
//提取出了方法和参数
}
public class Emailer : IAccountObserver
{
//希望通知到用户帐户emil
//发送通知。让自己得到更新
public void Update(UserAccountArgs args) //将参数提取出来
{
//..
string ToAddress = args.ToAddress; //参数具体传入
}
}
public class Mobile : IAccountObserver
{
//发送通知。让自己得到更新
public void Update(UserAccountArgs args) //将参数提取出来
{
//..
string mobileNumber = args.MobileNumber; //参数具体传入
}
}
分化A
public abstract class Subject
{
// ArrayList<IAccountObserver> observerList = new ArrayList<IAccountObserver>(); //泛型,接口封装,实现一对多
ArrayList observerList = new ArrayList(); //此处的概念是可变长度的数组,.net中用这种写法
protected virtual void Notify(UserAccoutArgs args)
{
//...
UserAccountArgs args = new UserAccountArgs();//构造参数
//...
foreach (IAccountObserver observer in observerList)
{
observer.Update(args); //对每一个对象进行更新
}
}
public void AddObserver(IAccountObserver observer)
{
observerList.add(observer);
}
public void RemoveObserver(IAccountObserver observer)
{
observerList.Remove(observer);
}
}
public class BandAccount : Subject // 如果需要改变,就扩展
{
public void Withdraw(UserAccountArgs args)
{
//...
Notify(args);//对每一个对象进行更新
}
}
--------------------------------------------------------------------------
流程调用: UserAccountArgs args = new UserAccountArgs();//参数传入 |
实现了订阅功能(观察者模式)的流程调用 思路,加入了
UserAccountArgs args = new UserAccountArgs(); //参数传入
IAccountObserver mobile = new Mobile();//接口实例化到实现类
BandAccount bankAccount = new BandAccount(); |
与等级相关的类视图
联系客服