zoukankan      html  css  js  c++  java
  • java设计模式-----19、迭代模式

      概念:

      Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

      迭代模式使用比较少,JDK集合也提供了Iterator的具体实现,可以直接拿来用,不必自己实现

      在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题。

       1.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法

       2.让调用者自己实现遍历。直接暴露数据细节给外部

       我们用代码实现一下

      首先,新建一个Book类,这是容器中的内容

     1 public class Book {
     2     private String id;
     3     private String name;
     4     private double price;
     5     
     6     public Book(String id, String name, double price) {
     7         this.id = id;
     8         this.name = name;
     9         this.price = price;
    10     }
    11 
    12     public String getId() {
    13         return id;
    14     }
    15 
    16     public void setId(String id) {
    17         this.id = id;
    18     }
    19 
    20     public String getName() {
    21         return name;
    22     }
    23 
    24     public void setName(String name) {
    25         this.name = name;
    26     }
    27 
    28     public double getPrice() {
    29         return price;
    30     }
    31 
    32     public void setPrice(double price) {
    33         this.price = price;
    34     }
    35     
    36     public void display() {
    37         System.out.println("ID=" + id + ",	name=" + name + ",	price" + price);
    38     }
    39 }

       再新建一个容器

     1 public class BookList {
     2     //容器内部还是一个List,也可以用数组
     3     private List<Book> bookList = new ArrayList<Book>();
     4     private int index;
     5     
     6     //添加书籍
     7     public void addBook(Book book){
     8         bookList.add(book);
     9     }
    10     
    11     //删除书籍
    12     public void removeBook(Book book){
    13         int bookIndex = bookList.indexOf(book);
    14         bookList.remove(bookIndex);
    15     }
    16     
    17     //判断是否有下一本书
    18     public boolean hasNext(){
    19         if(index >= bookList.size()){
    20             return false;
    21         }
    22         return true;
    23     }
    24     
    25     //获得下一本书
    26     public Book getNext(){
    27         return bookList.get(index++);
    28     }
    29     
    30     //获取集合长度
    31     public int getSize(){
    32         return bookList.size();
    33     }
    34     
    35     //根据index获取Book
    36     public Book getByIndex(int index){
    37         return bookList.get(index);
    38     }
    39 }

      接下来,就是迭代容器了,先采用第一种方式(由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法)

    public class MainClass {
        public static void main(String[] args) {
            BookList bookList = new BookList();
            
            Book book1 = new Book("001","设计模式",200);
            Book book2 = new Book("002","Java核心编程",200);
            Book book3 = new Book("003","计算机组成原理",200);
            
            bookList.addBook(book1);
            bookList.addBook(book2);
            bookList.addBook(book3);
            
            while(bookList.hasNext()){
                Book book = bookList.getNext();
                book.display();
            }
        }
    }

       结果如下:

      然后是第二种方式(让调用者自己实现遍历。直接暴露数据细节给外部)

     1 public class MainClass {
     2     public static void main(String[] args) {
     3         BookList bookList = new BookList();
     4         
     5         Book book1 = new Book("001","设计模式",200);
     6         Book book2 = new Book("002","Java核心编程",200);
     7         Book book3 = new Book("003","计算机组成原理",200);
     8         
     9         bookList.addBook(book1);
    10         bookList.addBook(book2);
    11         bookList.addBook(book3);
    12         
    13         for(int i = 0; i < bookList.getSize(); i++){
    14             Book book = bookList.getByIndex(i);
    15             book.display();
    16         }
    17     }
    18 }

       结果同上

      但这样,一定是有缺点的,不然就没有必要使用迭代模式了

      不使用迭代模式的缺点

      以上方法1与方法2都可以实现对遍历,但有这些问题

      1,容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。

      2,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。

      应用迭代模式的条件

      Iterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。

      所以,Iterator模式的应用场景可以归纳为满足以下几个条件:

      1、访问容器中包含的内部对象
      2、按顺序访问

      迭代模式的结构

      

      迭代模式的角色和职责

      1、Iterator(迭代器接口)

      该接口必须定义实现迭代功能的最小定义方法集

      比如提供hasNext()和next()方法。

      2、ConcreteIterator(迭代器实现类)

      迭代器接口Iterator的实现类。可以根据具体情况加以实现。

      3、Aggregate(容器接口)

      定义基本功能以及提供类似Iterator iterator()的方法。

      4、concreteAggregate(容器实现类)

      容器接口的实现类。必须实现Iterator iterator()方法。

       接下来,用代码实现一下迭代模式,只需修改BookList即可

     1 public class BookList {
     2     //容器内部还是一个List,也可以用数组
     3     private List<Book> bookList = new ArrayList<Book>();
     4     private int index;
     5     
     6     //添加书籍
     7     public void addBook(Book book){
     8         bookList.add(book);
     9     }
    10     
    11     //删除书籍
    12     public void removeBook(Book book){
    13         int bookIndex = bookList.indexOf(book);
    14         bookList.remove(bookIndex);
    15     }
    16     
    17     //判断是否有下一本书
    18 //    public boolean hasNext(){
    19 //        if(index >= bookList.size()){
    20 //            return false;
    21 //        }
    22 //        return true;
    23 //    }
    24     
    25     //获得下一本书
    26 //    public Book getNext(){
    27 //        return bookList.get(index++);
    28 //    }
    29     
    30     //获取集合长度
    31     public int getSize(){
    32         return bookList.size();
    33     }
    34     
    35     //根据index获取Book
    36     public Book getByIndex(int index){
    37         return bookList.get(index);
    38     }
    39     
    40     //得到Iterator实例
    41     public Iterator Iterator() {
    42         return new Itr();
    43     }
    44     
    45     //内部类,Iterator实例(因为要使用容器的内部信息,所以要写成内部类)
    46     private class Itr implements Iterator{
    47         //判断是否有下一本书,将刚才hasNext()中内容复制过来即可
    48         public boolean hasNext() {
    49             if(index >= bookList.size()){
    50                 return false;
    51             }
    52             return true;
    53         }
    54         //获得下一本书,将刚才getNext()中内容复制过来即可
    55         public Object next() {
    56             return bookList.get(index++);
    57         }
    58 
    59         public void remove() {
    60             
    61         }
    62     }
    63 }

      再在客户端实现一下

     1 public class MainClass {
     2     public static void main(String[] args) {
     3         BookList bookList = new BookList();
     4         
     5         Book book1 = new Book("001","设计模式",200);
     6         Book book2 = new Book("002","Java核心编程",200);
     7         Book book3 = new Book("003","计算机组成原理",200);
     8         
     9         bookList.addBook(book1);
    10         bookList.addBook(book2);
    11         bookList.addBook(book3);
    12         
    13         Iterator iterator = bookList.Iterator();
    14         while(iterator.hasNext()){
    15             Book book = (Book) iterator.next();
    16             book.display();
    17         }
    18     }
    19 }

      可以看到,这和使用JDK提供集合的Iterator方法就一模一样了。

      迭代模式的优缺点

      优点:

      1,实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。

      2,隐藏容器的实现细节。

      3,为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。

      4,可以为容器或其子容器实现不同的迭代方法或多个迭代方法。

      缺点:

      由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

  • 相关阅读:
    汉诺塔难题
    函数的两种调用方式

    汉诺塔难题
    汉诺塔难题

    python中对小数取整
    linux中部署apache服务(http服务或者web服务)
    python中如何判断变量类型
    python中求余数
  • 原文地址:https://www.cnblogs.com/xiaobai1226/p/8617511.html
Copyright © 2011-2022 走看看