zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式(Observer)(4)

    简介

            观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

    定义

            观察者模式(又被称为发布-订阅(Publish/Subscribe)模式)定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

    类型

    行为型模式

    类图

    图1 类图

    结构

    最基础的观察者模式包括以下四个角色:

    • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
    • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
    • Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
    • ConcrereObserver:具体观察者,是实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

    使用场景

    • 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
    • 事件多级触发场景。
    • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

    优点

    • 观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。
    • 观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。

    缺点

            在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂 而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

    模拟场景

            假设有一个软件公司,每当有新产品推出,就把信息通知到一些客户。

    实现

    C#版

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Observer
    {
        class Program
        {
            static void Main(string[] args)
            {
                MyCompany company = new MyCompany();
                IService customerA = new Customer("Alice");
                IService customerB = new Customer("Bob");
                company.Subscribe(customerA);
                company.Subscribe(customerB);
                company.SendMsg();
                Console.ReadLine();
            }
        }
        /// <summary>
        /// 抽象观察者
        /// </summary>
        public interface IService
        {
            void Update();
        }
        /// <summary>
        /// 具体观察者
        /// </summary>
        public class Customer : IService
        {
            private string name;
            public Customer(string name)
            {
                this.name = name;
            }
            public void Update()
            {
                Console.WriteLine("客户{0}收到通知了", this.name);
            }
        }
        /// <summary>
        /// 抽象被观察者
        /// </summary>
        public interface IMyCompany
        {
            //合作
            void Subscribe(IService subscriber);
            //取消合作
            void CancelSubscribe(IService subscriber);
            //向客户发送更新消息
            void SendMsg();
        }
    
        /// <summary>
        /// 被观察者
        /// </summary>
        public class MyCompany : IMyCompany
        {
            private IList<IService> subscribers = new List<IService>();
    
            public void Subscribe(IService subscriber)
            {
                subscribers.Add(subscriber);
            }
            public void CancelSubscribe(IService subscriber)
            {
                subscribers.Remove(subscriber);
            }
            public void SendMsg()
            {
                foreach (IService service in subscribers)
                {
                    service.Update();
                }
            }
        }
    }
    View Code

    Java版

    package Observer;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Program {
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
             MyCompany company = new MyCompany();
          IService customerA = new Customer("Alice");
          IService customerB = new Customer("Bob");
          company.Subscribe(customerA);
          company.Subscribe(customerB);
          company.SendMsg();
        }
    }
    interface IService {
            void Update();
    }
        class Customer implements IService
        {
            private String name;
            public Customer(String name)
            {
                this.name = name;
            }
            public void Update()
            {
                System.out.println("客户"+this.name+"收到通知了");
            }
        }
        /// <summary>
        /// 抽象被观察者
        /// </summary>
         interface IMyCompany
        {
            //合作
            void Subscribe(IService subscriber);
            //取消合作
            void CancelSubscribe(IService subscriber);
            //向客户发送更新消息
            void SendMsg();
        }
    
        /// <summary>
        /// 被观察者
        /// </summary>
         class MyCompany implements IMyCompany
        {
            private List<IService> subscribers = new ArrayList<IService>();
            public void Subscribe(IService subscriber)
            {
                subscribers.add(subscriber);
            }
            public void CancelSubscribe(IService subscriber)
            {
                subscribers.remove(subscriber);
            }
            public void SendMsg()
            {
                for (IService service : subscribers)
                {
                    service.Update();
                }
            }
        }
    View Code
  • 相关阅读:
    Struts2SpringHibernate整合示例,一个HelloWorld版的在线书店(项目源码+详尽注释+单元测试)
    Java实现蓝桥杯勇者斗恶龙
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 226 翻转二叉树
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 225 用队列实现栈
    Java实现 LeetCode 224 基本计算器
    Java实现 LeetCode 224 基本计算器
  • 原文地址:https://www.cnblogs.com/CIreland/p/9385987.html
Copyright © 2011-2022 走看看