golang与java 迭代器模式

1.定义

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
主要包括以下几个角色:

  1. 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  2. 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  3. 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  4. 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置

2.理解

就如同我们使用java的List一样,它提供了对应的Iterator对象,我们可以通过这个迭代器完成对list的访问。从定义上来看,提供了迭代器对象后,最好将聚合对象的实际表示隐藏起来,让使用者只能通过迭代器去访问。

3.示例介绍

下面我将用这样的例子来实现一个迭代器模式的代码。
书。聚合角色中的具体元素
书架。抽象聚合角色。里面有加入书功能和获得迭代器方法。
我的书架。具体聚合角色。
抽象迭代器。next()方法和hasNext()方法
具体迭代器。

4.java实现

public class IteratorPattern {
    public static void main(String[] args) {
        Book book1 = new Book();
        book1.setName("book 1");
        Book book2 = new Book();
        book2.setName("book 2");

        //新建一个具体聚合对象,并聚合一些元素
        BookShlef shlef = new MyBookShlef();
        shlef.add(book1).add(book2);

        //提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
        //现在我们无法直接通过shelf对内部的元素进行访问,只能通过迭代器
        MyIterator<Book> iterator = shlef.getIterator();
        while(iterator.hasNext()){
            Book next = iterator.next();
            System.out.println(next.getName());
        }

    }
}

//抽象聚合
interface BookShlef{
    MyIterator<Book> getIterator();
    BookShlef add(Book b);
}

//抽象迭代器
interface MyIterator<T>{
    T next();
    boolean hasNext();
}

@Data
class Book{
    private String name;
}

class MyBookShlef implements BookShlef{

    //迭代器的关键:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示,这里就是私有的内部数据
    private List<Book> list= new ArrayList<Book>();

    @Override
    public MyIterator<Book> getIterator() {
        BookIterator iterator = new BookIterator(this);
        return iterator;
    }

    @Override
    public BookShlef add(Book b) {
        this.list.add(b);
        return this;
    }

    //具体迭代器:这里采用了内部类的方式,以方便访问具体聚合中的私有数据。
    class BookIterator implements MyIterator<Book>{

        private MyBookShlef bookShlef;
        private int index;

        public BookIterator(MyBookShlef bookShlef){
            this.bookShlef = bookShlef;
        }

        @Override
        public Book next() {
            int size = this.bookShlef.list.size();
            if (size == 0 || index >= size){
                throw new RuntimeException("下标越界");
            }
            return this.bookShlef.list.get(index++);
        }

        @Override
        public boolean hasNext() {
            int size = this.bookShlef.list.size();
            if (size > 0 && index<size){
                return true;
            }
            return false;
        }

    }

}

在这里插入图片描述

5.golang实现

func main() {
	book1:=&Book{Name: "book1"}
	book2:=&Book{Name: "book2"}

	shelf := new(MyBookShlef)
	shelf.Add(book1)
	shelf.Add(book2)

	iterator := shelf.GetIterator()
	for iterator.HasNext(){
		ele := iterator.Next().Ele
		book := ele.(*Book)
		fmt.Println(book.Name)
	}
}

//一个统一的接口,用Element包装了下,这样,该迭代器接口可以给给多的具体迭代器使用。
//因为golang中无泛型,因此相比java麻烦了些
type MyIterator interface {
	Next() *Element
	HasNext() bool
}
type Element struct{
	Ele interface{}
}

type BookShelf interface {
	GetIterator() MyIterator
	Add(book *Book)
}

type MyBookShlef struct {
	list []*Book // 私有
}

func (bookShelf *MyBookShlef) GetIterator() MyIterator {

	bookIterator := new(BookIterator)
	bookIterator.list = bookShelf.list
	bookIterator.index = 0
	return bookIterator
}

func (bookShelf *MyBookShlef) Add(book *Book)  {
	bookShelf.list = append(bookShelf.list, book)
}

type BookIterator struct {
	//bookShelf BookShelf // 持有一个聚合类的引用,以访问它里面的数据,因为被私有化了,所以不能通过这种方式了
	list []*Book // 持有聚合类里面数据的引用也是可以的
	index int
}

func (iterator *BookIterator) HasNext() bool {
	size := len(iterator.list)
	if  size > 0 && iterator.index < size{
		return true
	}
	return false
}

func (iterator *BookIterator) Next() *Element{
	if !iterator.HasNext(){
		panic (errors.New("下标越界"))
	}
	book := iterator.list[iterator.index]
	iterator.index++
	return &Element{Ele: book}
}

type Book struct {
	Name string
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值