设计模式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)
一.概述 上一节[简单工厂模式]介绍了通过工厂创建对象以及简单的利弊分析:这一节来看看工厂方法模式对类的创建 工厂方法模式: 工厂方法与简单工厂的不同,主要体现在简单工厂的缺点的改进: 工厂类不再负责 ...
随机推荐
- oracle 存储过程 建表插值等
建表.插值的procedure create or replace procedure CREATE_EMP is v_createsql ); v_insertsql ); begin v_crea ...
- 【洛谷】P2725 邮票 Stamps(dp)
题目背景 给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资. 题目描述 例如,假设有 1 分和 3 ...
- angularJs中的发送请求例子
$http({ //发送请求 url: 'http://localhost:8080/teacher/api/login', method: 'post', data: obj }) .success ...
- VMware Workstation 12 Pro(安装CentOS7)
之前安装了一版 Ubuntu 14.04版本,发现蛮不好用的,果断放弃,换上CentOS7版本(在远程服务器上的安装方式除了网络设置有差异,基本相同) VMware Workstation 12 Pr ...
- NFS共享权限问题
//所有web集群节点的用户统一uid 例如888,用户最好也统一 Apache server: useradd -u 888 -s /sbin/nologin -M www chown -R www ...
- Rhel5.5配置Centos yum源
ruiy哥,抛砖引玉 当你使用rhel系统时,[大部分数据库中心及政府企业选择linux服务器时通常考虑采购的版本一般不外乎是Rhel红帽及Suse,理由你懂的EcoSystem!]你没有一个红帽网络 ...
- Spring Data MongoDB 三:基本文档查询(Query、BasicQuery
一.简介 spring Data MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我 ...
- MongoDB数据仓储
本篇是作为另一篇随笔的一部分‘搭建一个Web API项目’ MogonDB官网:https://www.mongodb.org/ 安装过程参考园友的分享http://www.cnblogs.com/l ...
- TI XDC工具入门简介
1. XDC(Express DSP Component)是TI提供的一个命令行工具,它可以生成并使用实时软件组件包,它包括一系列工具,这些工具可以允许你将你的C语言代码组织成类似于java的包管理方 ...
- emulator: Trying to vcpu execute at eip:6d4053