研磨设计模式day12迭代器模式

目录

场景

解决方案

解决思路

代码示例

代码改造

Java实现迭代器

迭代器模式的优点 

思考 

何时选用


场景

大公司收购了一个小公司,大公司的工资系统采用List来记录工资列表,而小公司是采用数组,老板希望通过决策辅助系统来统一查看工资数据不想看到两份不同的工资表。

解析:如何能够以一个统一的方式 来访问 内部实现不同的 聚合对象

解决方案

迭代器模式

定义:

所谓聚合就是指一组对象的组合结构:比如 Java中的集合、数组等

解决思路

要有一个统一的方式来访问,那就要定义这个统一的访问方式,那么按照统一的访问方式定义出来的接口就应该是Iterator接口。(定义访问和遍历元素的接口)

迭代器迭代的是具体的聚合对象,不同的聚合对象应该有不同的迭代器,所以应该抽象出来一个公共的父类,让它提供 操作聚合对象的 公共接口。也是就Aggregate对象(聚合对象)

如何创建?由于迭代器与聚合对象紧密相关,因此让具体的聚合对象来负责创建相应的迭代器对象

代码示例

工资实体

package day13迭代器模式.entity;/*** 工资实体*/
public class PayModel {/*** 支付工资的人员*/private String userName;/*** 支付的工资数额*/private double pay;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public double getPay() {return pay;}public void setPay(double pay) {this.pay = pay;}@Overridepublic String toString() {return "PayModel{" +"userName='" + userName + '\'' +", pay=" + pay +'}';}
}

大公司原有的工资管理对象 使用List

package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 大公司原有的工资管理对象*/
public class PayDa {/*** 聚合对象*/private List list = new ArrayList();/*** 获取工资列表* @return  工资列表*/public List getPayList(){return list;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}
}

小公司原有的工资管理对象 使用数组

package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 小公司原有的工资管理对象*/
public class PayXiao {/*** 用数组管理*/private PayModel[] pms = null;/*** 获取工资列表* @return  工资列表*/public PayModel[] getPays(){return pms;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}
}

Client

package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.Collection;
import java.util.Iterator;
import java.util.List;public class Client {public static void main(String[] args) {// 访问集团的工资列表PayDa payDa = new PayDa();// 先计算再获取payDa.calcPay();List payList = payDa.getPayList();Iterator it = payList.iterator();System.out.println("大公司工资列表: ");while (it.hasNext()){PayModel next = (PayModel)it.next();System.out.println(next);}// 访问小公司的工资列表PayXiao payXiao = new PayXiao();payXiao.calcPay();PayModel[] pays = payXiao.getPays();System.out.println("小公司工资列表: ");for (int i = 0; i < pays.length; i++) {System.out.println(pays[i]);}}
}

发现他们的访问方式是完全不一样的(一个是list,一个是对象数组)。

要使用迭代器来整合上面两个聚合对象,那就需要先定义出抽象的聚合对象和迭代器接口来,再提供相应的实现

代码改造

Iterator

package day13迭代器模式;public interface Iterator {/*** 移动到聚合对象的第一个位置*/public void first();/*** 移动到聚合对象的下一个位置*/public void next();/*** 判断是否移动到聚合对象的最后一个位置* @return true表示已经移动到聚合对象的最后一个位置*         false表示没有移动到聚合对象的最后一个位置*/public boolean isDone();/*** 获取迭代的当前元素* @return  迭代的当前元素*/public Object currentItem();
}

 定义好统一接口后,就得分别实现,一个是List实现,一个是数组实现

数组实现

package day13迭代器模式.Iterator;import day13迭代器模式.PayXiao;/*** 用来实现访问数组的迭代接口*/
public class ArrayIteratorImpl implements Iterator{/*** 用来存放被迭代的聚合对象*/private PayXiao payXiao = null;/*** 用来记录当前迭代到的位置索引* -1表示刚开始的时候,迭代器指向聚合对象第一个对象之前*/private int index = -1;/*** 构造函数,传入聚合对象*/public ArrayIteratorImpl(PayXiao payXiao){this.payXiao = payXiao;}@Overridepublic void first() {index = 0;}@Overridepublic void next() {if (index < this.payXiao.size()){index = index + 1;}}@Overridepublic boolean isDone() {if (index == this.payXiao.size()){return true;}return false;}@Overridepublic Object currentItem() {return this.payXiao.get(index);}
}

集合实现

package day13迭代器模式.Iterator;import day13迭代器模式.PayDa;public class CollectionIteratorImpl implements Iterator{/*** 用来存放被迭代的聚合对象*/private PayDa payDa = null;/*** 用来记录当前迭代到的位置索引* -1表示刚开始的时候,迭代器指向聚合对象第一个对象之前*/private int index = -1;/*** 构造函数,传入聚合对象*/public CollectionIteratorImpl(PayDa payDa){this.payDa = payDa;}@Overridepublic void first() {index = 0;}@Overridepublic void next() {if (index < this.payDa.size()){index = index + 1;}}@Overridepublic boolean isDone() {if (index == this.payDa.size()){return true;}return false;}@Overridepublic Object currentItem() {return this.payDa.get(index);}
}

迭代器迭代的是具体的聚合对象,不同的聚合对象应该有不同的迭代器,所以应该抽象出来一个公共的父类,让它提供 操作聚合对象的 公共接口。

也是就Aggregate对象(聚合对象)

package day13迭代器模式;import day13迭代器模式.Iterator.Iterator;/*** 迭代器迭代的是具体的聚合对象,不同的聚合对象应该有不同的迭代器,* 所以应该抽象出来一个公共的父类,让它提供 操作聚合对象的 公共接口。* 也是就Aggregate对象(聚合对象)*/
public abstract class Aggregate {/*** 工厂方法,创建对应迭代器对象的接口*/public abstract Iterator createIterator();
}

让PayDa和PayXiao,这两个原有的工资管理对象继承这个Aggregate

PayDa

package day13迭代器模式;import day13迭代器模式.Iterator.CollectionIteratorImpl;
import day13迭代器模式.Iterator.Iterator;
import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 大公司原有的工资管理对象*/
public class PayDa extends Aggregate{/*** 聚合对象*/private List list = new ArrayList();/*** 获取工资列表* @return  工资列表*/public List getPayList(){return list;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}@Overridepublic Iterator createIterator() {return new CollectionIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < this.list.size()){obj = this.list.get(index);}return obj;}public int size(){return this.list.size();}
}

PayXiao

package day13迭代器模式;import day13迭代器模式.Iterator.ArrayIteratorImpl;
import day13迭代器模式.Iterator.Iterator;
import day13迭代器模式.entity.PayModel;import java.util.ArrayList;
import java.util.List;/*** 小公司原有的工资管理对象*/
public class PayXiao extends Aggregate{/*** 用数组管理*/private PayModel[] pms = null;/*** 获取工资列表* @return  工资列表*/public PayModel[] getPays(){return pms;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}@Overridepublic Iterator createIterator() {return new ArrayIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < pms.length){obj = pms[index];}return obj;}public int size(){return this.pms.length;}
}

Client

package day13迭代器模式;import day13迭代器模式.entity.PayModel;import java.util.Collection;
import java.util.Iterator;
import java.util.List;public class Client {public static void main(String[] args) {// 访问集团的工资列表PayDa payDa = new PayDa();// 先计算再获取payDa.calcPay();
//        List payList = payDa.getPayList();
//        Iterator it = payList.iterator();System.out.println("大公司工资列表: ");
//        while (it.hasNext()){
//            PayModel next = (PayModel)it.next();
//            System.out.println(next);
//        }test(payDa.createIterator());// 访问小公司的工资列表PayXiao payXiao = new PayXiao();payXiao.calcPay();
//        PayModel[] pays = payXiao.getPays();System.out.println("小公司工资列表: ");test(payXiao.createIterator());}private static void test(day13迭代器模式.Iterator.Iterator it){// 循环输出聚合对象中的值// 首先设置迭代器到第一个元素it.first();while (!it.isDone()){// 取出当前的元素来Object o = it.currentItem();System.out.println("当前元素: " + o);it.next();}}
}

迭代器模式的关键思想就是把聚合对象的遍历和访问从聚合对象中分离出来,放入单独的迭代器中。

Java实现迭代器

PayModel类(工资实体)

package day13迭代器Java实现.entity;/*** 工资实体*/
public class PayModel {/*** 支付工资的人员*/private String userName;/*** 支付的工资数额*/private double pay;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public double getPay() {return pay;}public void setPay(double pay) {this.pay = pay;}@Overridepublic String toString() {return "PayModel{" +"userName='" + userName + '\'' +", pay=" + pay +'}';}
}

创建Aggregate,这里使用java.util.Iterator

package day13迭代器Java实现;import java.util.Iterator;/*** 迭代器迭代的是具体的聚合对象,不同的聚合对象应该有不同的迭代器,* 所以应该抽象出来一个公共的父类,让它提供 操作聚合对象的 公共接口。* 也是就Aggregate对象(聚合对象)*/
public abstract class Aggregate {/*** 工厂方法,创建对应迭代器对象的接口*/public abstract Iterator createIterator();
}

PayDa继承该抽象类

package day13迭代器Java实现;import day13迭代器Java实现.entity.PayModel;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** 大公司原有的工资管理对象*/
public class PayDa extends Aggregate {/*** 聚合对象*/private List<PayModel> list = new ArrayList<PayModel>();/*** 获取工资列表* @return  工资列表*/public List<PayModel> getPayList(){return list;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");list.add(payModel);list.add(payModel1);}@Overridepublic Iterator createIterator() {return list.iterator();}}

PayXiao继承该抽象类

package day13迭代器Java实现;import day13迭代器Java实现.Iterator.ArrayIteratorImpl;
import day13迭代器Java实现.entity.PayModel;import java.util.Iterator;/*** 小公司原有的工资管理对象*/
public class PayXiao extends Aggregate {/*** 用数组管理*/private PayModel[] pms = null;/*** 获取工资列表* @return  工资列表*/public PayModel[] getPays(){return pms;}/*** 计算工资*/public void calcPay(){// 计算工资并把工资数据填充到工资列表中// 为了测试,输入些数据进去PayModel payModel = new PayModel();payModel.setPay(3800);payModel.setUserName("张三");PayModel payModel1 = new PayModel();payModel1.setPay(5800);payModel1.setUserName("李四");pms = new PayModel[2];pms[0] = payModel;pms[1] = payModel1;}@Overridepublic Iterator createIterator() {return new ArrayIteratorImpl(this);}public Object get(int index){Object obj = null;if (index < pms.length){obj = pms[index];}return obj;}public int size(){return this.pms.length;}
}

将小公司的融入大公司,就让小公司来实现这个迭代器,让它进行统一

ArrayIteratorImpl

package day13迭代器Java实现.Iterator;import day13迭代器Java实现.PayXiao;import java.util.Iterator;/*** 用来实现访问数组的迭代接口*/
public class ArrayIteratorImpl implements Iterator {/*** 用来存放被迭代的聚合对象*/private PayXiao payXiao = null;/*** 用来记录当前迭代到的位置索引* -1表示刚开始的时候,迭代器指向聚合对象第一个对象之前*/private int index = 0;/*** 构造函数,传入聚合对象*/public ArrayIteratorImpl(PayXiao payXiao){this.payXiao = payXiao;}@Overridepublic void remove() {Iterator.super.remove();}/*** 判断是否还有下一个元素* @return*/@Overridepublic boolean hasNext() {if (payXiao != null && index < payXiao.size()){return true;}return false;}@Overridepublic Object next() {Object o = null;if (hasNext()){o = payXiao.get(index);// 每取走一个值,就把已访问索引加1index++;}return o;}
}

Client

package day13迭代器Java实现;import day13迭代器Java实现.entity.PayModel;import java.util.Iterator;public class Client {public static void main(String[] args) {// 访问集团的工资列表PayDa payDa = new PayDa();// 先计算再获取payDa.calcPay();
//        List payList = payDa.getPayList();
//        Iterator it = payList.iterator();System.out.println("大公司工资列表: ");
//        while (it.hasNext()){
//            PayModel next = (PayModel)it.next();
//            System.out.println(next);
//        }test(payDa.createIterator());// 访问小公司的工资列表PayXiao payXiao = new PayXiao();payXiao.calcPay();
//        PayModel[] pays = payXiao.getPays();System.out.println("小公司工资列表: ");test(payXiao.createIterator());}private static void test(Iterator it){// 判断是否还有下一个元素while (it.hasNext()){PayModel next = (PayModel)it.next();System.out.println(next);}}
}

 解析:为什么要保留数据的IteratorImpl呢?因为list有iterator方法可以直接调用,数组没有要进行转变,怎么转变呢?就是实现Iterator接口后重写方法next和hasNext这两个方法。以此来跟list相同就可以使用统一的迭代器了。

在Client中,大公司调用自身list的迭代器,小公司调用重写后的迭代器

它new了一个Impl,这个Impl实现的就是java.util.iterator的迭代器且重写了方法 

迭代器模式的优点 

思考 

本质:

控制访问聚合对象中的元素

何时选用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/106112.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencv案例03 -基于OpenCV实现二维码生成,发现,定位,识别

1.二维码的生成 废话不多说&#xff0c;直接上代码 # 生成二维码 import qrcode# 二维码包含的示例数据 data "B0018" # 生成的二维码图片名称 filename "qrcode.png" # 生成二维码 img qrcode.make(data) # 保存成图片输出 img.save(filename)img.sh…

C#矩阵XY排序

矩阵XY快速排序 using MyVision.Script.Method;public class MyScript : ScriptMethods {//struct MOTIONPOSXY_S{public double Pos_x;public double Pos_y;};//脚本执行该方法public bool Process(){//try{//脚本代码写在下方 List<double> PointX GetDoubleList(&qu…

搭建开发环境-Mac

概述 上一篇搭建开发环境-WSLUbuntu 记录了WSL 和Ubuntu 下开发环境的搭建。这一篇就说下Mac开发环境的搭建。 就像很多人误以为Mini 是专为女孩子设计的高颜值车&#xff0c;其实是一辆极其hardcore 的拉力车一样。 很多人都被Mac 那高颜值蒙蔽了&#xff0c;其实这是一台生产…

构造函数内的方法 直接写在构造函数内部 与 写在prototype上 的区别

文章目录 前言区别总结 前言 以前没注意过, 去创建一个构造函数的时候, 方法都是直接写在函数内的. 在构造函数需要多次实例化的情况下有缺点, 不过幸好以前项目里的构造函数也不需要多次实例化, 缺点没有生效. 区别 为了比较, 先在构造函数内部直接书写方法, 查看实例化结果…

Kubernetes 使用 Rancher 管理

K8S集群管理工具 只能管理单个K8S集群 kubectl命令行管理工具 dashboard&#xff08;K8S官方的UI界面图形化管理工具&#xff09; &#xff08;管理多集群很麻烦&#xff0c;切换不同集群每次需要更改kube-config文件[kubectl配置文件]&#xff0c;如果kubeadm部署每次都需…

item_search_img-按图搜索淘宝商品(拍立淘)

一、接口参数说明&#xff1a; item_search_img-按图搜索淘宝商品&#xff08;拍立淘&#xff09;&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_search_img 名称类型必须描…

iconfont 图标在vue里的使用

刚好项目需要使用一个iconfont的图标&#xff0c;所以记录一下这个过程 1、iconfont-阿里巴巴矢量图标库 这个注册一个账号&#xff0c;以便后续使用下载代码时需要 2、寻找自己需要的图标 我主要是找两个图标 &#xff0c;一个加号&#xff0c;一个减号&#xff0c;分别加入到…

华为云渲染实践

// 编者按&#xff1a;云计算与网络基础设施发展为云端渲染提供了更好的发展机会&#xff0c;华为云随之长期在自研图形渲染引擎、工业领域渲染和AI加速渲染三大方向进行云渲染方面的探索与研究。本次LiveVideoStackCon 2023上海站邀请了来自华为云的陈普&#xff0c;为大家分…

[系统] 电脑突然变卡 / 电脑突然** / 各种突发情况解决思路

今天来公司办公&#xff0c;开机之后发现电脑出现各种问题&#xff0c;死机、卡顿、点什么都加载&#xff0c;甚至开一个文件夹要1分钟才能打开&#xff0c;花了2个小时才解决&#xff0c;走了很多弯路&#xff0c;其实早点想通&#xff0c;5分钟就能解决问题&#xff0c;所以打…

玩转科技|了解AI平台桌面客户端—ChatBox

目录 前言 特性 ​编辑 为什么需要 ChatBox&#xff1f; ChatGPT Plus 平替&#xff1f; 下载 支持系统 功能图 使用教程 ​感受 展示 前言 今天小编又来了&#xff0c;推荐给大家一款开源的OpenAI API桌面客户端ChatBox&#xff0c;它支持 Windows、Mac 和 Linux。…

Vue2向Vue3过度Vuex核心概念state状态

目录 1 核心概念 - state 状态1.目标2.提供数据3.访问Vuex中的数据4.通过$store访问的语法5.代码实现5.1模板中使用5.2组件逻辑中使用5.3 js文件中使用 2 通过辅助函数 - mapState获取 state中的数据1.第一步&#xff1a;导入mapState (mapState是vuex中的一个函数)2.第二步&am…

【Apollo学习笔记】——规划模块TASK之PATH_REUSE_DECIDER

文章目录 前言PATH_REUSE_DECIDER功能简介PATH_REUSE_DECIDER相关配置PATH_REUSE_DECIDER总体流程PATH_REUSE_DECIDER相关子函数IsCollisionFreeTrimHistoryPathIsIgnoredBlockingObstacle和GetBlockingObstacleS Else参考 前言 在Apollo星火计划学习笔记——Apollo路径规划算…

容器技术,1. Docker,2. Kubernetes(K8s):

目录 容器技术 1. Docker&#xff1a; 2. Kubernetes&#xff08;K8s&#xff09;&#xff1a; Docker和Kubernetes 容器的主要应用场景有哪些&#xff1f; 容器技术 有效的将单个操作系统的资源划分到孤立的组中&#xff0c;以便更好的在孤立的组之间平衡有冲突的资源使…

分布式 - 服务器Nginx:一小时入门系列之 HTTPS协议配置

文章目录 1. HTTPS 协议2. 生成 SSL 证书和私钥文件3. 配置 SSL 证书和私钥文件4. HTTPS 协议优化 1. HTTPS 协议 HTTPS 是一种通过计算机网络进行安全通信的协议。它是HTTP的安全版本&#xff0c;通过使用 SSL 或 TLS 协议来加密和保护数据传输。HTTPS的主要目的是确保在客户…

PHP小白搭建Kafka环境以及初步使用rdkafka

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装java&#xff08;Kafka必须安装java&#xff0c;因为kafka依赖java核心&#xff09;二、安装以及配置Kafka、zookeeper1.下载Kafka&#xff08;无需下载…

强化学习在游戏AI中的应用与挑战

文章目录 1. 强化学习简介2. 强化学习在游戏AI中的应用2.1 游戏智能体训练2.2 游戏AI决策2.3 游戏测试和优化 3. 强化学习在游戏AI中的挑战3.1 探索与利用的平衡3.2 多样性的应对 4. 解决方法与展望4.1 深度强化学习4.2 奖励设计和函数逼近 5. 总结 &#x1f389;欢迎来到AIGC人…

计算机网络——OSI与TCP/IP各层的结构与功能,都有哪些协议?

文章目录 一 OSI与TCP/IP各层的结构与功能,都有哪些协议?1.1 应用层1.2 运输层1.3 网络层1.4 数据链路层1.5 物理层1.6 总结一下 二 ⭐TCP 三次握手和四次挥手(面试常客)2.1 TCP 三次握手漫画图解2.2 为什么要三次握手⭐2.3 第2次握手传回了ACK&#xff0c;为什么还要传回SYN&…

基于Java+SpringBoot+Vue前后端分离社区智慧养老监护管理平台设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【Jetpack】Navigation 导航组件 ④ ( Fragment 跳转中使用 safe args 安全传递参数 )

文章目录 一、页面跳转间的传统的数据传递方式1、传统的数据传递方式 - Bundle 传递数据1、Navigation 组件中的 Bundle 数据传递2、传统数据传递实现步骤3、FragmentA 完整代码示例4、FragmentB 完整代码示例5、执行结果 2、使用 Bundle 传递数据安全性差 二、页面跳转间的传统…

lesson9: C++多线程

1.线程库 1.1 thread类的简单介绍 C11 中引入了对 线程的支持 了&#xff0c;使得 C 在 并行编程时 不需要依赖第三方库 而且在原子操作中还引入了 原子类 的概念。要使用标准库中的线程&#xff0c;必须包含 < thread > 头文件 函数名 功能 thread() 构造一个线程对象…