第一章 入门

1.这里讲了一个简单的例子,鸭子的例子。鸭子都会叫,都会走,都会游泳(不变的部分)。但是有的鸭子会飞,有的鸭子的外观不一样等等(变得部分),如何设计呢?采取分离的策略,将不变的部分和可变的部分分离,因此引出我们第一个设计原则:找出应用中可能需要的变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。

2.如何设计呢?对于上面的鸭子的例子,我们知道我们要增强我们的代码弹性, 就是说要更容易修改,引出第二个设计原则:针对接口编程,而不是针对实现编程。具体来讲,对于我们鸭子的每个可变行为,比如飞行行为,单独拿出来作为一个接口。如下图

3.接下来,你就应该要整合鸭子的行为了。前面的过程,我们将鸭子的可变行为委托(delegate)给了FlayBehavior和QuackBehavior。具体的做法是让鸭子类持有FlyBehavior和QuackBehavior的两个实例变量,然后写两个方法,比如飞行方法,如下所示

public void performFly(){ flyBehavior.fly();}

这样鸭子就有了自己的飞行行为,我们只需要在实例化这个鸭子的时候,比如在构造函数中初始化对应的飞行和名叫的具体的类即可。

4.第三个设计原则:多用组合,少用继承。

上述就讲述了一个设计模式策略模式,而且是一个多策略模式,有飞行的策略,有名叫的策略,不同的策略下面又有不同的实现。

观察者模式

观察者模式适用于经常变化且需要被监测的对象。课本上举的例子是气象站的一个类WebData,这个Webdata能获得最新的气象数据并及时的更新到三个布告板。布告板也不能仅仅只有3个,知识说现在有三个, 以后可能会有更多的布告板展示其他的数据(可拓展性)。
怎么办呢?
基本的过程呢,我们用一个简单的例子来解释:假设观察者是订阅报纸的人,简称狗,鸭子,猫和老鼠,他们都订阅了某个报社的报纸(假设鸭子还没订阅)。而被订阅的报社呢,是被观察者,就叫他们报社。整体的工作流程如下:
某天,鸭子向报社说,我想订阅一份报纸(鸭子相当观察者了),这个过程称作注册;
报社街道订阅通知,将鸭子添加到自己的订阅列表;
好,现在鸭子也加入到了观察者里面,开始等待报社送报纸(发送通知);
报社印出了新的报纸,并告诉观察者们报纸已经好了;
老鼠不想当观察者了,想订阅另一个报社的报纸,于是老鼠向报社发送请求,然后老鼠离开了,删除了一个观察者。
报社又产生了新的报纸,只不过老鼠已经接收不到通知了。
那么我们基本就了解了观察者模式的工作流程了,那么观察者模式应该具体怎么实现呢?我们来看类图
一定要注意这几个方法,对于被观察者(主题,Subject),registerObserver,RemoveObserver,NotifyObserver,对于观察者,只需要一个update。这是一个松耦合的设计,观察者只需要等待主题的通知,而主题只知道观察者只有一个update 方法。剩下的就比较简单了。你可以写一个Client类,这个类通过持有观察者和被观察者两个接口,不断的向被观察者内部注册观察者或者移除观察者。或者当被观察者需要通知观察者时,由Client调用notifyObservers()方法。
java内部实现了观察者模式,Observervable抽象类负责被观察者,Observer接口负责观察者,如下图所示
java内置的观察者模式必须要经过两步。即当被观察者更新内容后,必须先setChange(),然后才能调用notifyObserver()看下面的代码
观察者
import java.util.Observable;
import java.util.Observer;public class BlackBoard implements Observer{@Overridepublic void update(Observable o, Object arg) {// TODO Auto-generated method stubif(o instanceof Teacher){Teacher teacher = (Teacher)o;System.out.println(teacher.getContent());}}}

被观察者

import java.util.Observable;public class Teacher extends Observable{private String content;public Teacher(){}public void measurementsChanged(){setChanged();notifyObservers();}public void setContent(String content){this.content=content;measurementsChanged();}public String getContent() {// TODO Auto-generated method stubreturn content;}}

客户端:

public class Client {public static void main(String[] args){Teacher t = new Teacher();t.addObserver(new BlackBoard());t.setContent("Course Content");
//      t.measurementsChanged();t.setContent("new Content");}}

总结一下,观察者模式需要以下步骤:

1、创建观察者和被观察者,这里观察者需要有update()方法,被观察者需要有addObserver(),removeObserver(),notifyOverver()方法。甚至还有自己的状态setChange()表示当前数据有没有更新。
2、在被观察者内部注册观察者,这个可以在客户端或者观察者内部甚至被观察者内部执行,都无所谓的。
3、被观察者更新内容,设置setChange(),通知所有客户端notifyObservers()。

深入浅出设计模式之策略模式、观察者模式相关推荐

  1. 设计模式:策略模式+观察者模式

    以游戏情景举例: 情景:一个boss发动一个技能时会让自己的喽啰收到随机的增益效果. 提取一下主要需求: 1:随机增益效果 2:通知多个对象 其中1用策略模式+工厂模式来解决,2用观察者模式来解决 先 ...

  2. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索"为什么MVC不是一种设计模式呢?"其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composi ...

  3. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  4. 换个姿势学设计模式:策略模式

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:公众号「闻人的技术博客」 前言 前段时间,接到一个 ...

  5. 研磨设计模式之 策略模式--转

    http://www.uml.org.cn/sjms/201009092.asp 研磨设计模式之 策略模式   2010-09-09 作者:云飞龙行 来源:云飞龙行的blog   先感谢众多朋友的支持 ...

  6. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

  7. C++设计模式之策略模式(Strategy)

    Strategy策略模式 作用:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. UML图: 代码实现 #include <iostream& ...

  8. python策略模式包含角色_详解Python设计模式之策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中"不见了,或者简 ...

  9. 一篇博客读懂设计模式之-----策略模式

    设计模式之策略模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的对象 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下 ...

  10. 面向对象设计模式之策略模式

    面向对象设计模式之策略模式 1.策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 2.抽象鸭子类,鸭子飞行行为在此处类似于算法族 1 package ...

最新文章

  1. JPA中实现查询list
  2. 【C语言】%[修饰符] 格式字符
  3. B. Bogosort codeforces(思维)
  4. 互联网日报 | 字节跳动否认进军社区团购;中兴手机回归国内2C市场;华为公布5G商用一年成绩单...
  5. Node.js web应用模块之Supervisor
  6. python计算近似圆周率
  7. mac怎么查node版本_Node.js 微服务实践:基于容器的一站式命令行工具链
  8. Spring Framework--Data Access(1)--Transaction Management(2) - 声明式事务管理
  9. 3D游戏常用技巧Normal Mapping (法线贴图)原理解析——基础篇
  10. hdu 4308 Saving Princess claire_ 广搜 多校联合赛第七题
  11. php页面不刷新 图片的src不更新,详解iframe的src指向的内容不刷新的解决办法
  12. 计算机视觉论文-2021-07-21
  13. 运输业的EDI是如何运作的?
  14. Daily Scrum Meeting 11.03
  15. 网站关键词怎么合理布局提升网站排名
  16. pdf,word,ppt在线预览
  17. c语言实现各种排序算法(作业:点名册排序)
  18. Linux—ps命令
  19. 旧版本NVIDIA驱动下载地址
  20. UNetbootin使用

热门文章

  1. 惠普服务器c盘格式化提示win7系统盘,c盘格式化,小编告诉你怎么格式化c盘
  2. 让你的软件支持繁体中文
  3. textarea 滚动条设置
  4. KEmulator与eclipse的集成
  5. Unix/Linux入门篇
  6. java项目启动失败的解决方案
  7. 最全面的Fiddler 4教程讲解(界面)
  8. STC单片机免冷启/自动下载原理DIY免冷启烧录器(纯硬件版和软件版)
  9. Oracle11g安装教程
  10. html5+JS调用手机摄像头扫码