1. Iteratorパターン 3
- 2012/04/26 一部修正しました
デザインパターン 1章 Iteratorパターン
- 1.1 Itaratorパターンとは
- 1.2 サンプルケース
- 1.2 実習課題1
- 1.2 実習課題2
- 1.2 実習課題3
- 1.3 Iterator パターンのまとめ
(実習課題2)
前ページの最後のクラス図にあわせて、 MyStudentList クラスと、MyStudentListIterator クラスを実装しなさい。 ただし、MyStudentList クラスは、以前の古い名簿 StudentList を拡張したものにすること。
public class MyStudentList extends StudentList implements Aggregate{ public MyStudentList(){ super(); } public MyStudentList(int studentCount){ super(studentCount); } public Iterator iterator(){ return new MyStudentListIterator(this); } }
public class MyStudentListIterator implements Iterator{ private MyStudentList myStudentList; private int index; public MyStudentListIterator(MyStudentList list){ this.myStudentList = list; this.index = 0; } public boolean hasNext(){ if(myStudentList.getLastNum() > index){ return true; }else{ return false; } } public Student next(){ Student s = myStudentList.getStudentAt(index); index++; return s; } }
あなた | : | おぉ、これが Iterator パターンですか。こうしておけば、 新しい名簿である「NewStudentList」クラスが渡されたときも簡単に対応できるわけですね。 |
ベテラン | : | 簡単に対応できるかどうかは別として、より柔軟に対応できることだけは間違いないね。
君は callStudents() メソッドをpublic void callStudents(){ int size = studentList.getLastNum(); for(int n=0;n<size;n++){ System.out.println(studentList.getStudentAt(n).getName()); } }のように実装していたね。callStudents() メソッドの中で、 古い形式の名簿にしか存在しないメソッドである getLastNum() など、 集約体に依存したコードを書いているため、名簿が新しくなったときに、 君自身の名簿の使い方まで変更する必要が出てくるわけ。 今回は、1箇所の修正で済んだからまだよかったけど、名簿の順序で生徒になにかするなんてことはよくあるよね。 名簿の順で日直を指定したり、名簿の順番でテストを返したり。これらのすべての実装をすでに終わらせていたとしたら、 君は名簿の順でアクセスする部分をすべて見直す必要があったわけだよ。 |
あなた | : | ほんとうですね。考えるだけでぞっとします。ところでベテラン先生は、 どのように callStudents() メソッドを記述しておられるんですか? |
ベテラン | : | 簡単だよ。 public void callStudents(){ Iterator itr = studentList.iterator(); while(itr.hasNext()){ System.out.println(((Student)itr.next()).getName()); } }当然 MyStudentList クラスで Assemble インタフェースを実装しているよ。 新しい名簿が渡された時には、NewMyStudentList クラスとして Aggregate インタフェースを実装し、 NewMyStudentList クラスと対になるような NewMyStudentListIterator クラスを実装する。 こうすることで、自分が持つ名簿を新しいものにするだけで、日常の仕事を変更する必要がないわけ。 |
あなた | : | スバラシイ・・・。 |