2010年10月3日日曜日

SunのJava認定資格が

9月2日から、Oracle認定資格制度の一つになりました。OracleがSunを買収したから、まあ当たり前のことが行われたということですが。




はたして、試験の中身はSunのときと同じなのかなぁ(´・ω・`)



よく調べると、試験コードがSunとOracleで同じ(例えば、JavaプログラマならCX-310-065)だから中身も同じだ!と期待。



ちなみに、Oracle認定のMySQL資格もあるw

2010年9月5日日曜日

Observerパターン

Observerとは、観察者のことです。Observerパターンとは、作業者の状態を監視する役のクラスがあるパターンです。


先に、監視されるクラス(作業をするクラス)を説明すると、コードとしては以下の通りです。

public abstract class Subject {
    private List<Observer> observerList = new ArrayList<Obsever>();

    public void addObserver(Observer observer) {
        observerList.add(observer);
    }

    protected void notifyObservers() {
    // 参考本ではこのメソッドはpublicになっていたが、子クラスからしか呼ばれないので、protectedにした。
        Iterator itr = observerList.iterator();
        while (itr.hasNext()) {
            Observer observer = (Observer) itr.next();
            observer.update(this);
        }
    }

    public abstract void execute();

    // その他、observerから呼んで欲しいメソッドを定義
}

まず、監視する人をこの人は知っています。複数人いてもよいようにListになっています。作業をするメソッドはexecute()で実装しますが、何か状態が変わったときはexecute()内でnotifyObservers()を呼び、監視者に通知します(Observer#update()を呼びます)

監視するクラスについて説明します。監視者は誰も作業者の状態変更通知を受け取れるようにupdate()を実装します。そーいうことで、Observerインターフェースを用意しておきます。

public interface Observer {
    void update(Subject subject);
}

Observerインターフェースの実装クラスは例えばこんな感じです。

public class SampleObserver implements Observer {
    public void update(Subject subject) {
        // Subjectクラスのメソッドを呼び、例えばコンソールに出力する、ログに残すなどの処理を行う。
    }
}

この後は、Subjectクラスの子クラスを作り、mainクラスからその子クラスのインスタンスを作って、SampleObserverをaddし、execute()を呼べばいいでしょう。

監視をするパターン自体は難しくないと思います。ポイントとしては、どのクラスでも作業者、監視者になれるよう、親クラス(厳密に言うと、作業者はabstractクラスで、監視者はinterface)を定義してあげて、具体的な作業者、監視者はそれらを継承・実装することで、汎用性があがるということです。

ただし、注意しなければならないのは、SubjectからObserverへ通知をした後に、ObserverからSubjectへ何かしらの指示を行った場合です。このとき、Observerからの指示でSubjectの状態が変化すると、またそのタイミングでObserverへ通知を行ってしまうからです。フラグでも用意して、防ぐようにしましょう。

ちなみに、Observer#update()をSubjectが呼ぶ際は、Subject自身を引数に入れています。が、例えば値の更新を通知するだけならば、引数に値を入れて渡すでも良いと思います。ただし、この場合において、もし、Observerが複数のSubjectを監視しているならば、どのSubjectからの変更通知なのか分からないです。Observerにどの程度の情報を渡すかは実装する際に検討すべきでしょう。


しかし、このパターンは監視というより、通知ですよね・・・


関連パターン
Mediatorパターン」Mediatorは、個々の作業者との調整役という位置づけであり、Observerでは、SubjectがObserverに通知をして同期を取ることに主眼を置いています。

Mediatorパターン

Mediatorとは仲介役とか相談役とかという意味です。個々人がバラバラに作業しているところをまとめてくれます。個々人同士であーだこーだ言い合ってもまとまらない場合には全体を俯瞰できて、適切に指示できる人が欲しいですよね。

Mediatorパターンは個々の担当者の状態を把握し、次になるべき状態を個々の担当者に指示する役目がいるパターンです。ここで言っている状態とは、例えば、あるログインフォームで言うと

ゲストユーザか正規ユーザか
ユーザ名が入力できる入力できない
パスワードが入力できる入力できない
OKボタンが押せる押せない
・・・

などなどです。Mediatorは例えば、「正規ユーザが選択されている状態」かつ「ユーザ名とパスワードを入力されている状態」というのを担当者から聞いたら、「OKボタンを押せるようにする」という風にOKボタン担当者に指示します。


サンプルソースは・・・考えておきます(´・ω・`)


関連パターン
Facadeパターン」Mediatorは双方向だが、Facadeは一方向のみ。
「Observerパターン」(勉強中)

2010年8月19日木曜日

Eclipse3.6本体&プラグインインストール手順

(2010/09/11追記)全部日本語化したいなと思ったので、今はPleiadesで公開されている「Pleiades All in One Eclipse for Java Developers」を使っています。



ほんの2ヶ月ほど前だったでしょうか、Eclipseの最新ヴァージョンである3.6「Helios」が登場しました。新PC購入に伴い、このPCに入れるEclipseはHeliosにしようと思ったので、簡単に導入手順をまとめておきます。


1. Eclipse 3.6 ダウンロード
Eclipse Downloadsよりお好きなのをダウンロードしてください。よく分からない人は「Eclipse IDE for Java Developers」で良いと思います。おそらく、Eclipseを初めて触る人はIDEでJavaをコーディングしてみたい人だと思うので・・・ちなみに私は「Eclipse IDE for Java EE Developers」にしました。いや、Eclipse IDE for Java Developersでもいいと思うんだけどさ・・・ あと、32bit版、64bit版の2種類がありますから気をつけてください。

2. Eclipse解凍
ダウンロードしたファイルはzipファイルのため、それを解凍します。解凍すると、おそらく?中にeclipseフォルダがあり、更にその中にはeclipse本体が入っていることでしょう

3. 適当なところに配置
別にどこにおいても良いと思うのですが、いつもの私の習慣から、C直下にeclipseフォルダを作成し、(この時点でパスはC:\eclipse)更にその下にeclipseフォルダを置いて、名前をeclipse3.6にしました。(ということで、パスはC:\eclipse\eclipse3.6になりました)

4. 日本語化パッケージダウンロード
いつもなら「Pleiades」ですが、プラグインとして3.6対応は出ていないみたい。ちなみに3.6に日本語プラグインを入れたEclipseをPleiadesで配布してる・・・はじめからこれをダウンロードして使えって話ですよね(´・ω・`)


今回は日本語化言語パック(サードパーティ版)であるnlpackを入れることにしました。以下からダウンロードです。
http://sourceforge.jp/projects/blancofw/wiki/nlpack.eclipse
3.6なので「3.6.0 Stream Build」のをダウンロードしました。


5. 日本語化パッケージ解凍
ダウンロードしたファイルはzipファイルのため、それを解凍します。解凍すると、おそらく?中にeclipseフォルダがあり、更にその中にはfeaturesフォルダとpluginsフォルダがあると思います。


6. インストール
ここの作業が一番重要です。日本語化パッケージを解凍した際に出てくるeclipseフォルダをeclipse3.6の適切なところに入れます。まずすべきことは


6.1 eclipse3.6\dropins\フォルダの下に適当な名前のフォルダを作成する。
全角でも良いかどうかは未確認ですが、とりあえずプラグイン名がnlpackという名前らしいので、「nlpack」フォルダをdropinsの下に作ります。


6.2 日本語化パッケージのeclipseフォルダを移動
日本語化パッケージを解凍した際に出てくるeclipseフォルダ(中にはfeaturesフォルダとpluginsフォルダが入っている)を先ほど作ったnlpackフォルダの中に置きます。


7. 起動
eclipseを起動してみてください。eclipse.exeはeclipse3.6フォルダにあります。


起動した際に以下の日本語化されたダイアログが出れば日本語化プラグインインストール成功です。










ただ、起動してみると一部日本語化されていない感じが・・・こりゃあ、既に日本語化されたPleiadesのeclipseをダウンロードするしかないか・・・な?


補足:日本語化プラグインのアンインストールについて
dropins以下に入れたプラグインはそのまま削除することでアンインストールできます。それ以外でインストールしたプラグインはそれでは削除できません。というか、dropinsには入っていないので削除できませんが・・・dropins以外のプラグインインストールはまたの機会に説明します。


参考:日本語化 - Eclipse Wiki

2010年8月18日水曜日

Thunderbirdのデータ移行

旧PC(XP)から新PC(Win7)にデータ移行をしているのですが、Thunderbirdのデータはどうするのかなぁと思って調べてみると、意外と簡単でした。備忘のために一応メモっときます。


1. MozBackupを新旧PCにインストール
インストーラは以下にあり
http://www.geocities.jp/chimantaea_mirabilis/MozBackup/files.html

2. 旧PCにおいて、バックアップを取る。
旧PCでMozBackupを起動して、ガイドの通りに従えばバックアップファイルが生成される。

3. 生成されたバックアップファイルを新PCに移す。

4. 新PCにおいて、データ復元をする。
新PCでMozBackupを起動して、ガイドの通りに従えばバックアップファイルを元にしたデータ復元が実行される。


こうすればおk

ツールの対応OSが書かれていなくて不安に思ったが特に問題ありませんでした。

ちなみに、このツールはFireFoxも使えるそうだ

2010年8月4日水曜日

Facadeパターン

久々のデザパタですすみません(´・ω・`)

今日はFacadeパターンです。Facadeとは正面とか外見というフランス語?の言葉だそうです。デザインパターンの世界ではFacadeは「窓口」という意味で使ってます(正面とほぼ同じか・・・)

窓口ですので、「○○をお願いします。」と頼めば、その〇〇を関連項目も含めて全て処理してくれるということです。

Facadeクラスの例としては、以下のようにstaticメソッドを用意します。そのメソッド内では、必要な処理を実装します(あるいは、他クラスで実装されたメソッドを呼び出すなど)。
public class Facade {
    ・・・

    public static void doSample() {
        // 必要な処理を実装
    }
    ・・・
}

ユーザーは窓口に処理をお願いしましょう。
public class Main {
    public static void main(String[] args) {
        Facade.doSample();
    }
}

このパターンは、複雑な処理、例えばメソッドを適切な順番で過不足なく呼ぶ必要がある場合に威力を発揮します。それらの複雑なロジックを上記の例で言うdoSample()内でまとめ、中身を知らない人はただ単にdoSample()を呼べば済むということです。もちろん、doSample()を実装する人は仕様を詳しく知っている必要がありますが、開発メンバー全員がその仕様を知っている必要はないので、チームでコーディングする時には有効なパターンと言えます。

また、窓口を1つ用意して、利用者はそれを呼ぶだけでいいので、複数のメソッドを呼ぶケースと比べると、呼び出す側と呼び出される側の結合が緩いと言えます。結合が緩やかだと、部品として再利用しやすいです。

あとは、呼び出される側の「public メソッド」が少なくて済みます。これはカプセル化の話ですね。

ちなみに今回は窓口は1つしか例で示しませんでしたが、窓口が複数ある場合は当然考えられます。そして、窓口の窓口も大いにありえます。お願いごとは窓口に行けば十分ですからね。

関連パターン
Abstract Factoryパターン」「部品を作って」とお願いすれば作ってくれるので、Facadeパターンと言えます。
Singletonパターン」Facadeパターンは普通はSingletonです。インスタンス化して、複数の同じ窓口を作っても意味がありません。本には書かれていないですが、インスタンス化できないようにする(コンストラクタをprivateにする)としても良いと思います。
「Mediatorパターン」(勉強中)

2010年6月20日日曜日

Chain of Responsibilityパターン

Chain Of Responsibilityパターンは(本では)責任のたらい回しと書かれていて、なんだか悪いイメージがしますが、このパターンは「自分のところで処理できなければ、別の人に処理をお願いする」というパターンです。


今回もコードは単純に書きます(´・ω・`)
概要を先に示すと、
・クライアントはトラブルを対処する人にトラブル情報を渡す。
・トラブルを対処する人はトラブル情報を確認し、
・自分で対処できる→対処する
・自分で対処できない→他の人に対処してもらう
という感じです。トラブル情報は単純にトラブル番号のみを持つとします(本と同じです)


トラブルを対処するSupportクラスは以下のような感じです。
public abstract class Support {
    ・・・
    private Support next;
    ・・・
    public Support(String name) {
         ・・・
    }
    publilc Support setNext(Support next) {
        this.next = next;
        return next;
    }
    public final void support(Trouble trouble) {
        if (resolve(trouble)) {
            // 解決できた時の処理を記述
        } else if (next != null) {
            // 次の人にお願いする。
            next.support(trouble);
        } else {
            // 次の人がいない(誰ひとりとして対処できなかった)時の処理を記述
        }
    }
    protected abstract boolean resolve(Trouble trouble);
}
自分で対処できない場合に次の人にお願いするので、Supportクラスのインスタンスをnextフィールドで持つようにします。

対処する時にはsupportメソッドが呼ばれます。中ではまず、サブクラスで定義されるresolveメソッドを呼びます。resolveメソッドは解決できた時にtrue、解決できなかった時にfalseが返すとします。trueならば、解決できたのでその時の処理を実行し、そうでない場合は次の人(nextに入っているSupportクラスのインスタンス)にお願いします。そして、次の人でsupportメソッドが実行され、解決できた時はその時の処理、解決できなかったときは次の人へ・・・と処理が続きます。もし、解決できないまま、次の人がいなくなってしまった場合はそのトラブルは誰ひとりとして対処できなかったということで、その時の処理を実行します。

Supportクラスのサブクラスはresolveメソッドを実装します。Troubleクラスのインスタンスの中身を参照して、そのメソッドにあった処理を実装します。

Mainクラスでは対処順序を決めておき、出てきたトラブルを対処してもらいましょう(ちなみに、出てきたトラブルをSupportにお願いするのがクライアントの役目です)
・・・
Support support1 = new Support1(・・・);
Support support2 = new Support2(・・・);
Support support3 = new Support3(・・・);
support1.setNext(support2).setNext(support3);// 本当はJavaでメソッドチェーンを書くのはあまりおすすめしない・・・
・・・
support1.support(new Trouble(・・・));
このパターンの良いところは、クライアントはトラブル対処処理を知る必要がなく、1人目にお願いするだけで良いというところです。クライアントとサポートのつながりがゆるいということです。もし、クライアントがトラブル対処処理を知るとなると、密なつながりを持つことになってしまいます。

サポートだけを見ても、無理ならば次の人にお願いするだけなので、サポートメンバーを全員知っておく必要もありません。しかし、たらい回しなのでパフォーマンスが悪くなる可能性があるのがこのパターンの欠点です。もし、パフォーマンスを上げたければ、各サポートメンバーを知っているマネージャーがいて、トラブルの中身によって適切なサポートメンバーにお願いするという形になると思います。「このトラブルについてはこの人に任せよう」と直接お願いするということです。

関連パターン
Compositeパターン」サポートがCompositeパターンで定義される場合あり
「Commandパターン」(勉強中)

Visitorパターン

Visitorとは訪問者のことで、Visitorパターンとはデータ構造の中を訪問して処理を行うパターンです。

プログラムの説明を全部すると莫大な量の文章を書かなくてはならないので今回は割愛サーセン(´・ω・`)


Visitorは、各データを訪問するvisitorメソッドを用意します。以前勉強したCompositeパターンで言うと、Fileクラスを訪ねるvisitorメソッドとDirectoryクラスを訪ねるvisitorメソッドを用意することになります。

public void visit(File file) {
    ・・・
}

public void visit(Directori dir) {
    ・・・
}
ちなみに、訪問時の処理が複数考えられるならば、処理ごとにクラスを切り出します。上記のコードをabstractなVistorクラスとして書いておいて、そのクラスを継承したクラスを作ればいいです。

また、訪問される側(つまり、データ側)は訪問を受け入れなければなりません。ということで、acceptメソッドを用意します。引数は訪問してきた人、つまり、Visitorクラスのインスタンスです。
public void accept(Visitor v) {
    v.accept(this);
}
内部では、訪ねてきた人に処理をお願いします。渡すのは自身です。ということで、(Compositeパターンの例で言うと)Fileだったり、Directoryだったりします。本には書かれていないのですが、もし何かしらの理由で受け入れできない場合はここで例外を出すのが良いと思います。

Mainでは、データを用意してVisitorに訪問してもらいましょう。
・・・
File file = new File("sample", 100);
file.accept(new SampleVisitor());
・・・

このパターンを使う理由としてはデータと処理の分離をするためです。
処理の追加はVisitorクラスを継承したクラスを作ればよいので容易です。しかし、データを拡張した場合は、Visitorクラスにそのデータに訪問するvisitメソッドを(Visitorクラスのサブクラス全て)書かないといけないので、大変です。

関連パターン
Iteratorパターン」データ構造を辿って処理するパターンのもうひとつの例
Compositeパターン」Visitorパターンを適用するデータ構造はCompositeパターンになることがある。
「Interpreterパターン」(勉強中)

2010年6月13日日曜日

Decoratorパターン

Decoratorパターンとは、あるものを土台にしてDecorateする(飾り付ける)ためのパターンです。普通は飾り付けるといいますか、土台に対して何かを付加したい場合はその土台クラスを継承したクラスを実装することが考えられます。しかし、これですと臨機応変に付加したいタイプを変えたり、複数のタイプを付加したい場合に実現できません。「ベースはこれで、これとこれを付加したい、飾りつけたい」と言った場合に威力を発揮するのがこのパターンです。


今回は文字列を#または<>、あるいはその両方をつけてコンソールに表示するサンプルにします。

まず、文字列表示用のベースクラスです。
public abstract class SampleBase {
    public abstract String getValue();
    public final void print() {
        System.out.println(getValue());
    }
}
print()が呼ばれると子クラスで持っている文字列を表示します。もちろん飾りはついていれば飾りも合わせて表示されます。

文字列を持っているクラスは以下の感じです。
public class Sample extends SampleBase {
    private String value;
    public Sample(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
コンストラクタを介して文字列が渡されます。SampleBaseを継承しているので、getValue()を実装しています。ただ単にこのクラスが管理している文字列を返すだけです。

次に、飾り付け用のベースクラスです。
public abstract class Decor extends SampleBase {
    protected SampleBase sampleBase;
    public Decor(SampleBase sampleBase) {
        this.sampleBase = sampleBase;
    }
}
飾り付けも表示されるのでSampleBaseを継承しているのが特徴です。そして、自身は何に対して飾り付けるのかを知っておく必要がありますので、sampleBaseを持っています。

具体的な飾り付けクラスの一つは以下のとおりです。
public class SharpDecor extends Decor {
    public SharpDecor(SampleBase sampleBase) {
        super(sampleBase);
    }

    public String getValue() {
        return "#" + sampleBase.getValue() + "#";
    }
}
コンストラクタを介して、飾り付けの対象を受け取ります。Sampleが渡されることがあるのは分かると思いますが、Decorを継承したオブジェクトが渡されることもあります。そして、そのDecor継承クラスは飾り付けの対象を知っていて・・・という風に構造が再帰的になります。これがDecoratorパターンの特徴です。ちなみに、SampleBaseもDecorもabstractなので、getValueメソッドはここで実装します。ここでは、飾り付けの対象からgetvalueメソッドで値を取り出し、#で「飾り付け」をして返しています。

他の飾り付けクラスは以下のとおりです。
public class BracketDecor extends Decor {
    public BracketDecor(SampleBase sampleBase) {
        super(sampleBase);
    }

    public String getValue() {
        return "<" + sampleBase.getValue() + ">";
    }
}
Mainは以下のとおりです。
public class Main {
    public static void main(String[] args) {
        SampleBase sample = new Sample("sample");
        sample.print(); // 何も飾りつけずに表示
        SampleBase sample2 = new SharpDecor(sample);
        sample2.print(); // #で飾り付け
        SampleBase sample3 = new BracketDecor(sample);
        sample3.print(); // <>で飾り付け
        SampleBase sample4 = new BracketDecor(sample2);
        sample4.print(); // #で飾りつけたサンプルに<>で飾り付け
    }
}
一番最初にSampleインスタンスを作り、まずは何も飾り付けずに表示します。その後に#で飾り付けた場合、<>で飾り付けた場合を表示し、最後に#で飾り付けたsample2を更に<>で飾り付けるという流れになっています。

実行結果は以下のとおりです。







このパターンを利用することで、機能追加が容易(今回の例でいう飾り付けの種類がいくらでも増やせる)であり、しかも、飾り付けられるもの(今回だとSampleクラス)を変更する必要がありません。文字列を表示すること自体も基本的にはsampleBaseへ移譲しているだけということもあり、クラス間結合(今回だとSampleとDecor、Decor同士)は緩い→動的に機能追加、差し替えができるのも特徴です。

ちなみに、java.ioパッケージはDecoratorパターンで実装されています。

関連パターン
Adapterパターン」中身のインターフェースを変えずに作るのがDecoratorパターンで、異なるインターフェースをつなぐのがAdapterパターン
Strategyパターン」飾りを変えたり重ねたりするのがDecoratorパターンで、アルゴリズムを変えるのがStrategyパターン

Compositeパターン

Compositeとは「合成する」とか「混ぜる」という意味ですが、Compositeパターンはファイルとディレクトリ構造のように容器とその中身を同じものとして扱い、再帰的な構造を作るパターンになります。

ファイルとディレクトリの例でいいますと、

Entryクラス
  • FileクラスとDirectoryクラス共通の親クラス(abstract)
  • FileとDirectory共通のメソッドはここでabstractで定義
  • Entryをaddするaddメソッドも用意するが、使用できるのはDirectoryのみなので、Entryクラス上では「何も実行しない」又は「例外を投げる」にしておく(ちなみに、addメソッドをabstractにすると、Fileクラスでaddメソッドを実装するハメになるので、abstractにしない)
Fileクラス
  • ファイルを表すクラス
  • 管理するのは名前とファイルとファイルサイズくらい?
Directoryクラス
  • ディレクトリを表すクラス
  • 名前とそのディレクトリが保持しているEntryのリストを管理
  • 必ずaddメソッドを実装
です。

ファイル(ディレクトリ)パスを表示したいときは、Entryクラスにabstractなprintメソッドを用意し、各クラスの実装においては、
  • Fileクラス:ファイル名を表示
  • Directoryクラス:自信のディレクトリ名だけでなく、リストから一つずつEntryを取り出し、それのprintメソッドを呼ぶ(Compositeが再帰的なので、このメソッドも再帰的に定義出来る)
と言う風にしておけばいいでしょう。


すみません、サンプルソースは本の丸写しになりそうなのでやめておきます(´・ω・`)
ファイル、ディレクトリ以外でCompositeになるものがあればいいのですが・・・


関連パターン
「Commandパターン」(勉強中)
「Visitorパターン」(勉強中)
Decoratorパターン」中身と容器を同じ扱いにするのがCompositeパターンで、中身と飾りを同じ扱いにするのがDecoratorパターン


Strategyパターン

すみません、仕事で立て込んでいたのでなかなか勉強する暇がありませんでした(´・ω・`)
Strategyパターンとは、様々なアルゴリズムをクラス単位で実装し、実行時に場面に応じて、そのアルゴリズムクラスを切り替えて処理して行くパターンになります。


で、クラス図としては前回のBridgeパターンとあまり変わりません。前回で言うところの実装クラス群に相当するところが今回はアルゴリズムクラス群になります。つまり、1つインターフェースがあり、その実装クラス内でアルゴリズムを実装します。そして、mainになるクラスはそのアルゴリズムクラスのインスタンスを(任意の条件、タイミングで)作り、共通のメソッドを呼べばおkです。

Strategyのインターフェースの例は以下のような感じです。
public interface Strategy {
    public void exec();
}

実装クラスの1つはこんな感じ
public interface AStrategy {
    ・・・
    public AStrategy(・・・) {
        ・・・
    }

    public void exec() {
        // AStrategy特有のアルゴリズムを実装
    }
}

他の実装クラスも(きっと)同じ感じになるでしょう

public interface BStrategy {
    ・・・
    public BStrategy(・・・) {
        ・・・
    }

    public void exec() {
        // BStrategy特有のアルゴリズムを実装
    }
}
mainクラスでは以下のように呼びます。
public static void main(String[] args) {
    Strategy aStrategy = new AStrategy(・・・);
    Strategy bStrategy = new BStrategy(・・・);
    ・・・
    aStrategy.exec();
    bStrategy.exec();
    ・・・
}
あくまでこれは例なので、ある条件の時はaStrategy、そうでないときはbStrategyにしてももちろん構いません。あるいはaStrategy実行中に何かしらの理由でbStrategyに切り替えることもあるかと思います。ここがミソで、このパターンを利用するとアルゴリズムを容易に切り替えられるということなのです。

関連パターン
「Flyweightパターン」(勉強中)
Abstract Factoryパターン」こちらのパターンは工場・部品などをごっそり切り替えるパターン
「Stateパターン」(勉強中)

2010年5月23日日曜日

Bridgeパターン

Bridgeパターンとは、実装クラス層と機能クラス層を橋渡しするためのパターンです。

実装クラス層と言うのは、abstractなクラスやinterfaceとそれらを継承、実装したクラス群のことをいいます。機能クラス層は1つのベースクラスと、メソッド等を追加するためにベースクラスを継承したクラスが複数個含まれるクラス群のことです。

この2つの層を結ぶ橋を用意することで、クラスの拡張を容易にすることができます。

(そろそろクラス図がないと説明しづらくなってきましたが、お付き合いください)

今回の例は単純に、引数でもらった文字列を加工して表示するだけです(毎度おなじみですが)
まずは、機能クラス層のベースクラスDisplaySampleです。
public class DisplaySample {
    private DisplayImpl impl;

    public DisplaySample(DisplayImpl impl) {
        this.impl = impl;
    }

    public void print() {
        impl.print();
    }
}

フィールドとして実装クラス層のオブジェクトを持ちます。これが「橋」となります。メソッドとしてはprint()のみです。これを呼ぶと、実装クラス層で定義されているprint()を呼び出します。

このベースクラスを継承したクラス(機能追加したクラス)は以下のとおりです。単純に、printTwice()を追加しただけです。これを呼ぶと、実装クラス層のprint()を2回呼びます。
public class ExtendedDisplaySample extends DisplaySample {
    public ExtendedDisplaySample(DisplayImpl impl) {
        super(impl);
    }

    public void printTwice() {
        System.out.print("1回め:");
        print();
        System.out.print("2回め:");
        print();
    }
}

次に、実装クラス層です。実装クラス層では、インターフェースとその実装クラスがあるわけですが、インターフェースとしては以下の通りです。
public interface DisplayImpl {
    public void print();
}

実装クラスは今回は2つ用意しました。1つは以下のように引数の文字列にアスタリスクをつけて返すだけのprint()を実装したクラスです。
public class AsteriskDisplayImpl implements DisplayImpl {
    private String value;

    public AsteriskDisplayImpl(String value) {
        this.value = value;
    }

    public void print() {
        System.out.println("*** " + value + " ***");
    }
}

もう一つは文字列の大文字小文字を変換して表示するprint()を実装したクラスです。
public class UpperLowerDisplayImpl implements DisplayImpl {
    private String value;

    public UpperLowerDisplayImpl(String value) {
        this.value = value;
    }

    public void print() {
        // valueをchar配列に変換
        char[] valueChars = value.toCharArray();

        // 大文字小文字を変換した後の文字を格納するビルダー
        StringBuilder sb = new StringBuilder();

        // 1文字ずつ、大文字か小文字かを判別し、ビルダーに変換後の文字を
        // 格納していく
        for (char ch : valueChars) {
            if (Character.isLowerCase(ch)) {
                sb.append(Character.toUpperCase(ch));
            } else {
                sb.append(Character.toLowerCase(ch));
            }
         }

         // toString()を呼び出して文字列として表示
         System.out.println(sb.toString());
     }
}
よくよく考えると、わざわざchar配列を用意しなくても、ループ中にvalue.charAt()を使えばいいよねorz

Mainは以下のとおりです。
public class Main {
    public static void main(String[] args) {
        DisplaySample dis1 = new DisplaySample(new AsteriskDisplayImpl("asterisk"));
        DisplaySample dis2 = new DisplaySample(new UpperLowerDisplayImpl("upperLOWER"));
        ExtendedDisplaySample ext1 = new ExtendedDisplaySample(new AsteriskDisplayImpl("twice / asterisk"));
        ExtendedDisplaySample ext2 = new ExtendedDisplaySample(new UpperLowerDisplayImpl("twice / uPpErLoWeR"));

        dis1.print();
        dis2.print();
        ext1.printTwice();
        ext2.printTwice();
    }
}
Mainでは、全部で4パターン用意してます。DisplaySampleとAsterisk、DisplaySampleとUpperLower、ExtendedとAsaterisk、ExtendedとupperLowerです。実行結果は以下のとおりです。








このパターンを使うと、機能拡張をしたい場合はExtendedDisplaySample(場合によってはDisplaySampleを再び継承?)を継承したり、DisplayImplの実装クラスを増やせば良いだけですね。

関連パターン
Abstract Factoryパターン」interface実装クラスにこのパターンを用いることがある
Template Methodパターン」実装クラス層で利用
Adapterパターン」異なるクラス同士を結びつけるためのパターン。これも橋渡し役と言えそう

Abstract Factoryパターン

前に紹介したパターンでは部品を抽象化して、マネージャーとかファクトリーに当たるところはせいぜいインターフェースで定義したAPIのみを使うという形でしたが、今度はファクトリーも抽象化します。ちなみに、ファクトリーが抽象的なら、そのファクトリーが扱うパーツも抽象的です。

※部品というより製品って言った方がいいかもな・・・

まず、抽象的なPartは以下のような感じです。
public abstract class Part {
    protected String name;

    public Part(String name) {
        this.name = name;
    }

    public abstract void doSomething();
}

nameフィールドがprotectedになっていますが、これは子クラスでもnameフィールドにアクセス出来るようにするためです。
そのPartを扱うFactoryは以下のようにします。
public abstract class Factory {
    public abstract Part createPart(String name);
}

もし、種類の違うPartを用意したければ、Partクラスとは違うクラスを作成し、Factoryクラスの中にもう一つcreateメソッドを用意すればいいです(*1)

抽象的なクラスがあれば、具体的なクラスもあります(ようは、抽象的なクラスを継承したクラスを作るのです)。具体的なクラスは例として2種類用意しました。

まず、1つ目のABCPartは以下の感じです。doSomething()はとりあえずはnameを表示するだけにしました。
import factory.Part;

public class ABCPart extends Part {
    public ABCPart(String name) {
        super(name);
    }

    public void doSomething() {
        System.out.println("ABCPart - name: " + name);
    }
}
ABCPartを扱うABCFactoryは以下の通りです。
import factory.Factory;
import factory.Part;

public class ABCFactory extends Factory {
    public Part createPart (String name) {
        return new ABCPart(name);
    }
}
2つ目はDEFPartです。ソースは以下の通りです。こちらのdoSomething()もnameを表示するだけですが、表示形式を変えています。
import factory.Part;

public class DEFPart extends Part {
    public DEFPart(String name) {
        super(name);
    }

    public void doSomething() {
        System.out.println("DEFPartです。名前は " + name + " です。");
    }
}
DEFPartを扱うDEFFactoryは以下の通りです。
import factory.Factory;
import factory.Part;

public class DEFFactory extends Factory {
    public Part createPart (String name) {
        return new DEFPart(name);
    }
}
Factoryを扱うMainは以下の通りです。
import factory.Factory;
import factory.Part;
import abc_factory.ABCFactory;
import def_factory.DEFFactory;

public class Main {
    private static final String ABC_FACTORY = "ABCFactory";
    private static final String DEF_FACTORY = "DEFFactory";

    public static void main(String[] args) {
 // TODO argsの長さが0だったり、2以上の場合があるので、その時はSystem.exit(0)を呼んで終了させる。

        Factory factory = createFactory(args[0]);

        Part part = factory.createPart("sample");
        part.doSomething();
    }

    private static Factory createFactory(String factoryName) {
        if (ABC_FACTORY.equals(factoryName)) {
            return new ABCFactory();
        } else if (DEF_FACTORY.equals(factoryName)) {
            return new DEFFactory();
        } else {
            return null;// TODO こうすると呼び出し側でnullチェックをしないといけないので望ましくない。
        }
    }
}
ABCFactoryとDEFFactoryの2種類があるので、引数で選択します。ですが、実際にFactoryやPartに処理をお願いするときにはどちらのFactory、Partを使っているのか気にする必要はありません。前回やったパターンと同じで、共通のAPIを利用するだけです。

ということで、今回はFactoryも抽象化してみました。前回同様、具体的なことは知らなくても処理をすることができます。

ちなみに、Mainクラスは具体的なクラスをimport文を利用して知っちゃっています。Mainクラスも具体的なクラスを知らないようにする方法は以下のとおりです。
public static Factory createFactory(String factoryName) {
    Factory factory = null;
    try {
        factory = (Factory)Class.forName(factoryName).newInstance();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
        return factory;
    }
}
これはクラス名を引数にとり、ClassクラスのforName()で、指定したクラスを動的に読み込みます。読み込んだクラスのインスタンス化はnewInstance()です。こうすることで、import abc_factory.ABCFactoryと書いたり、new ABCFactory();と書く必要がなくなります。言い換えると、MainはABCFactory()などを知っておく必要はないということです。

関連パターン
Builderパターン」どちらも複雑なインスタンスを生成するパターン
Factory Methodパターン」FactoryクラスのcreateのところをFactory Methodパターンにすることがある。
Compositeパターン」ファクトリーで作られる部品をComposite(つまり、部品の中に更なる部品)になる場合がある。
Singletonパターン」ファクトリーをいくつ作っても仕方がないので、それをSingletonパターンにすることがある。


*1 なので、Factory Methodパターンを利用するのが良いかと

2010年5月16日日曜日

Builderパターン

Builderパターンとは、文字通りビルド(組み立て、建築、構築)のためのパターンです。このパターンに出てくる人物は実際に建物を作る時と同様に、建築者、監督者、依頼人です。要件によって作るものは異なりますから、実際には上記に加えて、要件に特化した建築者もいます(本では具体的建築者なんて言っていますが)


まず、建築者はインスタンスを作るためのインターフェースを決めます。Builderクラスは以下のような感じです。
public abstract class Builder {
    public abstract void makeEntrance();
    public abstract void makeRoom(String name);
    ・・・
}

上のクラスを継承したクラス(ようは要件に特化した建築者)は以下のようにします。他の要件の場合でも同様に継承して作ればよいでしょう。
public class ABCBuilder extends Builder {
    public void makeEntrance() {
        ・・・
    }

    public void makeRoom(String name) {
        ・・・
    }
}

監督者であるDirectorクラスは、Builderクラスで宣言されているメソッドを使用して、実際に建築の指示をします。
public class Director {
    private Builder builder;
    public Director (Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.makeEntrance();
        builder.makeRoom("staff room");
        ・・・
    }
}
コンストラクタの引数がBuilderクラスのオブジェクトになっています。ここに、特化した建築者を入れてあげます。ソースを見てのとおり、監督者はBuilderクラスのメソッドしか呼ばないため、具体的にどんな建築者がやってきたのかを監督者であるDirectorは知りません。ですが、監督者は別にそんなことを意識しなくても必要な操作、つまり、Builderクラスで定義したメソッドを呼ぶことができちゃいます。

Mainクラスでは、要件に応じてABCBuilderクラスのインスタンス又はDEFBuilderクラスのインスタンスを生成し、Directorに構築の依頼をします。
public static void main(String[] args) {
    ・・・
    Director director = null;
    if ("ABC".equals(args[0])) {
        ABCBuilder abc = new ABCBuilder();
        director = new Director(abc);
    } else {
        DEFBuilder def = new DEFBuilder();
        director = new Director(def);
    }
    director.construct();
    ・・・
}

ここでのポイントは、依頼者であるMainクラスは、ABCとDEFがどのように構築されるかは知りません。ただ単に監督者に構築をお願いしただけです。そして、先程も説明しましたが、監督者はどんな建築者がやってこようと必要な指示をするだけで済んでいます。このパターンは各クラス間の独立性が高いことと、拡張性がある(別の用件に特化した建築者を作っても容易に対応出来る)のが特徴です。ですが、(他のパターンでも言えることですが)クラスの役割はしっかり理解しましょう。DirectorがABCBuilderのメソッドを呼ぶなんて以ての外です。

関連パターン
TemplateMethodパターン」今回のパターンでは、「DirectorがBuilderをコントロールする」パターンだったが、Template Methodパターンでは、「スーパークラスがサブクラスをコントロールする」パターン
Compositeパターン」作るものがCompositeになる場合がある。
Abstract Factoryパターン」どちらも複雑なインスタンスを生成するためのパターン
Facadeパターン」Facadeパターンは複数の処理をまとめて一つのメソッド(窓口)として実装し、外部からそのメソッドを呼ぶだけでよいパターン。BuilderパターンもBuilderが行う複数の処理をDirectorがまとめているという点で似ている。

Prototypeパターン

Prototypeパターンとは、インスタンスをnewで生成するのではなく、既にあるインスタンスからコピーをして新しいインスタンスを作るパターンです。このパターンを使う場面としては、似たようなクラスを大量に作りたくない場合や、インスタンス生成が難しい場合(*1)、F/W(*2)とインスタンス生成を分けたい場合などです。

コード例としては、複数のパーツを用意してそれを利用するという形にしています。パーツをコピーできるようにするためのPartインターフェースと、それを利用するManagerクラスをF/Wで用意します。パーツの雛形(まさしく、プロトタイプ)はPartインターフェースを実装すればよいです。実際にサンプルコードを動かしたいときは、PartインターフェースとManagerクラスのソースをframeworkフォルダに入れ、それ以外はframeworkフォルダの外においてください。

Partインターフェースは単純に以下のような感じです。Partはコピーできるので、copy()を用意しています。copy()を実際に実装するときはjava.lang.Objectのclone()を呼ぶので、cloneableインターフェースを継承しています。

package framework;
import java.lang.Cloneable;

public interface Part extends Cloneable {
    void doSomething();
    Part copy();
}

ManagerクラスはPartインターフェースを介してインスタンスのコピーを行うクラスです。register()はPartの登録、copyPart()はPartをコピーして、それを取得します。

package framework;
import java.util.Map;
import java.util.HashMap;

public class Manager {
    private Map<String, Part> showcase = new HashMap<String, Part>();
    public void register(String name, Part part) {
        showcase.put(name, part);
    }
    public Part copyPart(String name) {
        Part p = (Part)showcase.get(name);
        return p.copy();
    }
}


Partインターフェースを実装するクラスでは、doSomething()はそのパーツにあった処理(パーツの名前を決めたり、読み込むファイルを指定したり、フラグを立てたり・・・なんでも構わない)を定義すればよく、copy()はただ単純にjava.lang.Objectのclone()を呼べばいいです。(*3) 

Main(PartとManagerを利用するクラス)では以下のような感じです。最初はもちろんPartインスタンスを生成して登録しておく必要がありますが、その後はManagerさんにcopyPart()をお願いして、コピーを頂くだけです。
import framework.Part;
import framework.Manager;

public class Main {
    public static void main(String[] args) {
        // 準備
        Manager manager = new Manager();
        SamplePart part1 = new SamplePart("part1");
        SamplePart2 part2 = new SamplePart2("part2");
        manager.register("abc", part1);
        manager.register("def", part2);

        // 生成
        Part p1 = manager.copyPart("abc");
        p1.doSomething();
        Part p2 = manager.copyPart("def");
        p2.doSomething();
    }
}


register()に入れる名前は分かりやすいものがいいでしょう。コピーをお願いするときはその名前を指定します。例が今ひとつ分かりづらいですが、雛形としてのPartはManagerに登録されているので、わざわざパーツを一つずつ自分で作って(コーディングして)、そのクラスをnewする必要がなくなります。単純に言えば再利用性が高いということです。

また、ManagerクラスはPartを扱うクラスではあるものの、実際のPart(例で言うと、SamplePartやSamplePart2)については知らなくて構わないので、パーツとマネージャの依存関係が低いと言えます。

関連パターン
「Flyweightパターン」(勉強中)
「Mementoパターン」(勉強中)
Compositeパターン」Compositeで複雑な構造のインスタンスを作る場合にはprototypeを利用すると良いかもしれない(と本には書かれている)
Decoratorパターン」Decoratorで複雑な構造のインスタンスを作る場合にはprototypeを利用すると良いかもしれない(と本には書かれている)
「Commandパターン」(勉強中)

*1 例としては、グラフィックエディタなどでユーザがマウス操作によって作り上げた図形を再び作りたい場合。プログラミングでこれを作るのは大変なので、ユーザ操作によって作られた図形インスタンスをあらかじめ保存しておいて、それを作りたいときにコピーする(と本には書かれている)
*2 F/W frameworkの略称
*3 本当はclone()の実装についていろいろ説明したいが、本筋から離れるので割愛。気になる人は「Effective Java」のp.54にある「項目11 cloneを注意してオーバーライドする」を参照されたし

2010年5月9日日曜日

Singletonパターン

Singletonパターンとは、システム内でとあるクラスのインスタンスを「たった1つ」しか作らない(作りたくない)ようにするためのパターンです。このパターンを実現することで、指定したクラスのインスタンスが『絶対に』1つしか無いことを保証します。

Singletonにするクラスは以下のようになります。
public class SingletonSample {
    private static SingletonSample instance = new SingletonSample();

    /**
     * デフォルトコンストラクタ
     * 外部から使用されないようにprivateにしている
     */
    private SingletonSample() {}

    public static SingletonSample getInstance() {
        return instance;
    }
}
このクラスのように、Singletonを実現する場合は
  • 自身のインスタンスを持つprivateフィールドを用意する。
  • デフォルトコンストラクタにprivateをつける。
  • インスタンスを取得するメソッドを用意する。
となります。

Mainクラス(SingletonSampleクラスを利用するクラス)では以下のようにgetInstance()を呼べば良いです。
SingletonSample obj1 = SingletonSample.getInstance();

ちなみに、以下のようにMainクラスでSingletonSampleインスタンスを作るコードを入れると、
SingletonSample obj1 = new SingletonSample();




上の通り、コンパイルエラーになります。デフォルトコンストラクタがprivateで外部から利用できないようにしているので当たり前ですね。

また、getInstance()を何度呼んでも同じインスタンスなのかをチェックしてみます。以下のように、getInstance()を2回呼んで、それぞれの変数(obj1とobj2)は同じインスタンスを指しているのかをチェックします。(オブジェクト型を==で比較した場合、それは同一のインスタンスかどうか、正確に言うと、そのインスタンスが置かれているメモリ上の番地が同じかをチェックします。番地が同じならば同じインスタンスを指しているということになり、trueと判定されます)

SingletonSample obj1 = SingletonSample.getInstance();
    SingletonSample obj2 = SingletonSample.getInstance();
    if (obj1 == obj2) {
        System.out.println("same");
    } else {
        System.out.println("different");
    }
実行結果は以下の通りです。



Singletonパターンの悪い実装例も挙げておきます。
    private static SingletonSample instance;

    /**
     * デフォルトコンストラクタ
     * 外部から使用されないようにprivateにしている
     */
    private SingletonSample() {}

    public static SingletonSample getInstance() {
        if (instance == null) {
            instance = new SingletonSample();
        }
        return instance;
    }

上記では、SingletonSampleのインスタンスをフィールドで生成するのではなく、getInstance()が呼ばれた際にnullであるかどうかを判定して、もしnullならばその時に生成する方法を取っています。がしかし、複数の異なるスレッドから「ほぼ同時に」getInstance()を呼び出した場合、SingletonSampleのインスタンスが複数生成される可能性があります。

Javaでは、クラスに初めてアクセスした際にそのクラスの初期化が行われる(当然、その初期化は最初の1回のみ)ので、フィールドでインスタンスを生成するようにしておけば、複数生成されることは無いということになります。

注意:悪い実装例で、getInstance()にsynchronizedをつける方法も考えられるが、同期化コストが高いので推奨しません(と、wikipediaに書かれている)。スレッドのことをよく知らないので、そのコストがどれだけ高いのか分かりません(´・ω・`)

関連パターン
以下のパターンはインスタンスが1つである場合が多い

2010年5月2日日曜日

Factory Methodパターン

Factory Methodパターンとは、インスタンス生成を前回のTemplate Methodパターンで構成したパターンになります。インスタンス生成を行う(まさしく工場と言える)Factoryクラスと生成したものを表すProductクラスをフレームワークとして用意し、具体的な処理はそれぞれを継承して定義します。

例えば、工場では商品を作り、ある処理を行うというフローがある時には
public abstract class Factory {
    /**
     * 商品を作る.
     * @param name 商品名
     */
    public final Product create(String name) {
        Product p = createProduct(name);
        doSomething(p);
        return p;
    }
    
    protected abstract Product createProduct(String name);
    protected abstract void doSomething(Product p);
}

のようにしておきます。具体的な処理はこのクラスを継承して、
public class SampleFactory extends Factory {
    protected Product createProduct(name){
        return new SampleProduct(name);
    }
    protected void doSomething(Product p) {
        ・・・
    }
}

とします。Mainとなるクラス(Factoryを呼ぶクラス)は以下のような処理があれば良いです。
Factory factory = new SampleFactory();
Product product = factory.create("sample");

SampleProductクラスはProductクラスを継承したクラス(具体的な商品を表すクラス)です。

こうすることで、どんな商品が登場しても(Factory、Productクラスを継承したクラスがどんなに増えても)「商品を作って、ある処理を行う」というフローが変わりません。また、フレームワーク側は上記のようなSampleFactoryクラスやSampleProductクラスに依存しません。言い換えると、新商品が登場してもフレームワークを修正する必要がないということです。

関連パターン
「Template Methodパターン」Factory MethodパターンはTemplate Methodパターンの応用例
Singletonパターン」FactoryクラスはSingletonの場合が多い。
Compositeパターン」製品がcomposite(製品の中にある製品が含まれる)になる場合がある。
「Iteratorパターン」Iteratorインスタンス作成にはFactory Methodパターンが使われることがある。

Template Methodパターン

Template Methodパターンとは、文字通り、テンプレートとなるメソッドを用意して利用するパターンです。具体的には、内部に抽象メソッド(Javaの場合、abstractをつけたメソッド)をいくつか呼び出しているテンプレートメソッドを用意し、、抽象メソッドの具体的な処理をサブクラスで決めます。もちろん、サブクラスによって抽象メソッドの処理内容は違う可能性があるわけですが、どのように実装しても大きな流れはテンプレートメソッドで組み立てた通りになります。

例えば、テンプレートのあるクラスは
public abstract class AbstractSample {
    protected abstract void start();
    protected abstract void finish();
    public final void execute() {
        start();
        System.out.println("execute");
        finish();
    }
}

になります。execute()がテンプレートメソッドです。start()とfinishi()はサブクラスで以下のように定義します。
public class Sample extends AbstractSample {
    protected void start() {
        System.out.println("--- Start ---");
    }

    protected void finish() {
        System.out.println("--- Stop ---");
    }
}

別のサブクラスでは以下のようにしてみます。
public class AnotherSample extends AbstractSample {
    protected void start() {
        System.out.println("*** スタート ***");
    }

    protected void finish() {
        System.out.println("*** 終了 ***");
    }
}

Mainクラスは以下のようにしてみました。
public class Main {
    public static void main(String[] args) {
        AbstractSample sample = new Sample();
        sample.execute();
        AbstractSample anotherSample = new AnotherSample();
        anotherSample.execute();
    }
}

実行結果はこんな感じです。








このようにすることで、

  • サブクラスをいくつ作っても、大きな流れはテンプレートメソッドの通り(ロジック共通化)
  • サブクラスをいくつ作っても、呼び出すメソッドは同じ名前のメソッド

といった点が挙げられます。具体的な処理はサブクラスに決めてもらわないといけないとは言え、抽象クラスで処理を形作れることが、抽象クラスの存在意義と言えるでしょう。

注意:本に付属のサンプルコードで、Linux向けのものは文字コードがEUC_JPになっているため、コンパイル時に場合によっては警告が出るかもしれません。その時は、コンパイル時にencodingオプションを入れて

%> javac -encoding EUC_JP *.java

とすること。

関連パターン
「Factory Methodパターン」 Template Methodパターンをインスタンス生成に応用した例
Strategyパターン」Template Methodパターンでは継承を利用してプログラム動作を変更するのに対し、Strategyパターンでは移譲を利用してプログラム動作を変更する。

2010年4月30日金曜日

C#始めました

研究室の勉強会を通じてC#を勉強することにしました。1ヶ月前に勉強会が始まりましたが、本格的にC#でコーディングしたのは今日が初めて。


とりあえず、今までやってきたJavaやActionScriptなどとの違いを分かった分だけ列挙すると



  • コンソール出力はConsole.WriteLine();
  • しかも、第1引数の文字列中に"{0}"と書いておくと、第2引数の値がバインドされる(printfと同様の使い方ができる。)"{1}"と書けば、第3引数の値がバインド
  • メソッド名はアッパーキャメルで定義。プロパティもアッパーキャメル
  • インターフェース名は一番先頭にIをつける。
  • 静的クラスとは、静的メンバ、静的メソッドのみを定義したクラスのこと
  • 特に、class宣言のときにstaticキーワードをつけるとインスタンス化を防げる(privateであるデフォルトコンストラクタを用意しなくてよい)
  • 静的コンストラクタとは、静的メンバ、静的メソッドやそのコンストラクタのあるクラスが初めてインスタンス化されるとき「のみ」に実行されるコンストラクタ。静的な値の初期化を行いたいときに利用。コンストラクタ宣言の前にstaticをつける。Javaで言うところのstaticイニシャライザと同じ使い方


というくらいだろうか

C#を勉強しつつ、Silverlightもマスターしてしまおう(`・ω・´)

2010年4月25日日曜日

Adapterパターン

Adapterパターンとは、提供されてるものを必要な形に適合する(Adapter)するように変換するパターンのことです。

例えば、提供する側をAdapteeクラス、ターゲットをTargetクラス、ターゲットに適合するように変換するクラスをAdapterクラスとすると、Adapterクラスは例としては
public class Adapter extends Adaptee implements Target {
    ・・・
    @override
    public String getValue() {
        // Adapteeクラスで用意されているメソッドを呼び、
        // "value: "というprefixをつけて返す。
        return "value: " + getSampleValue();
    }
    ・・・
}

のようになります。上の例はTargetクラスをimplement、Adapteeクラスを継承した形ですが、

public class Adapter extends Target {
    private Adaptee adaptee;
    ・・・
    public String getValue() {
        // Adapteeクラスで用意されているメソッドを呼び、
        // "value: "というprefixをつけて返す。
        return "value: " + adaptee.getSampleValue();
    }
  ・・・
}

のように、Targetクラスを継承して,Adapteeクラスに処理を移譲する形でも実装できます。

関連パターン
Bridgeパターン異なるクラス同士を結びつけるためのパターン。これも橋渡し役と言えそう
Decoratorパターン中身のインターフェースを変えずに作るのがDecoratorパターンで、異なるインターフェースをつなぐのがAdapterパターン

Iteratorパターン

Iteratorパターンとは、集合の中から要素を1つずつ数える(取り出す)パターンである。

要素を1つずつ取り出したいときは、集合(配列でも何でも良い)から直接for文などで処理を書くことがあるが、Iteratorを用意することでこの処理をIteratorに任せることができる。そして後はIteratorで用意されるメソッド(大体はnext()やhasNext())を利用するだけで良いので,集合クラスの実装を意識しなくて済むという利点がある。

集合クラスを利用する側において、直接for文を利用した場合は
// SampleAggregateクラスはSampleクラスのオブジェクトを要素として、それを複数個持つクラス
Sample[] samples = sampleAggregate.getArray(); // 集合クラスが持つ配列を取得
for (int i = 0; i < samples.length; i++) {
    ・・・
}
となるがこの場合だと、

  • 自分で数えないといけない
  • 配列以外の集合(例えばArrayList)に切り替わった場合、利用する側も修正する必要がある 

というデメリットがある。
Iteratorの場合は
Iterator itr = sampleAggregate.iterator();
while (itr.hasNext()) {
    sample = (Sample) itr.next();
    ・・・
} 
となり、上記2つのでメリットが克服できる。(もちろん、要素の管理方法が配列からArrayListに変わった場合はIteratorクラスは修正する必要があるが、集合クラスを利用する側は修正の必要がない)

 関連パターン:
「Visitorパターン」(勉強中)
Compositeパターン」再帰的な構造を取っているパターンなので、これにIteratorパターンを適用するのは難しい。
「Factory Methodパターン」 Iteratorインスタンス生成にFactory Methodパターンが使われることがある。

※気づいた点
この本のサンプルプログラムでは、hasNext()を利用せずにずっとnext()を使っていると、「ArrayIndexOutOfBoundsException」が発生し、「インデックスが範囲外である」ことを教えてくれるが、それよりも「NoSuchElementException(要素がありません)」の方が分かりやすいんじゃないかな・・・実際、Java APIのjava.util.Iteratorを見ると、後者の例外を投げてくれます。

 参考URL:Iterator(Java Platform SE 6)

デザインパターンの勉強始めました

より良いクラス設計ができるようにと思い,結城浩さんの「Java言語で学ぶ デザインパターン入門」を使って勉強することにしました。

デザインパターンとは、

  • GoFによって整理されたプログラミングのパターン
  • 利用することで,開発者たちに有益で豊かな語彙を与え、互いの意思疎通を容易にする
  • 再利用しやすく,機能拡張しやすいソフトウェアを作るための有益な技法

です。

去年に研究室でデザインパターン勉強会をやっていたそうですが、社会人の俺には無理な平日に実施しており参加できなかったので,独学でやることにしますた(´・ω・`)

2010年3月7日日曜日

[Eclipse]Eclipse3.5.2本体&プラグインインストール手順

個人的なメモです。
1. Eclipseダウンロード
Eclipse Downloadsから適切なEclipseをダウンロード
今回は「Eclipse IDE for Java EE Developers」にした。

2. 解凍
今回は「C:\eclipse\eclipse 3.5.2」にした。
解凍したらまさかC:\eclipse\eclipse 3.5.2\eclipseになっていましたなんてないよね・・・

3. 日本語化プラグインダウンロード
Pleiades - Eclipse プラグイン日本語化プラグインから、「1.3.1」をダウンロード

4. 解凍
解凍してできたファイルやディレクトリをC:\eclipse\eclipse 3.5.2の下に入れる。プラグインでupdate-siteを使わない場合は、dropinsに入れるのが望ましいが、後で日本語化プラグインをはずすなんて考えられないので、直接入れる。

5. eclipse 3.5.2のフォルダにあるeclipse.ini編集
以下を一番下に追記

-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar

6. Eclipse起動
解凍したPleiadesフォルダの中に入っている「eclipse.exe -clean.cmd」でEclipseを起動する。このファイルはcleanオプションをつけてEclipseを起動するバッチファイルである。3.5の場合、プラグインを手動で入れた後はコマンドプロンプト上で

「prompt>eclipse.exe -clean」

のようにcleanオプションを入れないとプラグインが認識しないからである。

7. スプラッシュ画面変更
eclipse.iniで、下記を削除する。


-showsplash org.eclipse.platform






変更前






変更後



変更後の方が個人的には好きです。
8. プラグインインストール
何を入れるかは時と場合によるが、これくらいは入っていてもいいかと
  • EasyExplorer パッケージエクスプローラにあるフォルダをエクスプローラで表示してくれる
  • FindBugs Javaのソースコードからバグを検出してくれる
  • CheckStyle Javaの静的検査チェックツール。命名やスタイルなどの間違いを指摘
  • djUnit Javaのテストドライバ作成ツールjUnit(元から入っている)に対して、カバレッジなどの測定をやってくれる
  • Tomcat プラグイン Tomcatを使う場合は必須
  • Subversive ソースコードをSVNで管理したい場合には必須
あとはご自由に

2010年3月6日土曜日

フェンスポストエラー

あまり聞いたことのない言葉だったのでメモ



フェンスポストエラーとは、区切りの個数と長さの関係による間違いで起こるエラーのことです。
例えば、「10mのフェンスを、1mおきに柱を置いて作りたい場合、柱は何本必要ですか?」と聞いたときに、「10本」と答えてしまう場合ですね。本当は「11本」ですね




テスト関連の書物なら書いてあるのかしら

2010年1月16日土曜日

[php]文字化け対策メモ

別にphpを勉強する気は毛頭ないが、今勉強してるjavascript(というかAjax)でちょっと触るので、メモメモ


php.iniの設定に関しては以下のリンクを参考にする。
PHPの文字化け - 5つの誤解と5つの対策」http://memo.xight.org/2007-02-14-1

あと、Eclipseで作業してるときはphpファイルの文字コードを予め変えておく。phpファイルを右クリックし、プロパティを開いて「テキスト・ファイル・エンコード」をとりあえずUTF-8にしておくといい