設計やプログラミングを行う上で、覚えておいたほうがいいことなどをメモしておこうと思います。意見などありましたら、コメント等でご連絡ください。随時、更新予定です。

適用、引用による効能は自己責任でお願いします。

インデックス

ノウハウ一覧

if文の構造を考える

if - then - else の構造は、同等の重要さを持つ条件を並べるべき。特殊な条件の場合はガード節を用いて、特殊な条件であることが分かるようにする。つまり条件の重み付けを行うこと。

if (特殊な条件) {    /* ガード節 */
    // 処理内容 
    return 
} 
 
if (普通の条件1) { 
    // 処理1 
} 
else if (普通の条件2) { 
    // 処理2 
} 
else {  
    // その他の処理 
}

実装の継承とインターフェイスの継承

継承には、実装の継承とインターフェイスの継承とがある。実装の継承とは、Javaでいう extends を使う方法である。インターフェイスの継承とはJavaでいう implements を使う方法である。

使い分けるルールとしては

  1. クラスが「もの」や「こと」の種類を表している場合は実装の継承
  2. サービス、機能を継承する場合はインターフェイスの継承

[参考]

エラーメッセージには対処法を表示する

エラーメッセージの表示には 対処法 を書くようにする。例えば、「意図しない入力です。」よりも「生年月日には数値を入力してください。」のようにしたり、「現在、要求を受理できませんでした。」よりも可能であれば「3時間以内に復帰する予定です。」のようにしたほうがよい。

デザインパターンの考え方

デザインパターンは、ロール(役割)の相互作用を表している。相互作用におけるロール(役割)は、抽象クラスで定義します。

ロールの考え方を突き詰めていくと、「役割場(やくわりば)とその重ね合わせによるシステムの合成」という考え方に行き着きます。

アプリケーションサービスレイヤーの設計方法

ソフトウェアアーキテクチャを設計する場合、サービスレイヤーのコンポーネントを、「チャネルサービス」、「ユースケースサービス」、「汎用サービス」の3段階に分けると良い。

チャネルサービスは、コンポーネントのクライアントに対して開かれるインターフェースを定義する段階です。HTTPクライアントやSOAPクライアントに対するインターフェース等を定義します。

ユースケースサービスは、ユースケース特有のロジックを定義する段階です。

汎用サービスは、共通のロジック例えばログの出力や帳票出力などを定義する段階です。

チャネルサービス、ユースケースサービス、汎用サービスはそれぞれ下に依存します。

[参考]

サーブレットコンテキスト名はプログラムから取得するべし

JSPでリンクでサーブレットに飛ばす場合に、サーブレットコンテキスト名を付けなければならない場合がある。このとき、コンテキスト名をべた書きしてしまうと、コンテキスト名が変更になった場合にすべてのJSPを変更しなければならない。

<%= request.getContextPath() %> と書くことで、コンテキスト名が取得できるので、JSPではできるだけこの方法でコンテキスト名を取得するようにする。

JBuilderでカスタムserver.xmlを使う方法

JBuilderでTomcatを使う場合、server.xmlが自動で生成され、サーバーをシャットダウンすると削除されてしまいます。カスタムserver.xmlを作るには、この自動で生成されたserver.xmlの2行目にあるコメント

<!--This comment marks this file as generated, so it may be deleted and regenerated at any time. To preserve manual changes to this file, delete this comment.-->

を削除すればよいとのこと。

[参考]

コメントは道路標識の警告のように使う

プログラムに記述するコメントは、道路標識の警告(例:この先急カーブ)のように使う。コメントが多いプログラムは、そこらじゅうに注意書きがある本のように読みにくいもの。

できるだけわかりやすく書き、コメントは道路で突然の急カーブを警告するためだけに用いられる矢印標識のように使う。

プログラムは、人々がそれを読むために書かれるべきである。たまたま、それが計算機(コンパイラ)で実行できるにすぎない。

add, set 系のメソッドの戻り値はvoid よりも 受け取ったオブジェクト

add, set 系のメソッドの戻り値は void よりも、受け取ったオブジェクト(this) を返すようにすると、メソッドチェーンが行いやすい。特にBuilderクラスはこの恩恵が受けやすい。

Processor proc = new ProcessorBuilder()
                     .addOption("hoge")
                     .addOption("bar")
                     .setChild(ChildClass.class)

Webアプリケーション内で使われるビジネスロジックはスレッドセーフにする必要がある

Webアプリケーションはリクエストをスレッドで処理するようになっています。そのため、マルチスレッドを意識してプログラミングを行わなければなりません。

ビジネスロジック層のクラスにおいても、実装はマルチスレッドを意識しなければなりません。特に、アプリケーションレベルで共有されるオブジェクトや、セッションに格納されるオブジェクトは特に意識しなければなりません

セッションに格納されるオブジェクトをなぜスレッドセーフにしなければならないのか?それは、同じユーザセッションを持つスレッドが複数存在する可能性があるからです。Submitボタンを二度押された場合、リクエストが二度発行されることになります。このとき、同一セッションIDを持つスレッドが複数存在することになります。

Webアプリケーションはスレッドを意識するする必要がある

Webアプリケーションと言うのは、いろんなところに注意しなければなりません。マルチスレッドもしかり、セキュリティもしかりです。マルチスレッドプログラミングをちゃんと勉強しておく必要がありそうです。

[JSF]<h:commandLink>は <h:form>タグの中に書く

JSFでリンクを表現する場合、 <h:outputLink> と <h:commandLink> で表現できます。この二つの違いは前者は単純なリンクを表現するのに対して、後者はコマンドを発行するために JavaScript を使うものです。

<h:commandLink>を使う場合は <h:form>タグに囲まれるように書く必要があります。

outputLink と commandLink の使い分けは、JSF以外のページに遷移する場合は outputLink。同じアプリケーション内のJSFに遷移するときは commandLink を使うようです。

[JSF] actionListenerとactionの使い分け

アクションリスナーはUIComponent に対して処理を行うのに都合がよい。逆に、アクションは、戻り値でページ遷移を制御できるので、ページ処理が発生するビジネスロジックを記述するのに都合がよい。

環境に依存するものは、引数で受け取る

リソースや、ファイルオブジェクト、入出力ストリームなどの環境に依存するオブジェクトは、メソッドの引数で受け取るようにする。

private String[] parseFile(File file) throws Exception;
private String[] parseXML(InputStream is) throws Exception; 

参考

  • 良いプログラミングを行うためのバイブル(超おすすめ)
  • リファクタリング関係の情報はここから