精华内容
下载资源
问答
  • 2020-12-13 16:18:39

    设计模式的使用场景。

    设计模式分为 3 大类型共 23 种:

    创建型:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

    结构型:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

    行为型:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

     

    最常见的设计模式有:单例模式、工厂模式、代理模式、构造者模式、责任链模式、适配器模式、观察者模式等

     

    面试中对于设计模式,你应该明白不同的设计用来解决什么场景问题,对于常用的设计模式能够灵活运用。下面重点介绍几种常用的设计模式。

     

    单例模式

    首先是单例模式,这个模式在实际业务中会经常用到,也是设计模式中的主要考察点。这里介绍线程安全的单例模式实现方式。

    单例模式常见的实现方式有三种。

    第一种是静态初始化方式,也叫作饿汉方式。实现的思路就是在类初始化时完成单例实例的创建,因此不会产生并发问题,在这种方式下不管是否会使用到这个单例,都会创建这个单例。

    第二种实现方式是双重检查,也叫作懒汉方式,只有在真正用到这个单例实例的时候才会去创建,如果没有使用就不会创建。这个方式必然会面对多个线程同时使用实例时的并发问题。为了解决并发访问问题,通过 synchronized 或者 lock 进行双重检查,保证只有一个线程能够创建实例。这里要注意内存可见性引起的并发问题,必须使用 volatile 关键字修饰单例变量。

    第三种是单例注册表方式,Spring 中 Bean 的单例模式就是通过单例注册表方式实现的。

    下面结合设计模式的实际应用,来介绍常用的设计模式,在面试时遇到类似问题,记得要将设计模式与实际业务场景进行结合,来体现对设计模式的理解和应用能力。

     

              

     

     

    工厂模式

    工厂模式是创建不同类型实例时常用的方式,例如 Spring 中的各种 Bean 是有不同 Bean 工厂类进行创建的。

     

    代理模式

    代理模式,主要用在不适合或者不能直接引用另一个对象的场景,可以通过代理模式对被代理对象的访问行为进行控制。Java 的代理模式分为静态代理和动态代理。静态代理指在编译时就已经创建好了代理类,例如在源代码中编写的类;动态代理指在 JVM 运行过程中动态创建的代理类,使用动态代理的方法有 JDK 动态代理、CGLIB、Javassist 等。面试时遇到这个问题可以举个动态代理的例子,比如在 Motan RPC 中,是使用 JDK 的动态代理,通过反射把远程请求进行封装,使服务看上去就像在使用本地的方法。

     

    责任链模式

    责任链模式有点像工厂的流水线,链上每一个节点完成对对象的某一种处理,例如 Netty 框架在处理消息时使用的 Pipeline 就是一种责任链模式。

     

    适配器模式

    适配器模式,类似于我们常见的转接头,把两种不匹配的对象来进行适配,也可以起到对两个不同的对象进行解藕的作用。例如我们常用的日志处理框架 SLF4J,如果我们使用了 SLF4J 就可以跟 Log4j 或者 Logback 等具体的日志实现框架进行解藕。通过不同适配器将 SLF4J 与 Log4j 等实现框架进行适配,完成日志功能的使用。

     

    观察者模式

    观察者模式也被称作发布订阅模式,适用于一个对象的某个行为需要触发一系列事件的场景,例如 gRPC 中的 Stream 流式请求的处理就是通过观察者模式实现的。

     

    构造者模式

    构造者模式,适用于一个对象有很多复杂的属性,需要根据不同情况创建不同的具体对象,例如创建一个 PB 对象时使用的 builder 方式。

     

    Java 语言特性知识点

    Java 语言特性的知识点汇总如下

     

                 

     

    常用集合类实现与 Java 并发工具包 JUC 是常见考点,JUC 会在后面的多线程课程中进行详细讲解。

    Java 的集合类中部分需要重点了解类的实现。例如,HashMap、TreeMap 是如何实现的等。

    动态代理与反射是 Java 语言的特色,需要掌握动态代理与反射的使用场景,例如在 ORM 框架中会大量使用代理类。而 RPC 调用时会使用到反射机制调用实现类方法。

    Java 基础数据类型也常常会在面试中被问到,例如各种数据类型占用多大的内存空间、数据类型的自动转型与强制转型、基础数据类型与 wrapper 数据类型的自动装箱与拆箱等。

    Java 对对象的引用分为强引用、软引用、弱引用、虚引用四种,这些引用在 GC 时的处理策略不同,强引用不会被 GC 回收;软引用内存空间不足时会被 GC 回收;弱引用则在每次 GC 时被回收;虚引用必须和引用队列联合使用,主要用于跟踪一个对象被垃圾回收的过程。

    Java 的异常处理机制就是 try-catch-finally 机制,需要知道异常时在 try catch 中的处理流程;需要了解 Error 和 Exception 的区别。

    最后 Java 的注解机制和 SPI 扩展机制可以作为扩展点适当了解。

     

    详解 Map

    关于 Java 的基础知识重点讲解最常考察点 HashMap 和 ConcurrentHashMap,以及 Java 的不同版本新技术特性

     

                 

     

    面试中,Map 的实现这个题目能够考察到数据结构、Java 基础实现以及对并发问题处理思路的掌握程度。

     

    HashMap

    先来看 HashMap 的实现,简单来说,Java 的 HashMap 就是数组加链表实现的,数组中的每一项是一个链表。通过计算存入对象的 HashCode,来计算对象在数组中要存入的位置,用链表来解决散列冲突,链表中的节点存储的是键值对。

    除了实现的方式,我们还需要知道填充因子的作用与 Map 扩容时的 rehash 机制,需要知道 HashMap 的容量都是 2 的幂次方,是因为可以通过按位与操作来计算余数,比求模要快。另外需要知道 HashMap 是非线程安全的,在多线程 put 的情况下,有可能在容量超过填充因子时进行 rehash,因为 HashMap 为了避免尾部遍历,在链表插入元素时使用头插法,多线程的场景下有可能会产生死循环。

    ConcurrentHashMap    

    从 HashMap 的非线程安全,面试官很自然地就会问到线程安全的 ConcurrentHashMap。ConcurrentHashMap 采用分段锁的思想来降低并发场景下的锁定发生频率,在 JDK1.7 与 1.8 中的实现差异非常大,1.7 中使用 Segment 进行分段加锁,降低并发锁定;1.8 中使用 CAS 自旋锁的乐观锁来提高性能,但是在并发度较高时性能会比较一般。另外 1.8 中的 ConcurrentHashMap 引入了红黑树来解决 Hash 冲突时链表顺序查找的问题。红黑树的启用条件与链表的长度和 Map 的总容量有关,默认是链表大于 8 且容量大于 64 时转为红黑树。这部分内容建议详细阅读源码进行学习。

     

    详解 Java 版本特性

                 

     

     

    Java 近些年一改以往的版本发布风格,发布频率提高了很多。目前大部分公司的生产环境使用的还是 1.8 版本,一少部分升级到 1.9 或 1.10 版本,Java 的 1.8 版本是一个长期支持的版本,最新发布的 1.11 版本也是一个长期支持的版本,1.11 版本中已经包含了 1.9、1.10 版本的功能,所以 1.8 和 1.11 版本是我们要重点关注的版本。

    在 1.8 版本中 Java 增加了对 lambda 表达式的支持,使 Java 代码的编写可以更简洁,也更方便支持并行计算。并且提供了很多 Stream 流式处理的 API。1.8 版本还支持了方法引用的能力,可以进一步简化 lambda 表达式的写法。

    在 1.8 版本中,接口可以提供默认方法了,这样可以简化一些简单的抽象类。最后在 1.8 版本中对方法区进行调整,使用 Metaspace 替换掉了 PermGen 的永久代。Metaspace 与 PermGen 之间最大的区别在于:Metaspace 并不在虚拟机中,而是使用本地内存。替换的目的一方面是可以提升对元数据的管理同时提升 GC 效率,另一方面是方便后续 HotSpot 与 JRockit 合并

    在 1.9、1.10 版本中的主要特性是增加了模块系统,将 G1 设为默认垃圾回收器、支持局部变量推断等功能。这些功能都已经包含在 1.11 版本中。

    1.11 版本是 Java 最新的长期支持版本,也将会是未来一段时间的主要版本,1.11 版本中提供的最激动人心的功能是 ZGC 这个新的垃圾回收器,ZGC 为大内存堆设计,有着非常强悍的性能,能够实现 10ms 以下的 GC 暂停时间。关于 ZGC 会在下一课中进一步介绍。除此之外,1.11 版本对字符串处理 API 进行了增强,提供了字符复制等功能。1.11 版本还内置了 HttpClient。

    更多相关内容
  • * 观察模式应用场景实例 * * 免责声明:本文只是以哈票网举例,示例中并未涉及哈票网任何业务代码,全部原创,如有雷同,纯属巧合。 * * 场景描述: * 哈票以购票为核心业务(此模式不限于该业务),但围绕购票...
  • 在传统的前端解耦方面,观察模式作为比较常见一种设计模式,大量使用在各种框架类库的设计当中。 核心代码: // eventProxy.js 'use strict'; const eventProxy = { onObj: {}, oneObj: {}, on: function(key,...
  • 二、观察模式适用场景、 三、观察模式优缺点、 四、观察模式代码示例、 1、被观察者、 2、观察者、 3、通知类、 4、测试类、 五、JDK 中的观察模式支持类、 1、Observable、 2、Observer、





    一、观察者模式简介



    观察者模式 : 定义了 对象之间 一对多 的 依赖 , 令 多个 观察者 对象 同时 监听 某一个 主题对象 , 当 主题对象 发生改变时 , 所有的 观察者 都会 收到通知 并更新 ;

    观察者 有多个 , 被观察的 主题对象 只有一个 ;

    如 : 在购物网站 , 多个用户关注某商品后 , 当商品降价时 , 就会自动通知关注该商品的用户 ;

    • 主题对象 : 商品是主题对象 ;
    • 观察者 : 用户是观察者 ;
    • 观察者注册 : 用户关注 , 相当于注册观察者 ;
    • 通知触发条件 : 商品降价 ;

    观察者模式 类型 : 行为型 ;





    二、观察者模式适用场景



    观察者模式适用场景 : 关联行为 场景 , 建立一套 触发机制 ;

    如 : 用户关注某个商品的价格 , 降价时进行通知 , 这样 用户商品 产生了关联 , 触发机制就是 商品降价 ,





    三、观察者模式优缺点



    观察者模式 优点 :

    • 抽象耦合 :观察者被观察者 之间 , 建立了一个 抽象的 耦合 ; 由于 耦合 是抽象的 , 可以很容易 扩展 观察者 和 被观察者 ;
    • 广播通信 : 观察者模式 支持 广播通信 , 类似于消息广播 , 如果需要接收消息 , 只需要注册一下即可 ;

    观察者模式 缺点 :

    • 依赖过多 : 观察者 之间 细节依赖 过多 , 会增加 时间消耗程序的复杂程度 ;
      这里的 细节依赖 指的是 触发机制 , 触发链条 ; 如果 观察者设置过多 , 每次触发都要花很长时间去处理通知 ;
    • 循环调用 : 避免 循环调用 , 观察者 与 被观察者 之间 绝对不允许循环依赖 , 否则会触发 二者 之间的循环调用 , 导致系统崩溃 ;




    四、观察者模式代码示例



    JDK 中提供了观察者模式的支持 ;

    • 被观察者 : 被观察者 继承 Observable 类 ;
    • 观察者 : 观察者 实现 Observer 接口 ;
    • 关联 观察者 与 被观察者 : 调用 被观察者 的 addObserver 方法 , 关联二者 ;
    • 触发通知 : 被观察者 数据改变时 , 调用 setChangednotifyObservers 方法 , 会自动回调 观察者的 update 方法 ;

    用户在游戏中提出问题 , 管理员负责监听并处理问题 ;


    1、被观察者


    package observer;
    
    import java.util.Observable;
    
    /**
     * 被观察的主题对象
     *      JDK 提供了对观察者模式的支持 , 被观察者可以继承 Observable 类
     *
     * 被观察对象 继承 Observable 类
     */
    public class Game extends Observable {
        private String name;
    
        public Game(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        /**
         * 用户提交问题
         * @param game
         * @param question
         */
        public void produceQuestion(Game game, Question question) {
            System.out.println(question.getUserName() +
                    " 在 " + game.name + " 游戏中提交问题 : " + question.getContent());
    
            // 该方法是 Observable 提供的方法
            // 将 private boolean changed = false 成员变量设置为 true
            // 代表 被观察者 的状态发生了改变
            setChanged();
    
            // 通知 观察者
            notifyObservers(question);
        }
    }
    

    2、观察者


    package observer;
    
    import java.util.Observable;
    import java.util.Observer;
    
    /**
     * 管理员类
     *      管理员类观察的是游戏
     *      用户反馈的问题 属于 游戏 , 管理员关注的是游戏
     *      无法关注 问题
     *
     * 如 : 在电商平台 , 关注的是某个商品 , 在降价时发送通知
     *      商品是存在的 , 降价消息 在关注的时候还没有被创建 , 是无法获取依赖的
     */
    public class Manager implements Observer {
        /**
         * 管理员名称
         */
        private String name;
    
        public Manager(String name) {
            this.name = name;
        }
    
        @Override
        public void update(Observable o, Object arg) {
            // 获取 被观察者 对象
            Game game = (Game) o;
    
            // 获取 被观察者 对象 调用 notifyObservers 方法的参数
            Question question = (Question) arg;
    
            System.out.println(name + " 观察者 接收到 被观察者 " + game.getName() +
                    " 的通知 , 用户 " + question.getUserName() +
                    " 提出问题 " + question.getContent());
        }
    }
    

    3、通知类


    package observer;
    
    public class Question {
        /**
         * 用户名
         */
        private String userName;
    
        /**
         * 问题内容
         */
        private String content;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }
    

    4、测试类


    package observer;
    
    public class Main {
        public static void main(String[] args) {
            // 创建被观察者
            Game game = new Game("Cat And Mouse");
            // 创建观察者
            Manager manager = new Manager("Tom");
    
            // 关联 观察者 与 被观察者
            game.addObserver(manager);
    
            // 业务逻辑 : 用户提出问题到游戏中 , 管理员接收到通知消息
            Question question = new Question();
            question.setUserName("Jerry");
            question.setContent("游戏崩溃");
    
            // 在游戏中提交问题
            game.produceQuestion(game, question);
        }
    }
    

    执行结果 :

    JerryCat And Mouse 游戏中提交问题 : 游戏崩溃
    Tom 观察者 接收到 被观察者 Cat And Mouse 的通知 , 用户 Jerry 提出问题 游戏崩溃
    

    在这里插入图片描述





    五、JDK 中的观察者模式支持类




    1、Observable


    被观察者需要继承该类 ;

    public class Observable {
        private boolean changed = false;
        /** 使用 Vector 是线程安全的集合 , 存放观察者对象 , 在构造器中初始化该类 */
        private Vector<Observer> obs;
    
        /** Construct an Observable with zero Observers. */
    
        public Observable() {
            obs = new Vector<>();
        }
    
        /**
         * 添加观察者对象 , 采用了 synchronized 修饰 , 是同步方法 , 保证了线程安全 
         *
         * @param   o   an observer to be added.
         * @throws NullPointerException   if the parameter o is null.
         */
        public synchronized void addObserver(Observer o) {
            if (o == null)
                throw new NullPointerException();
            if (!obs.contains(o)) {
                obs.addElement(o);
            }
        }
    
        /**
         * 删除观察者 
         */
        public synchronized void deleteObserver(Observer o) {
            obs.removeElement(o);
        }
    
        /**
         * 通知观察者 , 无参
         *
         * @see     java.util.Observable#clearChanged()
         * @see     java.util.Observable#hasChanged()
         * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
         */
        public void notifyObservers() {
            notifyObservers(null);
        }
    
        /**
         * 通知观察者 , 有参
         *
         * @param   arg   any object.
         * @see     java.util.Observable#clearChanged()
         * @see     java.util.Observable#hasChanged()
         * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
         */
        public void notifyObservers(Object arg) {
            Object[] arrLocal;
    
            synchronized (this) {
                if (!changed)
                    return;
                arrLocal = obs.toArray();
                clearChanged();
            }
    
            for (int i = arrLocal.length-1; i>=0; i--)
                ((Observer)arrLocal[i]).update(this, arg);
        }
    
        public synchronized void deleteObservers() {
            obs.removeAllElements();
        }
    
        protected synchronized void setChanged() {
            changed = true;
        }
    
        protected synchronized void clearChanged() {
            changed = false;
        }
    
        public synchronized boolean hasChanged() {
            return changed;
        }
    
        /**
         * 查看观察者数量 
         *
         * @return  the number of observers of this object.
         */
        public synchronized int countObservers() {
            return obs.size();
        }
    }
    

    2、Observer


    观察者需要实现该接口 ;

    package java.util;
    
    /**
     * A class can implement the <code>Observer</code> interface when it
     * wants to be informed of changes in observable objects.
     *
     * @author  Chris Warth
     * @see     java.util.Observable
     * @since   JDK1.0
     */
    public interface Observer {
        /**
         * 当 被观察者 对象发生改变时 , 即被观察者对象调用 notifyObservers 方法时 , 自动调用该方法
         *
         * @param   o     被观察的对象.
         * @param   arg   被观察对象调用 notifyObservers 方法时传入的参数 
         */
        void update(Observable o, Object arg);
    }
    
    
    展开全文
  • 二、使用场景 关联行为场景,需要注意的是关联行为是可拆分的而不是“组合”关系 事件多级触发场景 跨系统的消息交换场景,如消息队列、事件总线的处理机制 三、简单实现 这里我们以微信公众号的订阅为例。公众号...
  • 观察模式的应用场景

    千次阅读 2020-11-09 19:09:05
    观察模式主要用于在关联行为之间建立一套触发机制的场景观察模式在现实生活应用也非常广泛,比如:微信朋友圈动态通知、消息通知、邮件通知、广播通知、桌面程序的事件响应等(如下图)。 现在大家都用过...

    观察者模式(Observer Pattern)定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新,属于行为型模式。观察者模式有时也叫做发布订阅模式。观察者模式主要用于在关联行为之间建立一套触发机制的场景。观察者模式在现实生活应用也非常广泛,比如:微信朋友圈动态通知、消息通知、邮件通知、广播通知、桌面程序的事件响应等(如下图)。

    现在大家都用过我们的生态圈了,当小伙伴们在生态圈中提问的时候,如果有设置指定老师回答,对应的老师就会收到邮件通知,这就是观察者模式的一种应用场景。我们有些小伙伴可能会想到MQ,异步队列等,其实JDK 本身就提供这样的API。我们用代码来还原一下这样一个应用场景,创建GPer 类:

    public class GPer extends Observable{
    
        private String name = "GPer生态圈";
        private static GPer gper = null;
        private GPer(){}
    
        public static GPer getInstance(){
            if(null == gper){
                gper = new GPer();
            }
            return gper;
        }
    
        public String getName() {
            return name;
        }
    
        public void publishQuestion(Question question){
            System.out.println(question.getUserName() + "在" + this.name + "上提交了一个问题。");
            setChanged();
            notifyObservers(question);
        }
    }

    创建问题Question 类:

    public class Question {
    
        private String userName;
        private String content;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }

    创建老师Teacher 类:

    public class Teacher implements Observer {
        private String name;
        public Teacher(String name){
            this.name = name;
        }
    
        public void update(Observable o, Object arg) {
            GPer gper = (GPer)o;
            Question question = (Question)arg;
            System.out.println("===============================");
            System.out.println(name + "老师,你好!\n" +
            "您收到了一个来自“" + gper.getName() + "”的提问,希望您解答,问题内容如下:\n" +
            question.getContent() + "\n" +
            "提问者:" + question.getUserName());
        }
    }

    客户端测试代码:

    public class ObserverTest {
        public static void main(String[] args) {
            GPer gper = GPer.getInstance();
            Teacher tom = new Teacher("Tom");
            Teacher mic = new Teacher("Mic");
    
    
            //这为没有@Tom老师
            Question question = new Question();
            question.setUserName("小明");
            question.setContent("观察者设计模式适用于哪些场景?");
            gper.addObserver(tom);
            gper.addObserver(mic);
            gper.publishQuestion(question);
    
    
        }
    
    }
    

    在下面我们再来设计一个业务场景,帮助小伙伴更好的理解观察者模式。JDK 源码中,观察者模式也应用非常多。例如java.awt.Event 就是观察者模式的一种,只不过Java 很少被用来写桌面程序。我们自己用代码来实现一下,以帮助小伙伴们更深刻地了解观察者模式的实现原理。首先,创建Event 类:

    /**
     * 监听器的一种包装,标准事件源格式的定义
     */
    public class Event {
        //事件源,事件是由谁发起的保存起来
        private Object source;
        //事件触发,要通知谁
        private Object target;
        //事件触发,要做什么动作,回调
        private Method callback;
        //事件的名称,触发的是什么事件
        private String trigger;
        //事件触发的时间
        private long time;
    
        public Event(Object target, Method callback) {
            this.target = target;
            this.callback = callback;
        }
    
        public Event setSource(Object source) {
            this.source = source;
            return this;
        }
    
        public Event setTime(long time) {
            this.time = time;
            return this;
        }
    
        public Object getSource() {
            return source;
        }
    
        public Event setTrigger(String trigger) {
            this.trigger = trigger;
            return this;
        }
    
        public long getTime() {
            return time;
        }
    
        public Object getTarget() {
            return target;
        }
    
        public Method getCallback() {
            return callback;
        }
    
        @Override
        public String toString() {
            return "Event{" + "\n" +
                    "\tsource=" + source.getClass() + ",\n" +
                    "\ttarget=" + target.getClass() + ",\n" +
                    "\tcallback=" + callback + ",\n" +
                    "\ttrigger='" + trigger + "',\n" +
                    "\ttime=" + time + "'\n" +
                    '}';
        }
    }

    创建EventLisenter 类:

    /**
     * 监听器,它就是观察者
     */
    public class EventLisenter {
    
        //JDK底层的Lisenter通常也是这样来设计的
        protected Map<String,Event> events = new HashMap<String,Event>();
    
        //事件名称和一个目标对象来触发事件
        public void addLisenter(String eventType,Object target){
            try {
                this.addLisenter(
                        eventType,
                        target,
                        target.getClass().getMethod("on" + toUpperFirstCase(eventType),Event.class));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        public void addLisenter(String eventType,Object target,Method callback){
            //注册事件
            events.put(eventType, new Event(target, callback));
        }
    
    
        //触发,只要有动作就触发
        private void trigger(Event event) {
            event.setSource(this);
            event.setTime(System.currentTimeMillis());
    
            try {
                //发起回调
                if(event.getCallback() != null){
                    //用反射调用它的回调函数
                    event.getCallback().invoke(event.getTarget(),event);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //事件名称触发
        protected void trigger(String trigger){
            if(!this.events.containsKey(trigger)){return;}
            trigger(this.events.get(trigger).setTrigger(trigger));
        }
    
        //逻辑处理的私有方法,首字母大写
        private String toUpperFirstCase(String str){
            char[] chars = str.toCharArray();
            chars[0] -= 32;
            return String.valueOf(chars);
        }
    
    }
    

    创建MouseEventType 接口:

    public interface MouseEventType {
        //单击
        String ON_CLICK = "click";
    
        //双击
        String ON_DOUBLE_CLICK = "doubleClick";
    
        //弹起
        String ON_UP = "up";
    
        //按下
        String ON_DOWN = "down";
    
        //移动
        String ON_MOVE = "move";
    
        //滚动
        String ON_WHEEL = "wheel";
    
        //悬停
        String ON_OVER = "over";
    
        //失焦
        String ON_BLUR = "blur";
    
        //获焦
        String ON_FOCUS = "focus";
    }

    创建Mouse 类:

    public class Mouse extends EventLisenter {
    
        public void click(){
            System.out.println("调用单击方法");
            this.trigger(MouseEventType.ON_CLICK);
        }
    
        public void doubleClick(){
            System.out.println("调用双击方法");
            this.trigger(MouseEventType.ON_DOUBLE_CLICK);
        }
    
        public void up(){
            System.out.println("调用弹起方法");
            this.trigger(MouseEventType.ON_UP);
        }
    
        public void down(){
            System.out.println("调用按下方法");
            this.trigger(MouseEventType.ON_DOWN);
        }
    
        public void move(){
            System.out.println("调用移动方法");
            this.trigger(MouseEventType.ON_MOVE);
        }
    
        public void wheel(){
            System.out.println("调用滚动方法");
            this.trigger(MouseEventType.ON_WHEEL);
        }
    
        public void over(){
            System.out.println("调用悬停方法");
            this.trigger(MouseEventType.ON_OVER);
        }
    
        public void blur(){
            System.out.println("调用获焦方法");
            this.trigger(MouseEventType.ON_BLUR);
        }
    
        public void focus(){
            System.out.println("调用失焦方法");
            this.trigger(MouseEventType.ON_FOCUS);
        }
    }

    创建回调方法MouseEventCallback 类:

    /**
     * 自己写的逻辑,用于回调
     */
    public class MouseEventCallback {
    
        public void onClick(Event e){
            System.out.println("===========触发鼠标单击事件==========" + "\n" + e);
        }
    
        public void onDoubleClick(Event e){
            System.out.println("===========触发鼠标双击事件==========" + "\n" + e);
        }
    
        public void onUp(Event e){
            System.out.println("===========触发鼠标弹起事件==========" + "\n" + e);
        }
    
        public void onDown(Event e){
            System.out.println("===========触发鼠标按下事件==========" + "\n" + e);
        }
    
        public void onMove(Event e){
            System.out.println("===========触发鼠标移动事件==========" + "\n" + e);
        }
    
        public void onWheel(Event e){
            System.out.println("===========触发鼠标滚动事件==========" + "\n" + e);
        }
    
        public void onOver(Event e){
            System.out.println("===========触发鼠标悬停事件==========" + "\n" + e);
        }
    
        public void onBlur(Event e){
            System.out.println("===========触发鼠标失焦事件==========" + "\n" + e);
        }
    
        public void onFocus(Event e){
            System.out.println("===========触发鼠标获焦事件==========" + "\n" + e);
        }
    
    }

    客户端测试代码:

    public class MouseEventTest {
        public static void main(String[] args) {
    
            MouseEventCallback callback = new MouseEventCallback();
    
            Mouse mouse = new Mouse();
    
            //@谁?  @回调方法
            mouse.addLisenter(MouseEventType.ON_CLICK,callback);
            mouse.addLisenter(MouseEventType.ON_FOCUS,callback);
    
            mouse.click();
    
            mouse.focus();
    
    
        }
    }

     

    展开全文
  • 主要介绍了PHP 观察模式,结合实例形式深入分析了对观察模式的理解与应用及相关注意事项,需要的朋友可以参考下
  • 当对象间存在一对多关系时,则使用观察模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察模式属于行为型模式。 简而言之,就两个点: 一对多 发布&订阅 举个例子 ,...

    1.介绍

    当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

    简而言之,就两个点:

    • 一对多
    • 发布&订阅

    举个例子 ,我们平时接触的dom事件. 也是js和dom之间实现的一种观察者模式.
    在这里插入图片描述
    只要订阅了div的click事件. 当点击div的时候, function click就会被触发.

    展开全文
  • 主要介绍了php设计模式中的观察模式使用php实现观察模式,感兴趣的小伙伴们可以参考一下
  •  观察模式是写松耦合代码的必备模式,重要性不言而喻,抛开代码层面,许多组件都采用了Publish-Subscribe模式,所以我想按照自己的理解重新设计一个使用场景并把观察模式灵活使用在其中  我想把C#中实现观察...
  • 1.观察模式是写松耦合代码的必备模式,重要性不言而喻,抛开代码层面,许多组件都采用了Publish-Subscribe模式,所以我想按照自己的理解重新设计一个使用场景并把观察模式灵活使用在其中 2.我想把C#中实现观察者...
  • 观察者结构图: 使用场景:老板回来通知员工需要进入工作状态。 定义观察者的抽象类: 代码如下: abstract class Observer { protected string name; protected ISubject sub; public Observer(string name, ...
  • 观察模式java

    2017-06-19 22:12:27
    观察模式java 应用场景如下 现在有一个销售各类的电子商务网站的购物车(Shopping Cart)系统。现在本网站进行打折,分别情况如下: 1. 对所有的教材类图书实行每本降价一元的折扣 2. 对连环画类图书提供7%的...
  • 最近在重构中用到了设计模式中的观察模式,简单的跟大家分享一下观察模式的原理和使用场景。 在进入正题之前,先简单的介绍一下业务场景,交易系统中很重要的一个流程就是订单状态的流转,这次重构的就是订单...
  • 观察模式应用场景实例

    千次阅读 2017-10-22 16:07:15
    观察模式应用场景实例一个典型的购票网站,以购票为核心业务(此模式不限于该业务),但围绕购票会产生不同的其他逻辑,如: 1. 购票后记录文本日志 2. 购票后记录数据库日志 3. 购票后发送短信 4. 购票送抵扣卷...
  • 本文实例讲述了javascript设计模式观察模式原理与用法。分享给大家供大家参考,具体如下: 介绍:前面我们针对系统内一对多,多对多的情况做了解决方案,是使用中介者模式,将...场景:我们使用观察模式做一
  • 观察模式 | C#实现

    千次阅读 2022-04-12 22:41:35
    什么是观察模式?...当使用观察模式后,观察者只需要知道观察目标发生了改变,而不需要知道究竟发生了什么改变;同理,观察目标只需要发出通知,让所有观察者自行做出响应。 游戏中的事件系统就很适合
  • 主要介绍了Java回调函数与观察模式实例代码,简单介绍了使用观察模式场景,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
  • 什么是观察模式

    千次阅读 2021-11-01 18:40:00
    观察模式 观察模式,也被称为发布订阅模式,是一种行为型设计模式,也是在实际的开发中用得比较多的一种模式,当对象间存在一对多关系时,就可以使用观察模式。定义对象间的一种一对多的依赖关系,当一个对象...
  • js的设计模式 - 【观察模式

    千次阅读 2022-03-21 15:12:41
    当对象间存在一对多关系时,则使用观察模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。一对多的关系。
  • java中观察模式使用场景

    千次阅读 2016-11-07 10:44:50
    观察模式 是一种非常经典 非常常用的设计模式。  一个对象的行为 依赖于 另一个对象的状态。或者换一种说法,当被观察对象(目标对象)的状态发生改变时 ,会直接影响到观察对象的行为。 特点一 : 被观察...
  • 观察模式(Observer Pattern)是对象的行为模式,又叫发布-订阅模式、源-监听器模式和从属者模式等。 两种模型(推模型和拉模型): ■推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不...
  • Java设计模式常见使用场景

    万次阅读 多人点赞 2018-05-09 16:07:16
    一、Java I/O中的设计模式1、适配器模式适配器模式就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。通常被用在一个项目需要引用一些开源框架来...
  • java设计模式--观察模式应用场景

    千次阅读 2017-02-17 16:07:43
    观察者分为两种模式:推和拉 推模型是假定知道观察者需要什么数据,传这个数据过去;拉模型是不知道观察者需要什么数据,干脆把自身传给他,按需取值 应用场景如下: 订阅火车票之后,需要记录日志,也需要...
  • 观察模式的效果有以下的优点:第一、观察模式在被观察者和观察者之间建立一个抽象的耦合。观察模式有下面的缺点:第一、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很...
  • 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计...
  • 优化方案:使用观察模式,使创建订单和消息通知进行分离,低耦合。可以选择消息队列,spring事件机制等,本文选择Spring事件机制。   改造开始: 1.创建事件 package ...
  • Java设计模式观察模式

    千次阅读 2021-09-21 16:57:24
    前言:在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多...所有这些,如果用观察模式来实现就非常方便。 一、观察模式简介 1.1、观察模式概述 观察模式(Observer
  • 观察模式中主体和观察者是互相感知的,发布-订阅模式是借助第三方来实现调度的,发布者和订阅者之间互不感知 联系 发布-订阅模式观察模式的一种变体。发布-订阅只是把一部分功能抽象成一个独立的Change...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 141,223
精华内容 56,489
关键字:

观察模式使用场景

友情链接: Line.rar