《大话设计模式》——读后感老板回来了,我不知道?——观察者模式之理论实例

街头小瘪三 街头小瘪三     2022-09-05     276

关键词:

单独看UML类图,有没有发现观察者类图和工厂方法模式的类图和相似?不过代码实现可不一样哦,从UML类图中我获取如下信息:

1、Subject是个抽象类,而不是接口

2、Observer也是个抽象类

3、具体观察者和具体通知者有一种关联关系

 

下面我会分别对Subject使用接口和抽象类实现,并进行比较:

首先使用接口:

抽象观察者:

package com.sjmx.observer.theory;

public interface Watcher {
    
     public void update(String str);
     
}

具体观察者:

package com.sjmx.observer.theory;

public class ConcreteWatcher implements Watcher {

    @Override
    public void update(String str) {
        
        if("学校卫生评比开始".equals(str)){
            System.out.println(str + ",结束打扫卫生!"); } } }
package com.sjmx.observer.theory;

public class ConcreteWatcher2 implements Watcher {

    @Override
    public void update(String str) {
         
        if("学校卫生评比开始".equals(str)){
            System.out.println(str + ",结束室外活动区整理!");
        }

    }

}
package com.sjmx.observer.theory;

public class ConcreteWatcher3 implements Watcher {

    @Override
    public void update(String str) {
         
        if("学校卫生评比开始".equals(str)){
            System.out.println(str + ",全体安静自习!");
        }

    }

}

 

主题(通知)接口:

package com.sjmx.observer.theory;

public interface Watched {
    
    public void addWatcher(Watcher watcher);

    public void removeWatcher(Watcher watcher);

    public void notifyWatchers(String str);
    
}

 

具体通知对象:

package com.sjmx.observer.theory;

import java.util.ArrayList;
import java.util.List;

public class ConcreteWatched implements Watched {

    // 存放观察者
    private List<Watcher> list = new ArrayList<Watcher>();

    @Override
    public void addWatcher(Watcher watcher)
    {
        list.add(watcher);
    }

    @Override
    public void removeWatcher(Watcher watcher)
    {
        list.remove(watcher);
    }

    @Override
    public void notifyWatchers(String str)
    {
        // 自动调用实际上是主题进行调用的
        for (Watcher watcher : list)
        {
            watcher.update(str);
        }
    }

}

客户端代码:

package com.sjmx.observer.theory;

public class Client {
    
    public static void main(String[] args)
    {
        Watched girl = new ConcreteWatched();
        
        Watcher watcher1 = new ConcreteWatcher();
        Watcher watcher2 = new ConcreteWatcher2();
        Watcher watcher3 = new ConcreteWatcher3();
        
        girl.addWatcher(watcher1);
        girl.addWatcher(watcher2);
        girl.addWatcher(watcher3);
        
        girl.notifyWatchers("warning");
    }
}

运行结构:

 

 

 

看完代码:

1、观察者模式所做的工作就是解除耦合,让耦合的双方都依赖于抽象,而不依赖于实体。从而使得一方的 变化不会影响另一方。

2、缺点也很容易看见的,所有的观察者实体都要方法相同,这在显示生活中是不可能的。比如,今天放假,学生停课,工人停止生产,股票停止交易,服务业开始服务等等。

3、抽象通知者是个接口,那么每个实体通知者都要拥有一个存放Watcher的List存在,而且每个实体通知者都有相同的addWatcher和removeWatcher方法,太累赘,而使用抽象类的话,就可以把这些相同的东西抽象到抽象类中操作,使其固定成模板。

 

下面再使用抽象类对通知者进行改造,观察者不变:

主题(通知)抽象类:

package com.sjmx.observer.theory2;

import java.util.ArrayList;
import java.util.List;

import com.sjmx.observer.theory.Watcher;

public abstract class Watched {
    
    // 存放观察者
    private List<Watcher> list = new ArrayList<Watcher>();

    public void addWatcher(Watcher watcher)
    {
        list.add(watcher);
    }

    public void removeWatcher(Watcher watcher)
    {
        list.remove(watcher);
    }

    public void notifyWatchers(String str)
    {
        // 自动调用实际上是主题进行调用的
        for (Watcher watcher : list)
        {
            watcher.update(str);
        }
    }
    
}    

具体通知者:

package com.sjmx.observer.theory2;

public class ConWatched extends Watched {
    
    public String state;
    
    public void notiyW(){
        this.notifyWatchers(state);
    }
    
}

从以上代码清晰可见,具体的通知者代码大量简化,此时Watched抽象类如果有10个实现类,代码量立刻就能体现出来,大大的减少了冗余代码

 

在来看看客户端:

package com.sjmx.observer.theory2;

import com.sjmx.observer.theory.ConcreteWatcher;
import com.sjmx.observer.theory.ConcreteWatcher2;
import com.sjmx.observer.theory.ConcreteWatcher3;
import com.sjmx.observer.theory.Watcher;

public class Client {

    public static void main(String[] args) {

        ConWatched wt = new ConWatched();

        Watcher watcher1 = new ConcreteWatcher();
        Watcher watcher2 = new ConcreteWatcher2();
        Watcher watcher3 = new ConcreteWatcher3();

        wt.addWatcher(watcher1);
        wt.addWatcher(watcher2);
        wt.addWatcher(watcher3);
        
        wt.state = "学校卫生评比开始";
        wt.notiyW();
    }

}

 通过客户端代码比较,我发现如果使用使用抽象类实现的话,具体通知者无法使用多态,因为具体通知者有自己独特的方法而抽象类中根本就不具有这些方法。而即使使用接口实现可以使用多态,在客户端也还是要去认识每一个实现了接口Watched的实现类, 单单在代码耦合度上,没有任何进步!当然,你也可以在Watched抽象类中添加一个抽象方法,然后具体的通知者(主题)再去实现这些抽象方法,再由这些方法去调用抽象类中notifyWatchers方法,那么在客户端也就可以使用多态了!

 

总结:观察者模式中,通知者使用抽象类比使用接口要好,因为他们有一些公共的逻辑!

行为型模式《大话设计模式》——读后感(16)加薪非要老板批?——职责链模式

职责链模式(ChainofResponsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 适用场景:1、有多个的... 查看详情

《大话设计模式》——读后感代码无错就是优?——简单工厂模式

本篇是我学习设计模式后的第一篇文章,由于本模式也比较简单,在此我就多啰嗦一下。学习本模式之前请下看一下我的《大话设计模式铺垫》文章,然后回答思考如下问题:1、UML类图看懂了吗?2、java的3大特性真的懂了吗?... 查看详情

《大话设计模式》读后感

转载:http://blog.csdn.net/u013798619 第一次读《大话设计模式》,是在刚接触C#的时候。疲累于大部头的官方教材中时,无意间翻开了这本生动有趣的书,甚是眼前一亮。由于当时C#基础薄弱,只是把它当小说来看,如饥似渴,饶... 查看详情

大话设计模式之策略模式读后感(代码片段)

策略模式:定义了算法家族,分别封装起来,让他们呢之间可以互相的替换,此模式让算法的变化不会影响到使用算法的客户。UML类图:解读:策略模式是定义一系列的算法,从概念上来讲,这些算法完成的工作都是一样的,只... 查看详情

大话设计模式之简单工厂读后感(代码片段)

引言:让我们重温经典,致敬经典简单工厂模式:根据调用端传参来有选择的实例化目标对象。UML类图:我们知道简单工厂就是为我们生成我们需要的对象。举个栗子:我们在舞台看表演的时候,一场场表演下来,我们可以总结... 查看详情

《大话设计模式》——读后感商场促销?——策略模式

...对商场促销进行各种各样的打折进行设计案例的,而大话设计模式中还提到:  等等,打折、返现等等一系列促销具体方式 查看详情

大话设计模式之工厂方法模式读后感(代码片段)

引言:让我们重温经典,致敬经典工厂方法模式:定义一个用于创建对象的接口,让子类来决定实例化哪一个类,工厂方法使一个类的实例化延迟到了子类。UML图:1packagecom.dzf.designtest;23/**4*<desc>5*工厂方法:定义一个创建对... 查看详情

《大话设计模式》——读后感(10)无尽加班何时休?——状态模式

原文定义:   状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变其类【DP】 UML结构图:   背景:  看到此模式,酝酿了好久才决定对状态模式进行总结。光看原文定义,实在... 查看详情

《大话设计模式》——读后感牛市股票还会亏钱?——外观模式

原文中对外观模式的定义为:     外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子类系统更加的容易使用【DP】. 从定义理解:1、外观模式是为子... 查看详情

《大话设计模式》——读后感(11)简历复印?——原型模式

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新对象[DP] 说白了,原型模式还是属于创建型模式,主要功能还是创建新对象。下面我自己写一个原型模式试试:案例1:自己写原型接口(Prototy):pac... 查看详情

《大话设计模式》——读后感为别人做嫁衣?——静态代理模式

什么是代理模式: 代理模式结构图:   直接上代码:GiveGift接口:packagecom.sjmx.staticProxy;publicinterfaceGiveGift{voidgiveDolls();voidgiveFlows();voidgiveChocolate();}真实实体:packagecom.sjmx.staticProxy;publi 查看详情

结构型模式《大话设计模式》——读后感(12)在nba我需要翻译?——适配器模式

适配器模式:将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作了[DP]UML类图: 简单模拟一下代码://已存在的、具有特殊功能、但不符合我们既... 查看详情

设计模式---观察者模式

...个别名,依赖(Dependents),发布-订阅(Publish-Subsrcibe)。大话设计模式中程杰老师对观察者模式的定义是,观察者模式:定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改... 查看详情

《大话设计模式》——读后感雷锋依然在人间?——工厂方法模式

什么是工厂方法模式:工厂方法UML结构图:从图中我获取以下信息:1、Product是个接口,而Creator是个抽象类(我还是试试接口)2、ConcreateProduct和ConcreteCreator是有依赖关系的,后者依赖前者 接下来看看简单工厂模式中例子用... 查看详情

行为型模式《大话设计模式》——读后感(15)烤羊肉串引来的思考?——命令模式

命令模式:将一个请求封装为一个对象,从而使得你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作【DP】 先看代码吧:Receiver:packagecom.sjmx.command;publicclassReceiver{publicvoiddoSomething(){Syste... 查看详情

结构型模式《大话设计模式》——读后感(13)手机软件何时能统一?——桥接模式

桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变换【DP】 概述:在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来... 查看详情

《大话设计模式》——读后感好菜每回味不同——建造者模式之基础案例

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 建造者模式通常包括下面几个角色:1.builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定... 查看详情

《大话设计模式》——读后感好菜每回味不同——建造者模式之经典案例

本文参考地址:http://www.cnblogs.com/xieweikai/p/6826481.html建造者模式应用场景比如在玩“极品飞车”这款游戏,那么每一关的地图会千变万化,简单的来说,地图会有晴天和阴天之分,那么创建地图时就要根据晴天或者阴天来对地图... 查看详情