Java设计模式之行为型-迭代器模式 (Iterator)

👉文章示例代码👈

附链

你也可以在这些平台阅读本文:

定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

四个角色

迭代器模式主要有以下四个角色:

  • 抽象聚合角色Aggregate:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  • 具体聚合角色Concrete Aggregate:实现抽象聚合类,返回一个具体的迭代器实例。
  • 抽象迭代器Iterator:定义访问和遍历聚合元素的接口。
  • 具体迭代器Concrete Iterator:实现抽象迭代器接口中锁定义的方法,完成对聚合对象的遍历,并且记录遍历的当前位置。

场景示例

笔者这里以超市的商品为例,需要做一个商品清单的展示。

创建商品实体类

/**
 * @author zhh
 * @description 商品实体类
 * @date 2020-02-28 14:20
 */
public class Goods {

    /**
     * 名称
     */
    private String name;

    /**
     * 价格
     */
    private double price;

    public Goods(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

创建抽象聚合角色

/**
 * @author zhh
 * @description 商品抽象聚合接口
 * @date 2020-02-28 14:26
 */
public interface GoodsAggregate {

    /**
     * 添加商品
     */
    void addGoods(Goods goods);

    /**
     * 删除商品
     */
    void removeGoods(Goods goods);

    /**
     * 获取商品迭代器
     */
    GoodsIterator getGoodsIterator();
}

创建具体聚合角色

/**
 * @author zhh
 * @description 商品具体聚合类
 * @date 2020-02-28 14:30
 */
public class GoodsAggregateImpl implements GoodsAggregate {

    private List<Goods> goodsList = new ArrayList<Goods>();

    public void addGoods(Goods goods) {
        goodsList.add(goods);
    }

    public void removeGoods(Goods goods) {
        goodsList.remove(goods);
    }

    public GoodsIterator getGoodsIterator() {
        return new GoodsIteratorImpl(goodsList);
    }
}

创建抽象迭代器角色

/**
 * @author zhh
 * @description 商品抽象迭代器接口
 * @date 2020-02-28 14:28
 */
public interface GoodsIterator {

    /**
     * 获取下一个商品
     */
    Goods nextGoods();

    /**
     * 判断是否还有商品
     */
    boolean hasGoods();
}

创建具体迭代器角色

/**
 * @author zhh
 * @description 商品抽象迭代器类
 * @date 2020-02-28 14:32
 */
public class GoodsIteratorImpl implements GoodsIterator {

    private List<Goods> goodsList;

    /**
     * 商品位置
     */
    private int index;

    public GoodsIteratorImpl(List<Goods> goodsList) {
        this.goodsList = goodsList;
    }

    public Goods nextGoods() {
        System.out.println("当前商品的位置是" + index);
        Goods goods = goodsList.get(index);
        index++;
        return goods;
    }

    public boolean hasGoods() {
        if (index < goodsList.size()) {
            return true;
        }
        return false;
    }
}

测试类及输出

/**
 * @author zhh
 * @description 测试类
 * @date 2020-02-28 14:40
 */
public class Test {

    public static void main(String[] args) {
        // 创建商品
        Goods goods1 = new Goods("可乐", 3.0);
        Goods goods2 = new Goods("薯片", 5.0);
        Goods goods3 = new Goods("奶茶", 3.0);
        Goods goods4 = new Goods("香肠", 10.0);
        Goods goods5 = new Goods("奶粉", 33.0);
        Goods goods6 = new Goods("牛肉干", 23.0);

        GoodsAggregate goodsAggregate = new GoodsAggregateImpl();
        goodsAggregate.addGoods(goods1);
        goodsAggregate.addGoods(goods2);
        goodsAggregate.addGoods(goods3);
        goodsAggregate.addGoods(goods4);
        goodsAggregate.addGoods(goods5);
        goodsAggregate.addGoods(goods6);

        System.out.println("---商品清单---");
        GoodsIterator goodsIterator = goodsAggregate.getGoodsIterator();
        Goods goods;
        while (goodsIterator.hasGoods()) {
            goods = goodsIterator.nextGoods();
            System.out.println(String.format("商品名称: %s, 商品价格: %s", goods.getName(), goods.getPrice()));
        }
    }
}

测试类的输出结果如下:

—商品清单—
当前商品的位置是0
商品名称: 可乐, 商品价格: 3.0
当前商品的位置是1
商品名称: 薯片, 商品价格: 5.0
当前商品的位置是2
商品名称: 奶茶, 商品价格: 3.0
当前商品的位置是3
商品名称: 香肠, 商品价格: 10.0
当前商品的位置是4
商品名称: 奶粉, 商品价格: 33.0
当前商品的位置是5
商品名称: 牛肉干, 商品价格: 23.0

类结构图

以上示例类的结构图如下所示

总结

适用场景

  • 当访问一个聚合对象中的内容但又不想暴露其内部表示。
  • 需要为聚合对象提供多种的遍历方式。
  • 当需要为遍历不同的聚合结构提供一个统一的接口。

优点

  • 具有良好的封装性,为遍历不同的聚合结构提供了一个统一的接口。
  • 分离了聚合类的遍历行为,简化聚合类。
  • 具有良好的扩展性,新增聚合类和迭代器类无需修改原有代码。

缺点

增加了类的个数,这在一定程度上增加了系统的复杂性。

参考

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值