设计模式18:Observer 观察者模式(行为型模式)
Observer 观察者模式(行为型模式)
动机(Motivation)
在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象)都将得到通知。如果这样的以来对象关系过于紧密,将使软件不能很好地抵御变化。
使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
意图(Intent)
定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新——《设计模式》GoF
示例代码
这是一个ATM取钱的例子:
public class ATM
{
private BankAccount bankAccount;
//...
void Process(int data)
{
bankAccount.Widthdraw(data);
}
} public class BankAccount
{
private Emailer emailer;//强依赖关系
private Mobile mobile;//强依赖关系 public void Widthdraw(int data)
{
//...
UserAccountArgs args=new UserAccountArgs();
//...
emailer.SendEmail(UserAccountArgs.UserEmail);
mobile.SendNotification(UserAccountArgs.MobileNumber);
}
} public class Emailer
{
public void SendEmail(string userEmail)
{
//...
}
} public class Mobile
{
public void SendNotification(string mobileNumber)
{
//...
}
}
public class UserAccountArgs
{
public string UserEmail { get; set; }
public string MobileNumber { get; set; }
}
BankAccount和Emailer、Mobile是紧耦合的关系,需要解耦:
public class BankAccount
{
IList<IAccountObserver> observerList=new List<IAccountObserver>(); public void Widthdraw(int data)
{
//...
UserAccountArgs args=new UserAccountArgs();
//...
foreach (var accountObserver in observerList)
{
accountObserver.Update(args);
}
} public void AddObserver(IAccountObserver accountObserver)
{
observerList.Add(accountObserver);
} public void RemoveObserver(IAccountObserver accountObserver)
{
observerList.Remove(accountObserver);
}
} public interface IAccountObserver
{
void Update(UserAccountArgs args);
} public class Emailer : IAccountObserver
{
//public void SendEmail(string to)
//{
// //...
//} public void Update(UserAccountArgs args)
{
string userEmail = args.UserEmail;
//...
}
} public class Mobile : IAccountObserver
{
//public void SendNotification(string to)
//{
// //...
//} public void Update(UserAccountArgs args)
{
string mobileNumber = args.MobileNumber;
//...
}
} public class UserAccountArgs
{
public string UserEmail { get; set; }
public string MobileNumber { get; set; }
}
如果BankAccount的变化比较多,可以继续抽象来解除与IAccountObserver的耦合:
public class BankAccount : Subject
{
public void Widthdraw(int data)
{
//...
UserAccountArgs args=new UserAccountArgs();
//...
Notify(args);
}
} public abstract class Subject
{
IList<IAccountObserver> observerList = new List<IAccountObserver>(); public void Notify(UserAccountArgs args)
{
//...
foreach (var accountObserver in observerList)
{
accountObserver.Update(args);
}
} public void AddObserver(IAccountObserver accountObserver)
{
observerList.Add(accountObserver);
} public void RemoveObserver(IAccountObserver accountObserver)
{
observerList.Remove(accountObserver);
}
}
这时BankAccount就和IAccountObserver解除耦合了。
演化过程
当写软件的时候,不一定要套用某个设计模式。为了应对变化,在解耦合的过程中,自然而然就用到了某种模式。
重要的是松耦合的设计思维。学习设计模式的意义在于深化设计思维。
结构(Structure)
Observer模式的几个要点
- 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
- 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否要订阅通知,目标对象对此一无所知。
- 在C#的event中,委托充当了Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。
转载请注明出处:
作者:JesseLZJ
出处:http://jesselzj.cnblogs.com
设计模式18:Observer 观察者模式(行为型模式)的更多相关文章
- 设计模式(19)--Observer(观察者模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图( ...
- Java经典设计模式之十一种行为型模式
转载: Java经典设计模式之十一种行为型模式 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式 ...
- Java设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...
- Java经典设计模式之十一种行为型模式(附实例和详解)
Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...
- java架构之路-(设计模式)五种创建型模式之单例模式
设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...
- 设计模式 ( 十七 ):Observer 观察者模式 -- 行为型
1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是 ...
- Java设计模式(5)——创建型模式之建造者模式(Builder)
一.概述 概念 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.(与工厂类不同的是它用于创建复合对象) UML图 主要角色 抽象建造者(Builder)——规范建造方法与结果 ...
- Java设计模式(4)——创建型模式之单例模式(Singleton)
一.概述 弥补一下之前没有给设计模式下的定义,先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计 ...
- Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)
一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...
- Java设计模式(2)——创建型模式之工厂方法模式(Factory Method)
一.概述 上一节[简单工厂模式]介绍了通过工厂创建对象以及简单的利弊分析:这一节来看看工厂方法模式对类的创建 工厂方法模式: 工厂方法与简单工厂的不同,主要体现在简单工厂的缺点的改进: 工厂类不再负责 ...
随机推荐
- 【BZOJ】1008: [HNOI2008]越狱(组合数学)
题目 题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 输入输出格式 ...
- Julia - 函数的参数传递
不定参数 不定参数的函数也称变参函数 函数的参数可以被定义成任意个 可以在最后一个参数后紧跟省略号“...”来定义变参函数 julia> bar(x, y, z...) = (x, y, z) ...
- zedgraph绘图(修改)
转自原文 zedgraph绘图(修改) 首先先下载 zedgraph.dll和zedgraph.web.DLL两个文件 添加项目并引用 首先添加一个用户控件 WebUserDrawGrap.ascx ...
- UNIX网络编程——socket的keep-alive(转)
第一部分 [需求] 不影响服务器处理的前提下,检测客户端程序是否被强制终了. [现状] 服务器端和客户端的Socket都设定了keepalive属性. 服务器端设定了探测次数等参数,客户端.服务器只是 ...
- ubuntu 初始设置备忘
配置静态网络 vim /etc/network/interfaces auto eth0 #iface eth0 inet dhcp iface eth0 inet static address x. ...
- axis客户端循环访问webservice的时候只发送了几条数据就断开了的问题
原因 axis客户端访问webservice默认是使用http1.0版本的,这个版本的http不能保持长连接,应该换成http1.1版本 具体修改步骤: <?xml version=" ...
- ubuntu linux常用指令(1)
序号 命令 说明 1 sudo su 从普通用户切换到root用户 2 su user 从root用户切换到普通用户 3 ls 列出当前目录的文件和目录,但是不包括隐藏文件和目录 4 ls -a 列出 ...
- xbstream 备份恢复
xbstream -x < ./backs/backup.xbstream -C /dbnode/data/ innobackupex --defaults-file=/dbnode/etc/ ...
- python 文件的读取&更新
[python 文件的读取&更新] 任务抽象: 读取一个文件, 更新内容后, 重新写入文件. 实际应用: 磁盘上的一个配置文件, 读入内存后为一个dict, 对dict更新后重新写入磁盘. d ...
- 必看的 jQuery性能优化的38个建议
一.注意定义jQuery变量的时候添加var关键字 这个不仅仅是jQuery,所有javascript开发过程中,都需要注意,请一定不要定义成如下: $loading = $('#loading'); ...