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 观察者模式(行为型模式)的更多相关文章

  1. 设计模式(19)--Observer(观察者模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图( ...

  2. Java经典设计模式之十一种行为型模式

    转载: Java经典设计模式之十一种行为型模式 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式 ...

  3. Java设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...

  4. Java经典设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...

  5. java架构之路-(设计模式)五种创建型模式之单例模式

    设计模式自身一直不是很了解,但其实我们时刻都在使用这些设计模式的,java有23种设计模式和6大原则. 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可 ...

  6. 设计模式 ( 十七 ):Observer 观察者模式 -- 行为型

    1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是 ...

  7. Java设计模式(5)——创建型模式之建造者模式(Builder)

    一.概述 概念 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.(与工厂类不同的是它用于创建复合对象) UML图   主要角色 抽象建造者(Builder)——规范建造方法与结果 ...

  8. Java设计模式(4)——创建型模式之单例模式(Singleton)

    一.概述 弥补一下之前没有给设计模式下的定义,先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计 ...

  9. Java设计模式(3)——创建型模式之抽象工厂模式(Abstract Factory)

    一.概述 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象. UML图: 其他的过多概念不再 ...

  10. Java设计模式(2)——创建型模式之工厂方法模式(Factory Method)

    一.概述 上一节[简单工厂模式]介绍了通过工厂创建对象以及简单的利弊分析:这一节来看看工厂方法模式对类的创建 工厂方法模式: 工厂方法与简单工厂的不同,主要体现在简单工厂的缺点的改进: 工厂类不再负责 ...

随机推荐

  1. url携带的参数获取并处理demo

    url demo: http://servername/webname/pagename.csp?paramName=paramValue&paramName2=paramName2& ...

  2. 脱壳系列(一) - CrypKeySDK 壳

    程序: 运行 用 PEiD 载入程序 PEid 显示找不到相关的壳 脱壳: 用 OD 载入程序 这个是壳的入口地址 因为代码段的入口地址为 00401000 这三个是壳增加的区段 按 F8 往下走程序 ...

  3. Django的视图层

    HttpResquest对象: request属性: /* 1.HttpRequest.GET 一个类似于字典的对象,包含 HTTP GET 的所有参数.详情请参考 QueryDict 对象. 2.H ...

  4. [CSAPP] Chapter 1 Overview of Computer

    1.1 information is bits + context All computer programs are just a sequence of bits, each with a val ...

  5. [ExtJs6] 环境搭建及创建项目

    1. 环境搭建 sencha cmd 和 extjs6 sdk. sencha cmd: https://www.sencha.com/products/extjs/cmd-download/ ext ...

  6. redis rdb文件解析

    http://www.ttlsa.com/python/redis-rdb-tools-analysis-of-reids-dump-file-and-memory-usage/ redis-rdb- ...

  7. Python 位运算符 逻辑运算符 成员运算符

    位运算符 运算符 描述 实例 & 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果12 ,二进制解释:0000 1100 | ...

  8. 使用heap profiler进行内存占用分析

    最近在项目中用到了google的heap profiler工具来分析内存占用,效果非常显著,因此在这里写一篇博客记录一下使用过程中遇到的一些问题. heap profiler依赖于tcmalloc,所 ...

  9. selenium+python—实现基本自动化测试

    安装selenium 打开命令控制符输入:pip install -U selenium 火狐浏览器安装firebug:www.firebug.com,调试所有网站语言,调试功能 Selenium I ...

  10. linux系统命令行基本组成元素

    一.shell prompt(PS1) 命令行提示符 1. 游标(coursor) 当你成功登录进一个文字界面之后,大部份情形下,你会在荧幕上看到一个不断闪烁的方块或底线(视不同版本而别),我们称之为 ...