zoukankan      html  css  js  c++  java
  • 设计模式20——行为型模式之观察者模式

    定义:观察者模式(ObserverPattern),定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

    类型:对象行为型模式

    概述:

             观察者模式也是比较难以理解,单看类图,会发现观察者模式与中介模式非常相似。如果不真正理解他们二者之间的区别,是难以真正理解观察者模式的。如果不理解观察者模式,更奢谈运用观察者模式了。

             中介模式主要是解决一系列交互对象的耦合的问题,而提出了中介类。几个以前交互的对象现在统一通过中介类来完成交流。而观察者模式侧重的是一对多的通知的功能,即当发生某件事时,主题对象将向所有注册过的观察者对象发出通知消息。

             中介模式侧重通过中介类来完成交流;而观察者模式侧重于一对多的通知。中介模式不需要知道具体的中介类的对象,需要交互的对象只需要知道一个通知中介对象的接口即可,具体是哪个中介来完成交互对象告诉的任务,交互对象不需要知道。但是交互对象必须知道有哪些交互对象,这样才能把对象A需要对象B做的事想办法通知到对象B

              观察者模式则,Subject对象不需要知道具体的观察者是谁,它只需要知道观察者的通知接口,就可以将消息通知到观察者。至于具体有哪些消息,则需要观察者自己去具体的Subject那里查看。

              这里举一个例子,某电商有大促销,通过邮件发送促销消息给消费者。但是如果消费者想了解有哪些具体的促销信息,则即需要亲自去电商网站查看有哪些具体的促销信息。

    类图:


     参与者:

    1. Vender,提供接口来完成对观察者的注册通知。
    2. YiXun,具体的电商,为消费者提供所需要查看具体信息。
    3. Observer,提供Update接口。
    1. CustomerACustomerB,具体的观察者,当有更新时去查看电商中自己喜欢的产品。

     示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Pattern21
    {
        //抽象状态
        public abstract class State
        {
            public abstract void Eat();
            public abstract void Walk();
        }
    
        // 高兴时的状态
        public class Happy : State
        {
            public override void Eat()
            {
                human.Eat();
                Console.WriteLine("很多!");
            }
    
            public override void Walk()
            {
                human.Walk();
                Console.WriteLine("手舞足蹈的!");
            }
    
            public void Attach(Human _human)
            {
                human = _human;
            }
    
            private Human human;
        }
    
        // 伤心时的状态
        public class Sad : State
        {
            public override void Eat()
            {
                human.Eat();
                Console.WriteLine("很少!");
            }
    
            public override void Walk()
            {
                human.Walk();
                Console.WriteLine("无精打采的!");
            }
    
            public void Attach(Human _human)
            {
                human = _human;
            }
    
            private Human human;
        }
       
    
        // 一个人
        public class Human
        {
            private State current;
    
            public void SetState(State s)
            {
                current = s;
            }
    
            public void Eat()
            {
                Console.Write("吃了");
            }
    
            public void Walk()
            {
                Console.Write("走起路来");
            }
    
            public void Show()
            {
                current.Eat();
                current.Walk();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                // 定义一个有很多状态的对象
                Human human = new Human();
    
                // 定义一个高兴的状态
                Happy hState = new Happy();
                hState.Attach(human);
                human.SetState(hState);
                human.Show();
    
                // 定义一个伤心的状态
                Sad sad = new Sad();
                sad.Attach(human);
                human.SetState(sad);
                human.Show();
    
                // 还可以添加生病的状态,只需要添加新的类而不需要修改Human类
                // ......
    
                Console.Read();
            }
        }
    }
     适用性:
    1.  一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
    1. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象
    1. 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

    优缺点:

    1. 优点,降低命令发起者与命令接受者之间的耦合,发布者通过接口通知所有观察者。
    1. 缺点,具体的观察者依赖了具体的发布者。

    参考资料:

    1. 《设计模式——可复用面向对象软件基础》
      1. 《大话设计模式》
  • 相关阅读:
    域hash值破解的总结经验
    centos下安装ngnix+php+mysql服务
    方程式EQGRP_Lost_in_Translation工具之fb.py
    Bypass AV meterpreter免杀技巧
    跟我一起创建栈
    vue-cli3使用yarn run build打包找不到路径
    使用vue-cli3快速适配H5项目
    关于判断是安卓还是ios环境跳转下载页
    跟我一起学习webpack输出动态HTML(三)
    跟我一起学习webpack使用配置文件(二)
  • 原文地址:https://www.cnblogs.com/feihe0755/p/3595408.html
Copyright © 2011-2022 走看看