Android、Java、Web系、Linux、マラソン等の備忘録

2011/09/04

Design Pattern:Iterator

0 件のコメント

どんなパターン?

ある集合の内部実装を知らなくても、その要素へ順番にアクセスする方法を提供

どんな場合に適用できる?



  • 数える対象の内部実装と切り離して数え上げを行いたい場合
  • 異なる集合に対して、単一の数え上げインタフェースを実装したい場合
  • 数える対象の総数が予め分かっていない場合に効果的(テキストファイルの内容を、先頭から1行ずつ取得する場合など)

 

構造

図1-1 Iteratorの構造 
図1-1 Iteratorの構造


Iteratorのインタフェースのメソッドには、上記以外にも、

  • First() :カレント要素を1つめの要素として初期化
  • CurrentItem():現在の要素を返す


などの機能を実装しても良いかもしれない。


構成要素



Iterator 順番に走査していくインタフェース(API)を定義する
ConcreteIterator Iteratorで定義したインタフェースを実装する。
Aggregateオブジェクトの走査の最に、カレント要素を保持
Aggregate Iteratorオブジェクトを生成するためのインタフェースを定義
ConcreateAggregate Aggregateが定義しているインタフェースを実装する。



 

サンプル


数える所だけ着目して、お寿司屋さんの大将をメインにふざけたサンプルを作ってみました。ツッコミどころは探せばいくらでもあると思いますが、まあこんな使い方ということで。

WS000189 

原形をとどめなくなってもいけないので、上図1-1に数え上げの対象となるSushiクラスを追加し、Concreteの部分だけお寿司屋さんっぽくして、それを使うMainTaishouクラスを加えました。

MainTaishouクラスでは、

  1. お客さんの注文を聞く
  2. お会計(お寿司の数え上げ)


を行います。

サンプルの全体像




※画像サイズが2605×3641と無駄にでかいので注意




ソースコード一覧


Iterator.java
package SampleIterator;

public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}



Aggregate.java
package SampleIterator;

public interface Aggregate {
public abstract Iterator iterator();
}



Order.java
package SampleIterator;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
* 注文クラス
* @author takaiwa.net
*
*/
public class Order implements Aggregate{

// お寿司料理金表(ネタ、値段)
private Map<String,Integer> nedanhyo = new HashMap<String, Integer>() {{
put("いわし", 130); put("こはだ", 130);
put("タマゴ", 170); put("さんま", 170);
put("かんぱち", 220);put("さば", 220);
put("大トロ", 280);
}};

private LinkedList<Sushi> denpyou = null;

public Order() {
// 空の注文伝票を作成
this.denpyou = new LinkedList<Sushi>();
}

/**
* お客さんから注文を受け付ける
* @param sushi
*/
public void append(Sushi sushi) {
// 注文されたお寿司を伝票へ
this.denpyou.push(sushi);
}

/**
* 値段表から食べた寿司の情報を返す
* @return
*/
public Sushi getItem() {
Sushi sushi = this.denpyou.pop();
String name = sushi.getName();
// 値段の書き込み
sushi.setPrice(this.nedanhyo.get(name));
return sushi;
}

/**
* お皿の枚数を返す
* @return
*/
public int getItemSize() {
return this.denpyou.size();
}

public Iterator iterator() {
return new OrderIterator(this);
}
}



OrderIterator.java
package SampleIterator;

/**
* 注文Iteratorクラス
* @author takaiwa.net
*
*/
public class OrderIterator implements Iterator{

private Order order = null;
private int item = 0;

public OrderIterator(Order order) {
this.order = order;
}

public boolean hasNext() {
if(this.item < order.getItemSize()) {
return true;
}
else {
return false;
}
}

public Object next() {
Sushi sushi = this.order.getItem();
this.item++;
return sushi;
}
}



Sushi.java
package SampleIterator;
/**
* 寿司クラス
* @author takaiwa.net
*
*/
public class Sushi {
private String name = null;
private Integer price = null;

/**
* コンストラクタ
* @param name
*/
public Sushi(String name) {
// 寿司の名前を設定
this.name = name;
}
/**
* 寿司の名前を返す
* @return
*/
public String getName() {
return this.name;
}
/**
* 値段の設定
* @param price
*/
public void setPrice(Integer price) {
this.price = price;
}
/**
* 値段を返す
* @return
*/
public Integer getPrice() {
return this.price;
}
}



MainTaisho.java
package SampleIterator;

/**
* 大将クラス
* @author takaiwa.net
*
*/
public class MainTaisho {

/**
* @param args
*/
public static void main(String[] args) {

System.out.println("いらっしゃせー、何にしましょう?");

Order order = new Order();

// お客さんの注文を聞く
order.append(new Sushi("タマゴ"));
order.append(new Sushi("いわし"));
order.append(new Sushi("さんま"));
order.append(new Sushi("かんぱち"));
order.append(new Sushi("大トロ"));
System.out.println("へい、おまち!");

// お会計
System.out.println("お会計は...");

Integer total = 0;
Iterator okaikei = order.iterator();
while(okaikei.hasNext()) {
Sushi sushi = (Sushi)okaikei.next();
System.out.println(sushi.getName() + " " + sushi.getPrice() + "円");
total += sushi.getPrice();
}

System.out.println("合計で" + total + "です。");
}

}


実際の実装例




Java自体に実装されています。
上記ソースにも登場した、LinkedListもそのオブジェクトをMainTaishouに返せるなら、直にIteratorで数え上げ可能です。あとは、SetインタフェースがIteratorを実装しているので、HashMap等でentrySetメソッドを実行するなどして、Iteratorで数え上げもできます。


参考文献




ふざけたサンプルより、まともなサンプルが見たい方は、


が参考になるかと思います。

関連しているパターン




  • Vistor パターン

  • Composite パターン

  • Factory Method パターン



0 件のコメント :

コメントを投稿