Tech Blog

Information Technology / Machine Learning / Data Analysis / Big Data / System Integration

デザインパターンのエッセンス

デザインパターン一覧

デザインパターンの記事を書き終えたので、まとめておきます。各々のデザインパターンの詳細は、下記のページをご覧ください。

  1. 生成に関するパターン
  2. 構造に関するパターン
  3. 振る舞いに関するパターン

デザインパターンが重要なワケ

どのような言語でも、プログラミングの学習はたいていの場合、世界にこんにちはとつぶやくところから始まる。例えばJavaの場合は、以下のようになる。

System.out.println("Hello World!");

その後、次のように変数が定義できることを知る。

int a = 1;

次に、関数を定義できることを知る。

int myFunc(int a) {
  return a++;
}

オブジェクト指向に基づくプログラミング言語の場合は、クラスという概念も学ぶことになるだろう。

public myClass {
  public int a = 1;
  public int myFunc(int b) {
    return a + b;
  }
} 

このようにしてプログラムをひととおり学ぶと、どんなアルゴリズムは自分で作れるようになる。これでプログラミングの学習は終わり。めでたしめでたし。…と思いきや、そうは問屋が卸さない。

"好きなようにプログラミングできる"ことは、"どのように実装するかを選択する"ことをプログラマに強いる。そして、プログラマは例えば次のような悩みを持つだろう。

  • 継承と委譲をどう使うか
  • どのようにメソッドを切るか
  • ロジックをどうやって共通化するか
  • 機能と実装をどうやって分離するか
  • 拡張性を保持するにはどうすべきか
  • 再利用性を保証するにはどうすべきか
  • 可読性を高めるにはどうすべきか

これらの悩みに対して、プログラマは長年にわたって知見を蓄積してきた。それらのTipsをプログラム設計のカタログとしてまとめたものが、デザインパターンである。デザインパターンは、プログラマが培ってきたプログラミングのパターンを集約したものと考えてよい。

したがって、綺麗なコードを書くための第一歩は、デザインパターンの理解から始まる。また、あまり気付かれないが、既存のコードを読むためにもデザインパターンの習得が重要である。

デザインパターンを分かりやすく

デザインパターンの解説書や解説しているホームページは数多くあるが、読むのがうんざりするほど長い。デザインパターンの解説なのに、デザインパターン以外の部分がこれでもかと盛り込まれている。また、ページをまたいで解説されているため、理解がしにくい。

そこで、本ブログではデザインパターンのエッセンスだけを以下にまとめた。JavaプログラムをUMLに併記することで、一目で流れを確認できるようにしている。UMLが読める人でJavaの文法をひととおり勉強した人であれば、お役に立つのではと思う。

  1. 生成に関するパターン
  2. 構造に関するパターン
  3. 振る舞いに関するパターン

デザインパターンのエッセンス~振る舞いパターン~

デザインパターンの解説は数多あるけれど、そもそも例が複雑で分かりにくい!というわけで、UML1枚のみでシンプルに説明するシリーズ第3弾(最終回)。
生成に関するパターン構造に関するパターンに引き続き、今回は振る舞いに関する11個のパターン。

13. Chain of Responsibilityパターン

  • 責任をたらい回しを行うパターン。
  • イベントの送受信を行う複数のオブジェクトを鎖状につなぎ、それらの間をイベントが渡されてゆくようにする。

f:id:tkdmah:20130609114651p:plain

14. Commandパターン

  • 命令をメソッドではなく命令を表すクラスのインスタンスという1個の「もの」として表現するパターン。
  • 複数の異なる操作について、それぞれに対応するオブジェクトを用意し、オブジェクトを切り替えることで操作の切替えを実現する。

f:id:tkdmah:20130609114703p:plain

15. Interpreterパターン

  • プログラムが解決しようとしている問題を簡単なミニ言語で表現し、通訳プログラムが解釈・実行するパターン。
  • 構文解析のために、文法規則を反映するクラス構造を作る。

f:id:tkdmah:20130609114734p:plain

16. Iteratorパターン

  • 集合を順番に指し示して全体をスキャンするパターン。
  • 複数の要素を内包するオブジェクトのすべての要素に順にアクセスする方法を提供する。反復子。

f:id:tkdmah:20130609114753p:plain

17. Mediatorパターン

  • オブジェクト同士がすべて相談役を介してやりとりするパターン。
  • オブジェクト間の相互作用を仲介するオブジェクトを定義し、オブジェクト間の結合度を低くする。

f:id:tkdmah:20130609114811p:plain

18. Mementoパターン

  • インスタンスの状態を表す役割を導入し、カプセル化の破壊に陥ることなく保存と復元を行うパターン。
  • データ構造に対する一連の操作のそれぞれを記録しておき、以前の状態の復帰または操作の再現が行えるようにする。

f:id:tkdmah:20130609114825p:plain

19. Observerパターン

  • 観察対象の状態変化に対して、観察者に通知されるパターン。Listenerとも呼ばれる。
  • インスタンスの変化を他のインスタンスから監視できるようにする。

f:id:tkdmah:20130609114843p:plain

20. Stateパターン

  • 状態をクラスで表現するパターン。
  • オブジェクトの状態を変化させることで、処理内容を変えられるようにする。

f:id:tkdmah:20130609114857p:plain

21. Strategyパターン

  • 問題を解くアルゴリズムを容易に交換するパターン。
  • データ構造に対して適用する一連のアルゴリズムをカプセル化し、アルゴリズムの切替えを容易にする。

f:id:tkdmah:20130609114911p:plain

22. Template Methodパターン

  • スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるパターン。
  • あるアルゴリズムの途中経過で必要な処理を抽象メソッドに委ね、その実装を変えることで処理が変えられるようにする。

f:id:tkdmah:20130609114923p:plain

23. Visitorパターン

  • データ構造の中をめぐり歩く訪問者のクラスを用意し、そのクラスが処理を行うパターン。
  • データ構造を保持するクラスと、それに対して処理を行うクラスを分離する。

f:id:tkdmah:20130609114935p:plain

デザインパターンのエッセンス~構造パターン~

デザインパターンの解説は数多あるけれど、そもそも例が複雑で分かりにくい!というわけで、UML1枚のみでシンプルに説明するシリーズ第2弾。
今回は、構造に関する7つのパターン。生成に関するパターンはこちら

6. Adapter

  • すでに提供されているものと必要なもののずれを埋めるデザインパターン。Wrapperパターンとも呼ばれる。
  • 元々関連性のない2つのクラスを接続するクラスを作る。
  • 継承を用いる方法

f:id:tkdmah:20130528015120p:plain

  • 委譲を用いる方法

f:id:tkdmah:20130528015131p:plain

7. Bridge

  • 機能のクラス階層と実装のクラス階層を橋渡しをするデザインパターン
  • クラスなどの実装と、呼出し側の間の橋渡しをするクラスを用意し、実装を隠蔽する。

f:id:tkdmah:20130528015143p:plain

8. Composite

  • 容器と中身を同一視し、再帰的な構造を作るパターン。
  • 再帰的な構造を表現する。

f:id:tkdmah:20130528015159p:plain

9. Decorator

  • オブジェクトにデコレーションをほどこしていくパターン。Filterとも呼ばれる。
  • あるインスタンスに対し、動的に付加機能を追加する。

f:id:tkdmah:20130528015209p:plain

10. Facade

  • 複雑なクラス構成をまとめてシンプルなAPIを提供するパターン。
  • 複数のサブシステムの窓口となる共通のインタフェースを提供する。

f:id:tkdmah:20130528015222p:plain

11. Flyweight

f:id:tkdmah:20130528015234p:plain

12. Proxy

  • 代理人を立てるパターン。
  • 共通のインタフェースをもつインスタンスを内包し、利用者からのアクセスを代理する。

f:id:tkdmah:20130528015247p:plain

デザインパターンのエッセンス~生成パターン~

デザインパターンの解説は数多あるけれど、そもそも例が複雑で分かりにくい!そこで、デザインパターンのエッセンスのみを抽出し、Javaソースコードを併記することで、UML1枚ずつでシンプルに説明する。
デザインパターンには、生成に関するパターン・構造に関するパターン・振る舞いに関するパターンがあるが、今回は生成に関する5つのパターンを取り上げる。

1. Abstract Factoryパターン

  • 抽象的な工場で、抽象的な製品を作るパターン。
  • 関連する一連のインスタンスを状況に応じて適切に生成する方法を提供する。

f:id:tkdmah:20130519132853p:plain

2. Builderパターン

f:id:tkdmah:20130519132859p:plain

3. Factory Methodパターン

f:id:tkdmah:20130519132907p:plain

4. Prototypeパターン

f:id:tkdmah:20130519132912p:plain

5. Singletonパターン

f:id:tkdmah:20130519132919p:plain

※斜体はabstract, 下線はstatic, +はpublic, -はprivate, #はprotectedを表す。

EclipseでMahout環境を構築する

目的

Mahoutは、Hadoop上で動くスケーラブルなオープンソース機械学習ライブラリである。今回は、Mahoutをソースコードレビューするために、Eclipseに取り込む。実行環境ではないので悪しからず。OSはWindowsを使用している。

方法

1.以下のサイトにアクセスする。

2.必要そうなものをダウンロードする。mahout/やhadoop/からダウンロードできる。例えば以下のjarファイルをC:\Program Files (x86)\pleiades\3_7_Indigo\libに保存する。

mahout-core-0.7-cdh4.1.2.jar
mahout-core-0.7-cdh4.1.2-sources.jar
mahout-math-0.7-cdh4.1.2.jar
mahout-math-0.7-cdh4.1.2-sources.jar
mahout-examples-0.7-cdh4.1.2.jar
mahout-examples-0.7-cdh4.1.2-sources.jar
hadoop-core-2.0.0-mr1-cdh4.1.2.jar
hadoop-core-2.0.0-mr1-cdh4.1.2-sources.jar
hadoop-example-2.0.0-mr1-cdh4.1.2.jar
hadoop-example-2.0.0-mr1-cdh4.1.2-sources.jar

3.Eclipseを起動させる。

4.ファイル > 新規 > Javaプロジェクト > プロジェクト名を記入して次へ > ライブラリータブをクリック > 外部JARの追加 > ダウンロードしたjarファイルをすべて選択して開く。

5.各jarの左をクリック > ソース添付をダブルクリック > 外部ファイル > ソースファイルを開く。設定後の画面は以下のとおり。
f:id:tkdmah:20130515234133p:plain

6.これにて環境構築完了。例えば、mahout-exampleにはkddcup 2011を解くプログラムらしきものが含まれていますね・・・。
f:id:tkdmah:20130515235142p:plain

How to Run Kdd2013AuthorPaperIdentification Benchmark

What is Kdd2013AuthorPaperIdentification?

How to Build Benchmark Environment?

  • Add exclude to /etc/yum.repos.d/CentOS-Base.repo file [base] and [updates] sections to exclude PostgreSQL Packages:
[base]
...
exclude=postgresql*
 
[updates]
...
exclude=postgresql*
# Only PostgreSQL 9.2 can store dataRev2.postgres
rpm -Uvh http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-6.noarch.rpm
yum install postgresql92 postgresql92-server postgresql92-contrib postgresql92-libs postgresql92-devel

# Python installation
yum install python
yum install python-devel

# Numpy installation
yum install numpy

# Scipy installation
yum install scipy

# g++ installation
yum install gcc-c++

# pip installation
yum install pip

# psycopg2 installation (not available by yum)
pip install psycopg2

# scikit-learn installation (not available by yum)
pip install -U scikit-learn

PostgreSQLのインストール

PostgreSQLのインストールにつまづいたので、ポイントを書いておきます。

f:id:tkdmah:20130420095945p:plain

ポイント1: .exeでインストールしてもPATHが通らない

.exeの標準設定でインストールして、ログインしようとすると、以下のようなエラーが出た。

C:\>psql -U postgres
psql: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

バージョンを確認してみると、8.2.11??

C:\>psql --version
psql (PostgreSQL) 8.2.11
contains support for command-line editing

何かのアプリケーションをインストールしたときにPostgreSQLもインストールされていて、それにアクセスしようとしていたようだ。
しかも.exeを実行してもPATHが設定されていなかった。
というわけで、スタート>コンピュータ>システムのプロパティ>システムの詳細設定>詳細設定>環境設定>システム環境設定>変数PATHの値にインストールしたパス(デフォルトでは"C:\Program Files\PostgreSQL\9.2\bin";)を先頭に加える。

ポイント2: ポート番号を合わせる

再びアクセスしようとすると下記のエラー。

C:\>psql -U postgres
psql: could not connect to server: Connection refused (0x0000274D/10061)
        Is the server running on host "localhost" (::1) and accepting
        TCP/IP connections on port 5432?
could not connect to server: Connection refused (0x0000274D/10061)
        Is the server running on host "localhost" (127.0.0.1) and accepting
        TCP/IP connections on port 5432?

dataの中にあるpostgresql.confからポートを確認すると、ポート番号が一致していない。

port = 5433				# (change requires restart)

以前インストールしたPostgreSQLが5432を使ってしまっていた。
以前のPostgreSQLには port = 5431 としてもらい、最新版を port = 5432 に変更して、保存して、再起動(pgAdminIIIからサービスの停止→サービスの再開)。

ポイント3: psqlとserverのバージョンを合わせる

やっと接続できた。が、psqlとserverのバージョンが異なるというWARNINGが出ている。

C:\>psql -U postgres
psql (9.2.4, server 9.1.9)
WARNING: psql version 9.2, server version 9.1.
         Some psql features might not work.
Type "help" for help.

pgAdminIIIからPostgreSQL 9.1のサービスを停止し、PostgreSQL 9.2に接続でWARNINGが出なくなった。

C:\>psql -U postgres
psql (9.2.4)
Type "help" for help.

postgres=# \q