行为型模式之观察者模式(Observer Pattern)

1.定义

对象之间的一种一对多的依赖关系,其中的一个对象状态发生了变化,依赖中其他相关的对象接收到了通知并自动更新。

2.案例

Sunny软件公司欲开发一款实时在线股票软件,该软件需提供如下功能:当股票购买者所购买的某支股票价格变化幅度达到5%时,系统将自动发送通知(包括新价格)给购买该股票的所有股民。试使用观察者模式设计并实现该系统。

2.1 UML

2.2 代码

/**
 * @ClassName Launcher
 * @Description: 启动类(观察者模式)
 * @Author cw
 * @Date 2020/3/2
 **/
public class Launcher {

    /**
     * Sunny软件公司欲开发一款实时在线股票软件,
     * 该软件需提供如下功能:当股票购买者所购买的某支股票价格变化幅度达到5%时,
     * 系统将自动发送通知(包括新价格)给购买该股票的所有股民。
     * 试使用观察者模式设计并实现该系统。
     * @param args
     */
    public static void main(String[] args) {
        StockObserver stockA = new StockObserver("001", "A股票",new BigDecimal(1.1));
        StockObserver stockB = new StockObserver("002", "B股票",new BigDecimal(2));
        Buyer buyerA = new Buyer("唐僧");
        Buyer buyerB = new Buyer("悟空");
        Buyer buyerC = new Buyer("八戒");

        Control control = new StockMarketControl();
        control.attach(stockA.getKey(), buyerA);
        control.attach(stockA.getKey(), buyerC);
        
        control.attach(stockB.getKey(), buyerA);
        control.attach(stockB.getKey(), buyerB);

        stockA.change(control,new BigDecimal(-0.05));


    }

}

/**
 * 抽象观察类(股票)
 */
interface Observer {
    public void change(Control control, BigDecimal percent);//变化具体数值

}

/**
 * 具体观察类(股票)
 */
class StockObserver implements Observer {
    private String key;//股票唯一编码
    private String name;//股票名称
    private BigDecimal price;//股票价格

    public StockObserver(String key, String name,BigDecimal price) {
        this.key = key;
        this.name = name;
        this.price = price;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    @Override
    public void change(Control control, BigDecimal percent) {
        control.publish(this, percent);
    }
}


/**
 * 购买者类
 */
class Buyer {
    private String name;//购买者

    public Buyer(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void receive(StockObserver stock,BigDecimal floatRate) {
        System.out.println(name + "接收;股票【" + stock.getName() + "】浮动价格【"+(stock.getPrice().multiply(floatRate)).setScale(2, BigDecimal.ROUND_HALF_UP)+"】");
    }
}

/**
 * 抽象控制类
 */
abstract class Control {
    Map<String, List<Buyer>> mapStock = new HashMap<>();

    public void attach(String key, Buyer buyer) {
        List<Buyer> listBuyer = mapStock.get(key);
        if (listBuyer == null) {
            listBuyer = new ArrayList<>();
            listBuyer.add(buyer);
            mapStock.put(key, listBuyer);
        } else {
            listBuyer.add(buyer);
        }
    }

    public abstract void publish(StockObserver stock, BigDecimal percent);
}

/**
 * 具体控制类(股市)
 */
class StockMarketControl extends Control {
    @Override
    public void publish(StockObserver stock, BigDecimal percent) {
         if (percent.compareTo(new BigDecimal(0.05)) < 0 && percent.compareTo(new BigDecimal(-0.05)) > 0){
             System.out.println("股票:" + stock.getName() + ";涨幅没有到达5%,不进行通知");
             return;
         }

        List<Buyer> lstBuyer = mapStock.get(stock.getKey());
        if (lstBuyer == null) {
            System.out.println("股票:" + stock.getName() + ";暂时没人购买");
            return;
        }

        lstBuyer.forEach(item -> {
            item.receive(stock,percent);
        });
    }
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值