学习了刘老师写的设计模式,观察者模式史上最全设计模式导学目录(完整版)_刘伟技术博客-CSDN博客

对象间的联动——观察者模式(六)_刘伟技术博客-CSDN博客 做一下后面的练习题。

练习

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

首先分析问题,问题里面有两个对象,一个是股票,一个是股民, 其中股票里面有一个元素 股价, 股票作为被观察者, 股民作为观察者。 当股民买入股票价格幅度达到5%通知股民,这里的变化5%,有两个比较对象,一个是股票价格和自己比较上涨或下跌5% 。 还有一个是股票价格和股民买入时的价格比较上涨或下跌5%。实际炒股过程中都是和买入价作比较的。

这里我们针对股票和股民抽象两个接口。

股票抽象对象:有几个属性:股票名称,股票价格,买入者列表,买入股票方法,卖出股票方法, 抽象方法 通知买者方法 notifySHare();

package com.pattern.observer.practice.abs;import java.util.ArrayList;
import java.util.List;/*** 股票对象*/
public abstract class SharesControlCenter {//股票名称protected String name;//股票价格protected double price;//买入者protected List<ShareHolder> shareHolderList = new ArrayList<ShareHolder>();/*** 买入股票*/public void buyShare(ShareHolder shareHolder){System.out.println(shareHolder.getName() + " buy " + name + " price " + price);if(!shareHolderList.contains(shareHolder)){shareHolderList.add(shareHolder);}}/*** 卖出股票* @param shareHolder*/public void sellShare(ShareHolder shareHolder){System.out.println(shareHolder.getName() + " sell " + name + " price " + price);shareHolderList.remove(shareHolder);}/*** 通知买者*/public abstract void notifyShare();public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}/*** 股价变化方法。* @param price*/protected abstract void setPrice(double price);
}

股民接口:这里有几个方法:接收通知方法,买入股票方法,卖出股票方法,获取买入股票价格方法。

package com.pattern.observer.practice.abs;
//股民接口。
public interface ShareHolder {//获取名称String getName();//设置名称void setName(String name);//接收通知方法void notifyShare(SharesControlCenter share);//买入股票void buyShare(SharesControlCenter share);//卖出股票void sellShare(SharesControlCenter share);//获取买入股票价格double getPrice(SharesControlCenter share);
}

然后再创建具体的股票类和实际买者:

package com.pattern.observer.practice;import com.pattern.observer.practice.abs.ShareHolder;
import com.pattern.observer.practice.abs.SharesControlCenter;import java.text.DecimalFormat;/*** 实际股票*/
public class SharesInfo extends SharesControlCenter {public SharesInfo(String name, double price) {System.out.println(name + " shares OK!");this.price = price;super.setName(name);}/*** 通知买者*/@Overridepublic void notifyShare() {for (ShareHolder shareHolder : shareHolderList) {double buyPrice = shareHolder.getPrice(this);double change = (buyPrice - this.price)/buyPrice;//当股票价格针对买入价格有5% 的变化,则通知购买者。if(change >= 0.05 || change <= -0.05){shareHolder.notifyShare(this);}}}//设置股票价格,@Overrideprotected void setPrice(double price) {double change = (price - this.price)/this.price;DecimalFormat df = new DecimalFormat("#.00");if (change > 0){System.out.println(this.getName() + " rise " + df.format(change * 100) + "%" + " now price:" + price);}else if(change < 0){System.out.println(this.getName() + " fall " + df.format(change * 100) + "%" + " now price:" + price);}else{System.out.println(this.getName() + " now price:" + price);}this.price = price;notifyShare();}
}

增加股民实体:

package com.pattern.observer.practice;import com.pattern.observer.practice.abs.ShareHolder;
import com.pattern.observer.practice.abs.SharesControlCenter;import java.util.HashMap;
import java.util.Map;public class ShareHolderPersion implements ShareHolder {//买者名称String name;//买者买到的股票价格,Map<SharesControlCenter,Double> shares = new HashMap<>();//买入策略BuyStrategy buyStrategy;public ShareHolderPersion(String name) {this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic void setName(String name) {this.name = name;}@Overridepublic void notifyShare(SharesControlCenter share) {Double buyprice = shares.get(share);System.out.println(name + "Receive notification :" + share.getName() + " now price:" + share.getPrice() + " buy price:" + buyprice);if(buyStrategy != null){buyStrategy.dealBuy(this, share);}}@Overridepublic void buyShare(SharesControlCenter share) {shares.put(share, share.getPrice());share.buyShare(this);}@Overridepublic void sellShare(SharesControlCenter share) {shares.remove(share);share.sellShare(this);}@Overridepublic double getPrice(SharesControlCenter share) {Double buyprice = shares.get(share);return buyprice;}public BuyStrategy getBuyStrategy() {return buyStrategy;}public void setBuyStrategy(BuyStrategy buyStrategy) {this.buyStrategy = buyStrategy;}}

最后增加调用实例:

package com.pattern.observer.practice;public class Client {public static void main(String[] args) {SharesInfo sharesInfo = new SharesInfo("贵州茅台",100);ShareHolderPersion buyer1,buyer2,buyer3;buyer1 = new ShareHolderPersion("老王");buyer1.buyShare(sharesInfo);sharesInfo.setPrice(105);buyer2 = new ShareHolderPersion("老李");buyer2.buyShare(sharesInfo);sharesInfo.setPrice(90);buyer3 = new ShareHolderPersion("老唐");buyer3.buyShare(sharesInfo);sharesInfo.setPrice(100);}
}

最后打印结果:

贵州茅台 shares OK!
老王 buy 贵州茅台 price 100.0
贵州茅台 rise 5.00% now price:105.0
老王Receive notification :贵州茅台 now price:105.0 buy price:100.0
老李 buy 贵州茅台 price 105.0
贵州茅台 fall -14.29% now price:90.0
老王Receive notification :贵州茅台 now price:90.0 buy price:100.0
老李Receive notification :贵州茅台 now price:90.0 buy price:105.0
老唐 buy 贵州茅台 price 90.0
贵州茅台 rise 11.11% now price:100.0
老唐Receive notification :贵州茅台 now price:100.0 buy price:90.0

扩展:由于每个股民买股票的思路不一样,针对股票涨跌做的买入,卖出操作也不同。这里还可以引入策略模式,给每个股民设置一个买入策略。来针对股票的涨跌做买入操作。这里我们加了一个新的策略接口。BuyStrategy.

package com.pattern.observer.practice.abs;/*** 购买策略*/
public interface BuyStrategy {/*** 处理方式* @param share* @param sharesControlCenter*/void dealBuy(ShareHolder share, SharesControlCenter sharesControlCenter);
}

对于策略添加不同的实现方法,一个是上涨买入,一个是下跌买入:

package com.pattern.observer.practice;import com.pattern.observer.practice.abs.BuyStrategy;
import com.pattern.observer.practice.abs.ShareHolder;
import com.pattern.observer.practice.abs.SharesControlCenter;/*** 上涨买入策略*/
public class RiseByStrategy implements BuyStrategy {@Overridepublic void dealBuy(ShareHolder share, SharesControlCenter sharesControlCenter) {double buyprice = share.getPrice(sharesControlCenter);double nowPrice = sharesControlCenter.getPrice();//买入价低于 实际价, 涨了if(buyprice < nowPrice){share.buyShare(sharesControlCenter);}/*else{share.sellShare(sharesControlCenter);}*/}}
package com.pattern.observer.practice;import com.pattern.observer.practice.abs.BuyStrategy;
import com.pattern.observer.practice.abs.ShareHolder;
import com.pattern.observer.practice.abs.SharesControlCenter;/*** 下跌买入策略*/
public class FallByStrategy implements BuyStrategy {@Overridepublic void dealBuy(ShareHolder share, SharesControlCenter sharesControlCenter) {double buyprice = share.getPrice(sharesControlCenter);double nowPrice = sharesControlCenter.getPrice();//买入价高于 实际价, 跌了if(buyprice > nowPrice){share.buyShare(sharesControlCenter);}/*else{share.sellShare(sharesControlCenter);}*/}}

这里可以试着把注释的 else内容打开。程序会报错,原因是在集合遍历的过程中不能对集合进行删除操作。这里只做了价格变动买入。可以思考一下卖出操作怎么实现。

然后再做一个client测试一下:

package com.pattern.observer.practice;import com.pattern.observer.practice.abs.BuyStrategy;public class Client {public static void main(String[] args) {SharesInfo sharesInfo = new SharesInfo("贵州茅台",100);ShareHolderPersion buyer1,buyer2,buyer3;BuyStrategy fallStrategy,riseStrategy;fallStrategy = new FallByStrategy();riseStrategy = new RiseByStrategy();buyer1 = new ShareHolderPersion("老王");buyer1.setBuyStrategy(fallStrategy);buyer1.buyShare(sharesInfo);sharesInfo.setPrice(105);buyer2 = new ShareHolderPersion("老李");buyer2.setBuyStrategy(riseStrategy);buyer2.buyShare(sharesInfo);sharesInfo.setPrice(90);buyer3 = new ShareHolderPersion("老唐");buyer3.setBuyStrategy(riseStrategy);buyer3.buyShare(sharesInfo);sharesInfo.setPrice(100);}
}

运行结果:

贵州茅台 shares OK!
老王 buy 贵州茅台 price 100.0
贵州茅台 rise 5.00% now price:105.0
老王Receive notification :贵州茅台 now price:105.0 buy price:100.0
老李 buy 贵州茅台 price 105.0
贵州茅台 fall -14.29% now price:90.0
老王Receive notification :贵州茅台 now price:90.0 buy price:100.0
老王 buy 贵州茅台 price 90.0
老李Receive notification :贵州茅台 now price:90.0 buy price:105.0
老唐 buy 贵州茅台 price 90.0
贵州茅台 rise 11.11% now price:100.0
老王Receive notification :贵州茅台 now price:100.0 buy price:90.0
老唐Receive notification :贵州茅台 now price:100.0 buy price:90.0
老唐 buy 贵州茅台 price 100.0

设计模式-观察者模式练习相关推荐

  1. Python设计模式-观察者模式

    Python设计模式-观察者模式 代码基于3.5.2,代码如下; #coding:utf-8 # 观察者设计模式class observerInterface():def update(self,va ...

  2. [Head First设计模式]山西面馆中的设计模式——观察者模式

    原文:[Head First设计模式]山西面馆中的设计模式--观察者模式 系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也 ...

  3. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  4. 【学习笔记】ABAP OOD设计模式 - 观察者模式

    ABAP OOD设计模式 - 观察者模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,这个对象相关依赖的 ...

  5. Java设计模式-观察者模式(订阅发布模式)

    Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持吧!! ...

  6. 设计模式---观察者模式介绍与理解

    设计模式---观察者模式介绍与理解: 观察者模式原理:类似于定牛奶业务 1. 奶站,subject:登记注册,移除,通知(register,remove,notify) 2. 用户,observer: ...

  7. 设计模式-观察者模式 发布/订阅模式

    设计模式-观察者模式 发布/订阅模式 代码 观察者接口 public interface IHanFeiZi{// 当吃早饭时public void havBreakFast();// 进行娱乐活动时 ...

  8. 设计模式 | 观察者模式及典型应用

    本文主要内容: 介绍观察者模式 微信公众号的发布/订阅示例 观察者模式总结 分析观察者模式的典型应用 JDK 提供的观察者接口中的观察者模式 Guava EventBus 中的观察者模式 JDK 委托 ...

  9. 李建忠设计模式——观察者模式

    1.观察者模式(Observer/Event) 1.动机 在软件构建过程中,需要为某些对象建立一种"通知依赖关系"--一个对象(目标)的状态发生改变,所有的依赖对象(观察者对象)都 ...

  10. 设计模式●观察者模式

    设计模式●观察者模式 观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做发布-订阅( ...

最新文章

  1. windows下nginx的简单使用
  2. Repeater 嵌套
  3. Windows Phone7天初学(4):数据绑定
  4. 华为交换机堆叠SVF助手(推荐)
  5. CodeForces - 831D Office Keys
  6. 初步了解Telerik for WPF 控件
  7. 实验四 图的实现与应用
  8. ios手机 php无法上传文件,【已解决】uni.uploadFile 苹果ios图片上传不成功
  9. GitHub Actions使用学习最全文档
  10. 记号(notation)的学习
  11. 基础才是重中之重~对象的生与死
  12. java知识总结-19
  13. 2018年全国大学生电子设计竞赛TI杯赛题简单回顾和准备经验分享
  14. viper4android脉冲样本,V4A脉冲反馈样本第一弹 爽爆
  15. 构建Android Push Notification Service服务端及客户端
  16. 38 Power Query-背后的贤内助 M 语言
  17. 【noiOJ】p7939
  18. 抑郁症,莫要讳疾忌医。
  19. HDU 5148 Cities (树形DP)*
  20. RTD2785T RTD2785R 2K eDP屏驱动芯片介绍

热门文章

  1. Yolov5自学笔记之二--在游戏中实时推理并应用(实例:哈利波特手游跳舞小游戏中自动按圈圈)
  2. 庞麦郎utau鬼畜音源下载
  3. oracle execute immediate 游标,EXECUTE IMMEDIATE 常见使用方法
  4. XSS 进阶篇:一文全面了解蓝莲花基本用法
  5. Excel表格技巧(逆了天的39个非常牛逼的技巧)
  6. Android新架构组件WorkManager
  7. 咨询公司应注意成本控制
  8. 【Android 开发】: Android客户端与服务端之间使用JSON交互数据。
  9. SQL Server 设置自增长主键
  10. lintcode-436-Maximal Square