`

系统融合(二) -- 迭代器模式

阅读更多

聚合类型兼容性问题

 

接上一次分享《系统融合 -- 适配器模式》,在对A、B两个系统进行融合的过程中,可以使用“适配器模式”把两类业务类似但接口定义不同的接口适配为同一个系统。在两个系统融合过程中,还经常遇到另一种情况:A系统返回的商品列表是ArrayList类型,B系统返回的商品列表是数组类型。

//A系统获取商品列表接口
public List<Product> getProdoucts(){
//省略业务代码
}
//B系统获取商品列表接口
public Product [] getProdoucts(){
//省略业务代码
}
 

 

这就是所谓的“聚合类型兼容性问题”。这时为了统一接口类型,可以在“适配器系统”把ArrayList转换成数组,或者把数组转换成ArrayList。但这不是最优雅的方式,我们还可以使用“迭代器模式”对两个接口进行兼容。Java中得聚合类型:数组、List、Set、Map等。

 

在使用“迭代器模式”解决这个兼容性问题之前,首先来看看什么是“迭代器模式”。

 

迭代器模式

 

迭代器模式提供一种顺序访问一个聚合对象中的各个元素的方法,而又不暴露其内部的表象。把遍历聚合中各个元素的任务移交到“迭代器”上,满足OO设计原则中的“单一责任原则”。另外具体的“迭代器”都实现自一个统一的接口(Iterator),可以兼容不同的聚合类型遍历(这就是解决本文开头“兼容性”问题的关键)。

 

简单的理解,就是把聚合类型中遍历每个成员的任务剥离出来,生成“迭代器”,这些迭代器都实现自同一个接口。类图关系:



 

 

从类图上看,该模式主要有4类角色:

抽象的聚合:AbsAggregate,可以是抽象类 也可以是接口。一般都会定义一个抽象方法,获取迭代器。

 

具体的聚合:ConcreteAggregate,实现或继承自AbsAggregate。一般都会实现AbsAggregate中的抽象方法,获取具体的迭代器。

抽象的迭代器:Iterator可以是抽象类 也可以是接口。一般最少有两个抽象方法,hasNext()和next()方法,用于遍历聚合中的元素。

具体的迭代器:ConcreteIterator,实现或继承自Iterator。对hasNext()和next()方法进行具体的实现。其构造过程依赖“具体的聚合”,也就是说每个“具体的聚合”,一般都会对应一个自己 “具体的迭代器”。

 

示例展示

 

回到文章开头,开始使用“迭代器模式”对A、B两个系统融合过程中,对两个不同的获取商品列表接口进行融合。为了方便理解,实现过程按照“迭代器模式”的4类角色 分类进行:

 

抽象的聚合:本示例中抽象的聚合是ProdcutAdapter接口,里面只定义了一个createIterator()的抽象方法:

public interface ProdcutAdapter {
 
    //批量获取商品接口
    Iterator<Product> createIterator();
}
 

 

具体的聚合:本示例中有两个系统进行融合,对应有两个具体的聚合:ProdcutAdapterAImpl(对应List类型的商品列表接口)、ProdcutAdapterBImpl(对应数组类型的商品接口)。核心是对createIterator方法的实现:

public class ProdcutAdapterAImpl implements ProdcutAdapter {
 
    public Iterator<Product> createIterator() {
        List<Product> products =getProdoucts();
        Iterator iterator = new ListIterator(products);
        return iterator;
    }
 
    //模拟从A系统获取List类型的商品列表
    public List<Product> getProdoucts(){
        //省略调用A系统方法,获取数组类型的商品列表
        Product p1 = new Product();
        p1.setId(1000);
        p1.setName("A系统1000商品");
        Product p2 = new Product();
        p2.setId(1001);
        p2.setName("A系统1001商品");
        List<Product> products = new ArrayList();
        products.add(p1);
        products.add(p2);
        return products;
    }
}
 
public class ProdcutAdapterBImpl implements ProdcutAdapter {
 
    public Iterator<Product> createIterator() {
        Product [] array = getProdoucts();
        Iterator iterator = new ArrayIterator(array);
        return iterator;
    }
 
    //模拟从B系统获取数组类型的商品列表
    public Product [] getProdoucts(){
        //省略调用B系统方法,获取数组类型的商品列表
        Product p3 = new Product();
        p3.setId(1003);
        p3.setName("B系统1003商品");
        Product p4 = new Product();
        p4.setId(1004);
        p4.setName("B系统1004商品");
        Product [] array = {p3,p4};
        return array;
    }
}
 

 

抽象的迭代器:Iterator,这里只定义迭代器的两个核心方法 hasNext和next:

 

public interface Iterator<E> {
    boolean hasNext();
    Object next();
}
 

 

具体的迭代器:本示例中有两类聚合,List和数组。对应的会创建两个具体的迭代器:ListIterator、ArrayIterator

 

public class ListIterator<E> implements Iterator{
    private List<E> products;
    int pos=0;//当前位置
 
    //外部迭代器,构造函数需要传入一个待迭代的集合类型
    public ListIterator(List<E> products) {
        this.products = products;
    }
 
    public boolean hasNext() {
        if (pos >= products.size()) {
            return false;
        } else {
            return true;
        }
    }
 
    public Object next() {
        E product = products.get(pos);
        pos = pos + 1;
        return product;
    }
}
 
public class ArrayIterator<E> implements Iterator{
    private E [] products;
    int pos=0;//当前位置
 
    //外部迭代器,构造函数需要传入一个待迭代的集合类型
    public ArrayIterator(E[] products) {
        this.products = products;
    }
 
    public boolean hasNext() {
        if (pos >= products.length) {
            return false;
        } else {
            return true;
        }
    }
 
    public Object next() {
        E product = products[pos];
        pos = pos + 1;
        return product;
    }
}

 

 

到这里“迭代器模式”的4类角色的实现完成,下面开始测试:

public class Main {
    public static void main(String[] args) {
        ProdcutAdapter prodcutAdapterA = new ProdcutAdapterAImpl();
        ProdcutAdapter prodcutAdapterB = new ProdcutAdapterBImpl();
 
        //获取迭代器,两个老系统接口被统一为一个迭代器类型
        Iterator iteratorA = prodcutAdapterA.createIterator();
        Iterator iteratorB = prodcutAdapterB.createIterator();
 
        //展示商品列表
        showProducts(iteratorA);
        showProducts(iteratorB);
    }
 
    //模拟商品列表展示
    public static void showProducts(Iterator iterator){
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("             ");
    }
}
 

 

执行main方法,打印结果为:

Product{id=1000, name='A系统1000商品', category='null', venderId=null}
Product{id=1001, name='A系统1001商品', category='null', venderId=null}
            
Product{id=1003, name='B系统1003商品', category='null', venderId=null}
Product{id=1004, name='B系统1004商品', category='null', venderId=null}

 

这里main方法是展示的如何让“客户端”无感知的调用A、B两个系统的获取商品列表方法,并采用统一的方法进行打印。换句话说“客户端”无需关心商品列表是List类型 还是 数组类型。

 

到这里,使用“迭代器模式”已经优雅的解决是两个系统“融合”过程中,聚合类型不兼容的问题。

 

Java中的迭代器

 

Java的API中对大部分的聚合类型都已经默认实现了自己的迭代器,统一实现自接口java.util.Iterator,相比本示例中定义的Iterator,java.util.Iterator多了一个remove方法:

public interface Iterator<E> {
    boolean hasNext();
 
    E next();
 
default void remove()
}
 

 

在上述示例中,我们自己实现了ArrayList类型的迭代器ArrayIterator,这里仅仅为了做示例演示使用。其实java API中ArrayList,已经有自己的迭代器实现,直接调用其iterator()方法即可。

 

如果本示例改用java.util.Iterator作为抽象的迭代器,ArrayIterator几乎不用改,去掉ArrayIterator实现,在ProdcutAdapterAImpl中把:

Iterator iterator = new ListIterator(products);

改为:

Iterator iterator = products.iterator();

 

Java api中几乎已为所有的聚合类型创建了自己的迭代器,并且都实现自java.util.Iterator接口。如果要扩展自定义聚合类型的迭代器,直接实现这个接口即可,这样做的好处是可以跟java api中的聚合类型的迭代器完全兼容。

 

内、外部迭代器

 

最后再提下内部迭代器和外部迭代器,本次示例中使用独立的类创建具体的迭代器,这属于外部迭代器。Java API中的实现都是内部迭代器:迭代器实现类做为聚合的一个内部类。这两种方式有各自的优缺点:

 

外部迭代器:优点 “单一责任原则”更彻底,具备更好的复用性。缺点 暴露聚合的内部成员。创建迭代器时,需要具体的聚合类型作为参数:

Iterator iterator = new ListIterator(products);

 

内部迭代器:优缺点刚好与外部迭代器相反。创建迭代器时,不需要参数:

Iterator iterator = products.iterator();

 

Java API为了防止暴露内部数据结构,一般都采用内部迭代器。

 

 

 

  • 大小: 9.3 KB
0
1
分享到:
评论

相关推荐

    二十三种设计模式【PDF版】

    设计模式之 Iterator(迭代器) 这个模式已经被整合入Java的Collection.在大多数场合下无需自己制造一个Iterator,只要将对象装入Collection中, 直接使用 Iterator 进行对象遍历。 设计模式之 Template(模板方法) ...

    基于QPLMTS算法的边缘计算场景下的任务调度器源码+项目说明.zip

    - 采用数据集发生器/边缘计算系统API初始化DAG任务数据、边缘节点数据 - 运行QPLMTS算法核心模块,产生调度结果 - 执行实验分析模块,分析调度结果 主要函数与功能 # 数据预处理区 1. **数据集发生器:** ...

    asp.net知识库

    C#2.0-迭代器 C#2.0 的新增功能学习 泛型的序列化问题 .NET 2.0 泛型在实际开发中的一次小应用 C#2.0 Singleton 的实现 .Net Framwork 强类型设计实践 通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: ...

    造纸企业智能制造解决方案.pptx

    时间轴 18世纪末 20世纪初 蒸汽机 1970年代初 今天 电力广泛应用 自动化、信息化 信息物联系统 工业1.0 创造机器工厂的"蒸汽时代" 工业2.0 将人类带入分工明确、大批量生产的流水线模式和"电气时代" 工业3.0 应用...

    智能控制现状以及运用.docx

    整个控制结构由线性反馈控制器和前馈学习补偿控制器组成,其中线性反馈控制器保证了非线性系统的稳定运行、前馈补偿控制器保证了系统的跟踪控制精度。它在执行重复运动的非线性机器人系统的控制中是相当成功的。 二、...

    大数据--第一章大数据概述笔记分享.pdf

    数据产⽣⽅式的变⾰促成⼤数据时代的来临 运营式系统阶段——数据产⽣⽅式是被动的 ⽤户原创内容阶段——数据产⽣⽅式是主动的 感知式系统阶段——⼤数据的产⽣(物联⽹、云计算和⼤数据) 物联⽹底层是感知层,如:...

    全球智能制造发展现状.doc

    阿里通过线下工厂数据化、 工厂产能商品化的模式,从提供电子商务交易平台演进为提供用户深度参与、供给链高 度协同、迭代式创新的制造智能化、柔性化、定制化解决方案。 三、我国机器人及智能制造产业分析 〔一〕...

    基于matlab的表情识别代码-scv:个人简历

    目的:从特征描述、样本迁移和检测器迭代优化等方面进行改进,提出一个场景自适应的行人检测框架 工作:提出融合上下文局部关联特征的行人目标描述方法;提出基于分块加权距离的样本迁移策略;提出权重差异化调整的...

Global site tag (gtag.js) - Google Analytics