【设计模式】迭代器模式

文章目录

  • 1.迭代器模式定义
  • 2.迭代器模式的角色
  • 3.迭代器模式实战案例
    • 3.1.场景说明
    • 3.2.关系类图
    • 3.3.代码实现
  • 4.迭代器模式优缺点
  • 5.迭代器模式使用场景
  • 6.迭代器模式总结

主页传送门: 传送

1.迭代器模式定义

       迭代器模式(Iterator Pattern) 目前已经是一个没落的设计模式,基本没人会单独写一个迭代器,除非是产品性质的开发。其定义如下:

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

       即:它提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。
       其通用类图如下:
【设计模式】迭代器模式_第1张图片

2.迭代器模式的角色

在迭代器模式中是涉及到以下几个角色:

  • 抽象迭代子(Iterator)角色:
    此抽象角色定义出遍历元素所需的接口。
  • 具体迭代子(ConcreteIterator)角色:
    此角色实现了Iterator接口,并保持迭代过程中的游标位置。
  • 聚集(Aggregate)角色:
    此抽象角色给出创建迭代子(Iterator)对象的接口。
  • 具体聚集(ConcreteAggregate)角色:
    实现了创建迭代子(Iterator)对象的接口,返回一个合适的具体迭代子实例。
  • 客户端(Client)角色:
    持有对聚集及其迭代子对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除。

3.迭代器模式实战案例

3.1.场景说明

       用迭代器模式编写一个浏览婺源旅游风景图的程序。
分析:婺源的名胜古迹较多,要设计一个查看相关景点图片和简介的程序,用“迭代器模式”设计比较合适。

首先,设计一个婺源景点(WyViewSpot)类来保存每张图片的名称与简介;再设计一个景点集(ViewSpotSet)接口,它是抽象聚合类,提供了增加和删除婺源景点的方法,以及获取迭代器的方法。

然后,定义一个婺源景点集(WyViewSpotSet)类,它是具体聚合类,用 ArrayList 来保存所有景点信息,并实现父类中的抽象方法;再定义婺源景点的抽象迭代器(ViewSpotltemtor)接口,其中包含了查看景点信息的相关方法。

最后,定义婺源景点的具体迭代器(WyViewSpotlterator)类,它实现了父类的抽象方法;客户端程序设计成窗口程序,它初始化婺源景点集(ViewSpotSet)中的数据,并实现 ActionListener 接口,它通过婺源景点迭代器(ViewSpotlterator)来査看婺源景点(WyViewSpot)的信息。

3.2.关系类图

       使用迭代器模式来实现的结构图如下:
【设计模式】迭代器模式_第2张图片

3.3.代码实现

//相框类

public class PictureFrame extends JFrame implements ActionListener {
    private static final long serialVersionUID = 1L;
    ViewSpotSet ag; //婺源景点集接口
    ViewSpotIterator it; //婺源景点迭代器接口
    WyViewSpot ob;    //婺源景点类
    PictureFrame() {
        super("中国最美乡村“婺源”的部分风景图");
        this.setResizable(false);
        ag = new WyViewSpotSet();
        ag.add(new WyViewSpot("江湾", "江湾景区是婺源的一个国家5A级旅游景区,景区内有萧江宗祠、永思街、滕家老屋、婺源人家、乡贤园、百工坊等一大批古建筑,精美绝伦,做工精细。"));
        ag.add(new WyViewSpot("李坑", "李坑村是一个以李姓聚居为主的古村落,是国家4A级旅游景区,其建筑风格独特,是著名的徽派建筑,给人一种安静、祥和的感觉。"));
        ag.add(new WyViewSpot("思溪延村", "思溪延村位于婺源县思口镇境内,始建于南宋庆元五年(1199年),当时建村者俞氏以(鱼)思清溪水而名。"));
        ag.add(new WyViewSpot("晓起村", "晓起有“中国茶文化第一村”与“国家级生态示范村”之美誉,村屋多为清代建筑,风格各具特色,村中小巷均铺青石,曲曲折折,回环如棋局。"));
        ag.add(new WyViewSpot("菊径村", "菊径村形状为山环水绕型,小河成大半圆型,绕村庄将近一周,四周为高山环绕,符合中国的八卦“后山前水”设计,当地人称“脸盆村”。"));
        ag.add(new WyViewSpot("篁岭", "篁岭是著名的“晒秋”文化起源地,也是一座距今近六百历史的徽州古村;篁岭属典型山居村落,民居围绕水口呈扇形梯状错落排布。"));
        ag.add(new WyViewSpot("彩虹桥", "彩虹桥是婺源颇有特色的带顶的桥——廊桥,其不仅造型优美,而且它可在雨天里供行人歇脚,其名取自唐诗“两水夹明镜,双桥落彩虹”。"));
        ag.add(new WyViewSpot("卧龙谷", "卧龙谷是国家4A级旅游区,这里飞泉瀑流泄银吐玉、彩池幽潭碧绿清新、山峰岩石挺拔奇巧,活脱脱一幅天然泼墨山水画。"));
        it = ag.getIterator(); //获取婺源景点迭代器
        ob = it.first();
        this.showPicture(ob.getName(), ob.getIntroduce());
    }
    //显示图片
    void showPicture(String Name, String Introduce) {
        Container cp = this.getContentPane();
        JPanel picturePanel = new JPanel();
        JPanel controlPanel = new JPanel();
        String FileName = "src/iterator/Picture/" + Name + ".jpg";
        JLabel lb = new JLabel(Name, new ImageIcon(FileName), JLabel.CENTER);
        JTextArea ta = new JTextArea(Introduce);
        lb.setHorizontalTextPosition(JLabel.CENTER);
        lb.setVerticalTextPosition(JLabel.TOP);
        lb.setFont(new Font("宋体", Font.BOLD, 20));
        ta.setLineWrap(true);
        ta.setEditable(false);
        //ta.setBackground(Color.orange);
        picturePanel.setLayout(new BorderLayout(5, 5));
        picturePanel.add("Center", lb);
        picturePanel.add("South", ta);
        JButton first, last, next, previous;
        first = new JButton("第一张");
        next = new JButton("下一张");
        previous = new JButton("上一张");
        last = new JButton("最末张");
        first.addActionListener(this);
        next.addActionListener(this);
        previous.addActionListener(this);
        last.addActionListener(this);
        controlPanel.add(first);
        controlPanel.add(next);
        controlPanel.add(previous);
        controlPanel.add(last);
        cp.add("Center", picturePanel);
        cp.add("South", controlPanel);
        this.setSize(630, 550);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        String command = arg0.getActionCommand();
        if (command.equals("第一张")) {
            ob = it.first();
            this.showPicture(ob.getName(), ob.getIntroduce());
        } else if (command.equals("下一张")) {
            ob = it.next();
            this.showPicture(ob.getName(), ob.getIntroduce());
        } else if (command.equals("上一张")) {
            ob = it.previous();
            this.showPicture(ob.getName(), ob.getIntroduce());
        } else if (command.equals("最末张")) {
            ob = it.last();
            this.showPicture(ob.getName(), ob.getIntroduce());
        }
    }
}

//婺源景点类

public class WyViewSpot {
    private String Name;
    private String Introduce;
    WyViewSpot(String Name, String Introduce) {
        this.Name = Name;
        this.Introduce = Introduce;
    }
    public String getName() {
        return Name;
    }
    public String getIntroduce() {
        return Introduce;
    }
}

//抽象聚合:婺源景点集接口

public interface ViewSpotSet {
    void add(WyViewSpot obj);
    void remove(WyViewSpot obj);
    ViewSpotIterator getIterator();
}

//具体聚合:婺源景点集

publi class WyViewSpotSet implements ViewSpotSet {
    private ArrayList<WyViewSpot> list = new ArrayList<WyViewSpot>();
    public void add(WyViewSpot obj) {
        list.add(obj);
    }
    public void remove(WyViewSpot obj) {
        list.remove(obj);
    }
    public ViewSpotIterator getIterator() {
        return (new WyViewSpotIterator(list));
    }
}

//抽象迭代器:婺源景点迭代器接口

public interface ViewSpotIterator {
    boolean hasNext();
    WyViewSpot first();
    WyViewSpot next();
    WyViewSpot previous();
    WyViewSpot last();
}

//具体迭代器:婺源景点迭代器

public class WyViewSpotIterator implements ViewSpotIterator {
    private ArrayList<WyViewSpot> list = null;
    private int index = -1;
    WyViewSpot obj = null;
    public WyViewSpotIterator(ArrayList<WyViewSpot> list) {
        this.list = list;
    }
    public boolean hasNext() {
        if (index < list.size() - 1) {
            return true;
        } else {
            return false;
        }
    }
    public WyViewSpot first() {
        index = 0;
        obj = list.get(index);
        return obj;
    }
    public WyViewSpot next() {
        if (this.hasNext()) {
            obj = list.get(++index);
        }
        return obj;
    }
    public WyViewSpot previous() {
        if (index > 0) {
            obj = list.get(--index);
        }
        return obj;
    }
    public WyViewSpot last() {
        index = list.size() - 1;
        obj = list.get(index);
        return obj;
    }
}

// 场景类

public class PictureIterator {
    public static void main(String[] args) {
        new PictureFrame();
    }
}

4.迭代器模式优缺点

迭代器模式有许多优点,以下是其中的一些:

  • 分离集合与迭代逻辑:迭代器模式将集合对象与遍历逻辑分离,使得它们可以独立变化。集合对象只需要实现迭代器接口,而客户端只需要通过迭代器进行遍历操作,从而实现了解耦和模块化。
  • 统一遍历接口:迭代器模式定义了一组统一的遍历接口,使得客户端可以以相同的方式对待不同类型的集合对象。无论是数组、链表、树状结构还是其他自定义集合,只要它们提供了符合迭代器接口的迭代器对象,就可以使用迭代器模式进行遍历,提高了代码的灵活性和可复用性。
  • 简化客户端代码:使用迭代器模式可以简化客户端代码,减少了对集合内部结构的直接操作,只需要通过迭代器对象进行遍历操作。

迭代器模式的缺点主要表现在以下几个方面:

  • 设计与实现成本高:迭代器模式需要实现一个迭代器接口,并且需要保证迭代器在遍历集合时的正确性,这可能会增加设计和实现的成本。
  • 灵活性不足:迭代器模式对于一些不是集合的数据结构(例如链表、树等)可能不太适用,因为它们的数据访问方式可能不同,需要实现不同的迭代器接口,这可能会影响整个系统的灵活性。
  • 无法直接操作集合内部结构:迭代器模式只提供了遍历集合的方式,无法直接操作集合的内部结构,例如修改、删除等操作,这可能会影响对集合的使用。

5.迭代器模式使用场景

迭代器模式主要适用于以下场景:

  1. 遍历多种数据结构:迭代器模式可以遍历多种数据结构,包括数组、链表、树状结构、自定义数据结构等。通过使用迭代器模式,可以使遍历操作与数据结构解耦,提高代码的可复用性和灵活性。
  2. 实现复杂的数据访问操作:当需要对复杂的数据结构进行访问操作时,使用迭代器模式可以使客户端代码简化,同时可以实现对数据的灵活遍历。
  3. 对聚合对象的多个遍历:由于迭代器模式分离了集合与遍历逻辑,因此可以在同一个聚合上可以有多个遍历操作,这有助于在多个客户端之间共享遍历逻辑。
  4. 对数据的修改和删除:除了遍历数据,迭代器模式还可以支持对数据的修改和删除操作。通过使用迭代器模式,客户端可以通过迭代器对象访问集合内部元素,并对其进行修改和删除。

6.迭代器模式总结

     迭代器模式是一种行为型设计模式,它提供了一种方法,可以顺序访问集合对象中的各个元素,而不暴露该对象的内部表示。迭代器模式通过将集合对象的遍历行为分离出来,交给迭代器角色来完成,从而避免了容器内部细节的暴露,并符合单一职责原则。迭代器模式的核心是迭代器接口和具体迭代器角色,通过它们可以实现遍历操作的灵活性和可复用性。
     总之,迭代器模式是一种非常实用的设计模式,它提供了一种灵活、可复用的方式来遍历集合对象。在实际开发中,可以根据具体的应用场景和需求来选择是否使用迭代器模式,以及如何使用迭代器模式。

如果喜欢的话,欢迎 关注 点赞 评论 收藏 一起讨论
你的支持就是我✍️创作的动力!

你可能感兴趣的:(设计模式,设计模式,迭代器模式,java)