设计模式-观察者模式练习
学习了刘老师写的设计模式,观察者模式史上最全设计模式导学目录(完整版)_刘伟技术博客-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
设计模式-观察者模式练习相关推荐
- Python设计模式-观察者模式
Python设计模式-观察者模式 代码基于3.5.2,代码如下; #coding:utf-8 # 观察者设计模式class observerInterface():def update(self,va ...
- [Head First设计模式]山西面馆中的设计模式——观察者模式
原文:[Head First设计模式]山西面馆中的设计模式--观察者模式 系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也 ...
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
- 【学习笔记】ABAP OOD设计模式 - 观察者模式
ABAP OOD设计模式 - 观察者模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,这个对象相关依赖的 ...
- Java设计模式-观察者模式(订阅发布模式)
Java设计模式-观察者模式(订阅发布模式) 一起来看 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持吧!! ...
- 设计模式---观察者模式介绍与理解
设计模式---观察者模式介绍与理解: 观察者模式原理:类似于定牛奶业务 1. 奶站,subject:登记注册,移除,通知(register,remove,notify) 2. 用户,observer: ...
- 设计模式-观察者模式 发布/订阅模式
设计模式-观察者模式 发布/订阅模式 代码 观察者接口 public interface IHanFeiZi{// 当吃早饭时public void havBreakFast();// 进行娱乐活动时 ...
- 设计模式 | 观察者模式及典型应用
本文主要内容: 介绍观察者模式 微信公众号的发布/订阅示例 观察者模式总结 分析观察者模式的典型应用 JDK 提供的观察者接口中的观察者模式 Guava EventBus 中的观察者模式 JDK 委托 ...
- 李建忠设计模式——观察者模式
1.观察者模式(Observer/Event) 1.动机 在软件构建过程中,需要为某些对象建立一种"通知依赖关系"--一个对象(目标)的状态发生改变,所有的依赖对象(观察者对象)都 ...
- 设计模式●观察者模式
设计模式●观察者模式 观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做发布-订阅( ...
最新文章
- windows下nginx的简单使用
- Repeater 嵌套
- Windows Phone7天初学(4):数据绑定
- 华为交换机堆叠SVF助手(推荐)
- CodeForces - 831D Office Keys
- 初步了解Telerik for WPF 控件
- 实验四 图的实现与应用
- ios手机 php无法上传文件,【已解决】uni.uploadFile 苹果ios图片上传不成功
- GitHub Actions使用学习最全文档
- 记号(notation)的学习
- 基础才是重中之重~对象的生与死
- java知识总结-19
- 2018年全国大学生电子设计竞赛TI杯赛题简单回顾和准备经验分享
- viper4android脉冲样本,V4A脉冲反馈样本第一弹 爽爆
- 构建Android Push Notification Service服务端及客户端
- 38 Power Query-背后的贤内助 M 语言
- 【noiOJ】p7939
- 抑郁症,莫要讳疾忌医。
- HDU 5148 Cities (树形DP)*
- RTD2785T RTD2785R 2K eDP屏驱动芯片介绍