LoginSignup
0
0

More than 3 years have passed since last update.

デザインパターン入門_メモ_Iterator

Posted at

Javade学ぶデザインパターン入門

結城浩「Javaで学ぶデザインパターン入門」をC#で勉強

Iterator パターン

今回はIteratorパターン

実装


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatternLearn.IteratorLearn
{
    /// <summary>
    /// Mainはテキスト通り
    /// </summary>
    class Test
    {
        public static void Main(string[] args)
        {
            BookShelf bookShelf = new BookShelf(4);
            bookShelf.AppendBook(new Book("Javaで学ぶデザインパターン入門1"));
            bookShelf.AppendBook(new Book("Javaで学ぶデザインパターン入門2"));
            bookShelf.AppendBook(new Book("Javaで学ぶデザインパターン入門3"));
            bookShelf.AppendBook(new Book("Javaで学ぶデザインパターン入門4"));
            ITerator it = bookShelf.iTerator();
            while (it.HasNext())
            {
                Book book = (Book)it.Next();
                Console.WriteLine(book.Name);
            }
            Console.Read();
        }
    }

    public interface Aggrregate
    {
        ITerator iTerator();
    }

    /// <summary>
    /// 要素の数え上げ、ループ変数のような役割
    /// </summary>
    public interface ITerator
    {
        bool HasNext();
        object Next();
    }

    public class BookShelfIterator : ITerator
    {
        private BookShelf bookShelf;
        private int index;

        public BookShelfIterator(BookShelf bookShelf)
        {
            this.bookShelf = bookShelf;
        }

        public bool HasNext()
        {
            return bookShelf.GetLength() >= (index + 1) ? true : false;  
        }

        public object Next()
        {
            if (HasNext())
            {
                this.index = index + 1;
                return bookShelf.GetBookAt(index - 1);
            } else
            {
                return null;
            }
        }
    }

    /// <summary>
    /// Aggregateを実装すること
    /// → 内部でIteratorメソッドを実装する必要がある。
    /// </summary>
    public class BookShelf : Aggrregate
    {
        private Book[] books;
        private int last;

        public BookShelf()
        {
            this.books = new Book[] { };
            this.last = 0;
        }

        /// <summary>
        /// Mainを見た後に追加した
        /// </summary>
        /// <param name="last"></param>
        public BookShelf(int itemNum)
        {
            this.books = new Book[itemNum];
            this.last = 0;
        }

        public Book GetBookAt(int index)
        {
            return books[index];
        }

        public void AppendBook(Book book)
        {
            books[last] = book;
            last = last + 1;
        }

        public int GetLength()
        {
            return last;
        }

        /// <summary>
        /// ここが重要
        /// Iteratorメソッドを実装する際に、
        /// Iteratorインターフェイスを実装しているクラスのコンストラクタを
        /// 呼び出してる
        /// → Iteratorの対象を切り替えるのが簡単
        /// </summary>
        /// <returns></returns>
        public ITerator iTerator()
        {
            return new BookShelfIterator(this);
        }
    }

    public class Book
    {
        public string Name { get; set; }

        public Book(string name)
        {
            this.Name = name;
        }
    }
}



重要な考え方(抜粋)

Iteratorを使うことで、実装とは切り離して、数え上げを行うことができる。
→ BookShelfをそのまま用いず、BookShelf中のIterator(BookSshelfIterator)を使用
  BookShelfの中身は、Iteratorが知っていればよい。
そのため、BookShelfの実装を変更しても、Main関数などそれを呼び出す側の実装を変更せずにすむ。

練習問題1-1

上記のBookShelfクラスでは上限を超えて本を収納することができない。
上限を超えても本を格納できるように変更せよ。

実装

  /// <summary>
    /// Aggregateを実装すること
    /// → 内部でIteratorメソッドを実装する必要がある。
    /// </summary>
    public class BookShelf : Aggrregate
    {
        private List<Book> books;
        private int last;

        public BookShelf()
        {
            this.books = new List<Book>();
            this.last = 0;
        }

        /// <summary>
        /// Mainを見た後に追加した
        /// </summary>
        /// <param name="last"></param>
        public BookShelf(int itemNum)
        {
            this.books = new List<Book>(itemNum);
            this.last = 0;
        }

        public Book GetBookAt(int index)
        {
            return books[index];
        }

        public void AppendBook(Book book)
        {
            books.Add(book);
            last = last + 1;
        }

        public int GetLength()
        {
            return last;
        }

        /// <summary>
        /// ここが重要
        /// Iteratorメソッドを実装する際に、
        /// Iteratorインターフェイスを実装しているクラスのコンストラクタを
        /// 呼び出してる
        /// → Iteratorの対象を切り替えるのが簡単
        /// </summary>
        /// <returns></returns>
        public ITerator iTerator()
        {
            return new BookShelfIterator(this);
        }
    }

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0