第1章
はじめてのデザインパターン  

第2章
逆引きカタログ ロジック編

第3章
逆引きカタログ J2EE編

第4章
逆引きカタログ その他

第5章
デザインパターン適用の勘所

第5章 デザインパターン適用の勘所

Authors:Agata Toshitaka

ファイル処理をクラス化する

図4 サンプルのクラス図(その3)
M子:
「できました(リスト4)。インタフェースの名前はFilePluginに、メソッド名はexecuteにしました。」

リスト4 FilePlugin.java
/**
 * ファイルを処理するプラグインです。
 */
public interface FilePlugin {
	/**
	 * ファイルを処理します。
	 */
	void execute (String itemCode, String filename, byte[] data);
}
O先輩:
「あとはif文の中の処理を、FilePluginの実装クラスに移動してみよう。」
M子:
「はい。クラス名はImageFilePluginとInfoFilePluginにしますね(リスト5,リスト6)。」

リスト5 ImageFilePlugin.java
/**
 * イメージファイルを処理するプラグインです。
 */
public class ImageFilePlugin implements FilePlugin {
	/** 処理です。*/
	public void execute(String itemCode, String filename, byte[] data) {
		ImageDao dao = new ImageDao();
		dao.update(itemCode, filename, data);
	}
}

リスト6 InfoFilePlugin.java
/**
 * 商品の説明ファイルを処理するプラグインです。
 */
public class InfoFilePlugin implements FilePlugin {
	/** ログです。*/
	private static final Log log =
				LogFactory.getLog(InfoFilePlugin.class);

	/** 処理です。*/
	public void execute(String itemCode, String filename, byte[] data) {
		try {
			InfoDao dao = new InfoDao();
			String info = new String(data, "Windows-31J");
			dao.update(itemCode, info);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
			throw new IORuntimeException(e);
		}
	}
}
O先輩:
「次にif文の中身をImageFilePluginとInfoFilePluginを使って処理するように変更してみようか。」
M子:
「はい。こんな感じですね(リスト7)。」

リスト7 FileUploadServlet3.java
/**
 * ファイルアップロードサーブレットです。
 */
public class FileUploadServlet3 extends HttpServlet {
	/** ファイルサイズの上限です。 */
	private static final int MAX_FILE_SIZE = 1000000;
	protected void doPost(HttpServletRequest req, HttpServletResponse res)
				throws ServletException, IOException {
		// マルチパートデータを取得
		List fileItems = UploadUtil.parseRequest(req, MAX_FILE_SIZE);

		// 商品コードの取得
		String itemCode = UploadUtil.getParameter(fileItems, "code");

		// アップロードされたファイルの処理
		FileItem item = UploadUtil.getFileItem(fileItems, "file");
		String filename = item.getName();
		byte[] data = item.get();

		// ファイルが画像だった場合
		FilePlugin plugin = null;
		if ("item.jpg".equals(filename)) {
			plugin = new ImageFilePlugin();
		// ファイルがinfo.txtだった場合
		} else if ("info.txt".equals(filename)) {
			plugin = new InfoFilePlugin();
		}
		plugin.execute(itemCode, filename, data);・・・@
	}
}
M子:
「ずいぶんすっきりしましたけど、if文はまだ残っていますね。」
O先輩:
「うん、そうだね。これはファクトリを使う前準備なんだ。 ここまででポイントなのは、「処理が共通のFilePluginインタフェースを実装したクラスに置き換わった」ってことなんだ。 リスト7-@の部分を見てごらん。 ここでは変数pluginの中身がImageFilePluginなのか、InfoFilePluginなのかを意識していないんだ。 俗に言うポリモフィズムってやつだね。 あと、ファイル処理のロジックを切り替えるという点では、ストラテジパターンの変形でもあると言えるね。」
M子:
「あーなんとなくわかってきました。」
O先輩:
「では最後のしあげに、if文でFilePluginを生成している部分をファクトリ化してみよう。」
TOP