在商城系统中使用设计模式----策略模式之在spring中使用观察者模式和发布/订阅

1.概念:

观察者模式:

  是属于设计者模式中的一种,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。

发布/订阅:

  是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者),而是通过调度器将消息发布给订阅者。

2.区别:下图明显可以看出发布/订阅比观察者模式中多了一层中间信道,

  

  • 在Observer模式中,O bservers知道Subject,同时Subject还保留了Observers的记录。然而,在发布者/订阅者中,发布者和订阅者不需要彼此了解。他们只是在消息队列或代理的帮助下进行通信。
  • 在Publisher / Subscriber模式中,组件是松散耦合的,而不是Observer模式。
  • 观察者模式主要以同步方式实现,即当某些事件发生时,Subject调用其所有观察者的适当方法。的发行者/订户图案在一个实施大多异步方式(使用消息队列)。
  • 观察者模式需要在单个应用程序地址空间中实现。另一方面,发布者/订阅者模式更像是跨应用程序模式。

3.使用场景:

  当用户下单成功后,要执行 修改订单状态,分佣,通知店主发货。

4.实现一:观察者模式:

 (1)  java.util包提供了对该模式的支持,提供了Observer(观察者)方法和Obervable(被观察者)方法。

package java.util;

public interface Observer {
    /**
   * 每当观察对象发生变化时,都会调用此方法。
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}
package java.util;

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    /** Construct an Observable with zero Observers. */
    public Observable() {
        obs = new Vector<>();
    }

    /**
     *  添加观察者
     * @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);
        }
    }

    /**
     * 删除观察者
     * @param   o   the observer to be deleted.
     */
    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);
    }

    /**
     * 通知观察者*/
    public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        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);
    }

    /**
     * Clears the observer list so that this object no longer has any observers.
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    /**
     * Marks this <tt>Observable</tt> object as having been changed; the
     * <tt>hasChanged</tt> method will now return <tt>true</tt>.
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    /**
     * Indicates that this object has no longer changed, or that it has
     * already notified all of its observers of its most recent change,
     * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
     * This method is called automatically by the
     * <code>notifyObservers</code> methods.
     *
     * @see     java.util.Observable#notifyObservers()
     * @see     java.util.Observable#notifyObservers(java.lang.Object)
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    /**
     * Tests if this object has changed.
     *
     * @return  <code>true</code> if and only if the <code>setChanged</code>
     *          method has been called more recently than the
     *          <code>clearChanged</code> method on this object;
     *          <code>false</code> otherwise.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#setChanged()
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * Returns the number of observers of this <tt>Observable</tt> object.
     *
     * @return  the number of observers of this object.
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

  (2)被观察者继承Observable类。

import java.util.Observable;

/**
 * @description:被观察者
 * @author: Chen
 * @create: 2019-04-03 23:01
 **/
public class PayObservable extends Observable {

    @Override
    public void notifyObservers() {
        System.out.println("有人下单啦");
        setChanged();
        super.notifyObservers();
    }
}

(3)观察者继承Observer接口

/**
 * @description:佣金观察者
 * @author: Chen
 * @create: 2019-04-03 22:55
 **/
public class CommissionObserver implements Observer {

    public CommissionObserver(Observable observable){
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("大家注意了,有傻逼下单了,我要开始分佣金了");
    }
}
package com.chen.observer;

import java.util.Observable;
import java.util.Observer;

/**
 * @description:消息观察者
 * @author: Chen
 * @create: 2019-04-03 22:50
 **/
public class MsgObserver implements Observer {

    public MsgObserver(Observable observable){
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("管理员,有人下单啦。");
    }
}
package com.chen.observer;

import java.util.Observable;
import java.util.Observer;

/**
 * @description:订单观察者
 * @author: Chen
 * @create: 2019-04-03 22:49
 **/
public class OrderObserver implements Observer {

    public OrderObserver(Observable observable){
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("赶紧把订单改成已支付");
    }
}

(4)调用入口

/**
 * @description:当用户下单成功后,要执行 修改订单状态,分佣,通知店主发货
 * @author: Chen
 * @create: 2019-04-03 22:34
 **/
public class ObserverMain {

    public static void main(String[] args) {

        PayObservable payObservable = new PayObservable();

        new CommissionObserver(payObservable);
        new MsgObserver(payObservable);
        new OrderObserver(payObservable);

        payObservable.notifyObservers();
    }
}

执行结果:

源码地址:商城中的观察者模式

原文地址:https://www.cnblogs.com/boychen/p/10747791.html

时间: 2024-10-16 22:04:25

在商城系统中使用设计模式----策略模式之在spring中使用观察者模式和发布/订阅的相关文章

在商城系统中使用设计模式----策略模式

1.概念: 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象.策略对象改变 context 对象的执行算法. 2.注意: 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护. 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为. 注意事项:如果一个系统的策略多于四个,就需要考虑使用

转:多篇文章中的设计模式-------策略模式

DRY原则和设计模式 前两天在做统计程序时,需要读取linux中的日志文件,在网上查了下,就有了结论,于是,根据需要,我写下了这样的代码: [java] view plaincopy public class dealFile { public static void dealContent(String[] commands){ BufferedReader reader=null; try{ Process process = Runtime.getRuntime().exec (comma

[工作中的设计模式]策略模式stategy

一.模式解析 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式的关键点为: 1.多种算法存在 2.算法继承同样的接口,执行同样的行为,为可以替代的 3.算法调用者唯一,算法调用者可以灵活改变自己需要调用的算法,从而实现计算. 二.模式代码 算法接口: /** * 算法统一接口,所有算法继承此接口 * @author zjl * @time 2016-1-24 * */ public interface IStra

ruby中的设计模式--策略模式

模板模式固然不错,但其还是有一些缺陷的.比如其实现依赖于继承并且缺足够的灵活性.在这时候我们就需要找到一个更加优化的解决方案——策略模式. 下面是使用策略模式实现的Report模板 1 # 策略1 2 class HTMLFormatter 3 def output_report title, text 4 puts '<html>' 5 puts ' <head>' 6 puts ' <title>' + title + '</title>' 7 puts

2.大话设计模式-策略模式

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DesignModel 8 { 9 /// <summary> 10 /// 策略模式 11 /// </summary> 12 public class TacticsModel 13 { 14 //对于

设计模式—策略模式

什么是策略模式? 策略模式定义了算法家族,分别封装起来,让它们之间能够相互替换,此模式让算法的变化不会影响到使用算法 的客户. 策略模式是一种定义一系列算法的方法,从概念上看全部这些算法完毕的都是同样的工作,仅仅是实现不同,它可 以以同样的方式调用全部的算法,降低了各种算法类与使用算法之间的耦合. 策略模式的长处? (1)策略模式的Strategy类层为Context类定义了一系列的可供重用的算法和行为.继承有助于析取出这些算法 的公共功能. (2)简化了单元測试(每一个算法都有自己的类,能够通

JavaScript设计模式 策略模式

在现实中,我们到达一个地方,通常可以选择不同的方式,例如自行车,火车,汽车,飞机等. 在程序设计中,通常也会有这样的情况,实现一个功能有多个方案可以选择,比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法. 而这种情况,在设计模式中,称为策略模式. 策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 例子: 很多公司的年终奖是根据员工的工资基数和年底绩效情况来方法的.如S级绩效为4倍工资,A级有3倍工资,B级有两倍工资. 在不使用策略模式的情况下,

head first 设计模式 策略模式

HEAD FIRST:策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 设计模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于它的客户而变化. 大话设计模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 使用这个模式的原因: 用许多的算法对一类进行计算.那么如果把这些算法强行编码到这个类当中.其实是不可取的.因为很多时候下不同的情况下使用不同的算

[设计模式] 策略模式(Strategy)

reference to : http://www.cnblogs.com/spring5/archive/2011/10/20/2485291.html 一.概要我们构建程序的时候,会遇到这样的状况,对象有某个行为,但是在不同的场景中,使用策略模式,可以把它们一个个封装起来,并且使它们可相互替换,而起使得算法可独立于使用它的客户而变化. 二.生活举例对于一个商店来讲,对不同的客户要报不同的价格,比如:(1)对普通客户或者是新客户报的是全价(2)对老客户(会员)报的价格,要给予一定的折扣(3)对