Iterator パターン

Last Change: 12-Sep-2015.
author : qh73xe

例題

あなたが学校の先生であることを考えてみましょう. あなたは、ある学校の新任の先生であるクラスの担任を任せられました. あなたが担任している「生徒」は5人いるものとします.

http://www.techscore.com/tech/DesignPattern/Iterator/Iterator1.html/#dp1-2 より

「生徒」を表すクラス Student クラスは、以下のように定義しましょう. 上記サイトでは java で書かれていますが,python で記述するなら以下の通りかなと.

  • なお python3 を前提に書きます.
class Student:
    __name = None
    __sex = None

    def __init__(self, name, sex):
        self.__name = str(name)
        self.__sex = str(sex)  # 元のサイトでは 1,2 の int であったがわかりやすく文字列を仮定

    def getName(self):
        return self.__name

    def getSex(self):
        return self.__sex

さて,これで生徒を扱うクラスができました. 生徒は名前, 性別を表す変数 name, sex を持ち、 名前を返す getName() メソッドと、性別を返す getSex() メソッドを持ちます.

  • python で private を宣言するには 変数名にアンダーバーを取り付けます.

これらの生徒を管理するために学校から先生に名簿が支給されます. 続いてはこの名簿のクラスを作成します. この名簿はインスタンス化される際には何人の生徒を登録するのかを明記させます. その数に従い None が入ったリストを作成し, 自分の生徒を登録して置くリストを持ち, そこに生徒を登録しておく add メゾットを持ちます.

class StudentList:
    __students = []
    __last = 0

    def __init__(self, studentNum):
        self.__students = [None for col in range(studentNum)]

    def add(self, student):
        self.__students[self.__last] = student
        self.__last =+ 1

    def getStudentAt(self, index):
        return self.__students[index]

    def getLastNum(self):
        return self.__last
  • うん,こんな class いる?とか聞かない.
    • そもそも元ネタは java だから
    • python の場合正直 list 型の変数で十分です.

で最後に先生のクラスを作成していきます. 上記の設定上,先生クラスは名簿をもちます. また,以下の能力(メゾット)を持つ必要があります.

  1. 先生は、学校から与えられた名簿に自分の生徒を書き込むことができること
  2. 先生は、生徒の名前を名簿の記載順に呼ぶことができること

—www.techscore.com/tech/DesignPattern/Iterator/Iterator1.html/#dp1-2 より

ですので先生クラスは以下のようになるはずです.

  • ここでは元ネタの通り,先生クラスは抽象クラスとして作成しています.
    • python で抽象クラスを扱う場合 abc ライブラリを利用します
    • これは組み込みのライブラリなので特にインストールは必要ないです.
from abc import ABCMeta, abstractmethod


class Teacher:
    __metaclass__ = ABCMeta

    @abstractmethod
    def createStudentList():
        pass

    @abstractmethod
    def callStudents():
        pass

イメージとしては,上記のコードで定義した先生クラスは, 先生という概念そのものを定義したクラスです. 以下で,今度はあなた自身に当たる具体的なクラスを作成する必要があります. さて,どのように作成していきましょうか?

  • ここでは 抽象クラス Teacher を継承したあなた自身というクラスを作成します
    • ここで abstractmethod として定義した2つの関数の実装を行っていきます.

実習課題1

「Teacher」抽象クラスを継承する MyTeacher クラスと、「StudentList」クラスを拡張した MyStudentList クラスを設計しクラス図を作成しなさい。 また、これらのクラスを実装し、 下記の Main 関数を実行しなさい。 この2つのクラス以外のクラスやインタフェースを自由に追加しても問題ありません。 MyTeacher クラスの callStudents メソッドでは、あなたのクラスの生徒を順番に標準出力に出力するようにしなさい。

あなたのクラスの生徒は、以下の5人とします。

  • 赤井亮太: 男
  • 赤羽里美: 女
  • 岡田美央: 女
  • 西森俊介: 男
  • 中ノ森玲菜: 女

http://www.techscore.com/tech/DesignPattern/Iterator/Iterator2.html/ より.一部改変

def main():
you = MyTeacher() you.createStudentList() you.callStudents()

んで回答例です. これは,今回お話している Iterator を使用しない場合です.

class MyTeacher(Teacher):
    __StudentList = None

    def createStudentList(self):
        self.__studentList = StudentList(5)
        self.__studentList.add(Student("赤井亮太", "男"))
        self.__studentList.add(Student("赤羽里美", "女"))
        self.__studentList.add(Student("岡田美央", "男"))
        self.__studentList.add(Student("西森俊介", "男"))
        self.__studentList.add(Student("中ノ森玲菜", "女"))

    def callStudents(self):
        size = self.__studentList.getLastNum();
        for n in range(size):
            print(self.__studentList.getStudentAt(n).getName())