広告

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2011年01月15日

    Java総合講座 - 初心者から達人へのパスポート
                  vol.214

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


========================================================
◆ 00.お知らせ(バックナンバーの閲覧に関して)
========================================================


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:vol.xxx(xxxは番号)が振られています。
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:xxx号(xxxは番号)が振られています。
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


========================================================
◆ 01.Strutsのアプリケーション開発(プロジェクト:StrutsShop)
========================================================

さて、Strutsに関して学んでおくべき技術には、Strutsそのもの以外に、
Strutsと組み合わせて使うと有効な別の技術もあります。

今日からしばらくの間はvol.186でお約束していた注文状況を管理する機能
を作り込んでいくことにし、そのときに一緒にこれらの技術を説明して
いくことにします。


まず一つ目の技術はTilesというものです。

Tilesはそれ自体が一つのフレームワークですが、かなり簡素なフレーム
ワーク(MVC(Model/View/Controller)のうちのViewの部分だけをサポート
するフレームワーク)であるため、Strutsのような大掛かりな(MVC全体を
サポートする)フレームワークと組み合わせて使うのが望ましいのです。

そのため、Strutsには既にTilesの機能が組み込み済みになっています。
(Strutsがインストールされていれば、Tilesを新たにインストールする
必要はありません。)



皆さんはおそらくこれまでにstruts-config.xmlファイルの中に

--------------------------------------------------------
  <plug-in className="org.apache.struts.tiles.TilesPlugin">
    <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/>
    <set-property property="moduleAware" value="true"/>
  </plug-in>
--------------------------------------------------------

というコードが入っていることに気づいていたことと思います。
これが、Strutsの中でTilesを使えるようにするためのコードです。

Tilesはorg.apache.struts.tilesというパッケージで提供されているのですが、
上のコードのplug-inタグのclassName属性を見ればわかるように、このパッケージの
TilesPluginというクラスを通してStrutsに組み込まれます。

また、後ほど説明するように、Tilesに関する設定情報は通常、tiles-defs.xml
という名前のファイル(以後「Tilesの構成ファイル」と呼ぶことにする)に入れ
ることになっていますが、上記のコードのうち
    <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml"/>
というコードで、WEB-INFディレクトリー配下のtiles-defs.xmlという名前のファイル
をその構成ファイルとして使用することを指定しています。


ちなみに、上の

  <plug-in className="org.apache.struts.tiles.TilesPlugin">
    ・
    ・
  </plug-in>

のコードを指定するためには、合わせて

  <controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>

というコードも必要になりますが、これもstruts-config.xmlファイルの中に
既に記述されていますね。
このTilesRequestProcessorというのは、Tiles用にStrutsの構成定義を拡張するため
のものです。



Tilesの詳細については

http://struts.apache.org/1.x/struts-tiles/index.html

などに書かれているので、必要な人はそれを見ていただくことにして、
ここではTilesの基本的な使い方をサンプル・プログラミングを通して
説明していきます。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


まず、Tilesがそもそも何をするものなのかについてお話しておきましょう。


Tilesの元もとの意味は、タイル(tile)(の複数形)です。
タイルというのは、建築物の壁などに貼る(日本では主に浴室の壁などに貼られ
ている)あのタイルです。

タイルというものは予め別の場所で作っておいて(というか普通は大量生産された
既製品のタイルを購入して)、それらを現場に持ってきて壁に貼り付けるという
やり方をしますね。

このイメージがWebページの開発の現場にも生かされます。

Webページというと、普通は各ページを同じパターンの構成にして統一性を
持たせることが多いですね。

たとえば、どのページも上のほうにはメニューがあり、下のほうにはCopyrightなど
の決まった文言があり、これらのメニューや文言はすべてのページで同じで、中央の
本体の部分だけが各ページごとに異なる、といった統一されたパターンになっている
ことが多いです。

このとき、メニューを含んだ上のほうの部分をヘッダーと呼び、Copyrightなどの文言
を含んだ下のほうの部分をフッターと呼ぶことにすると、ヘッダーの部分とフッター
の部分と本体の部分を予め別の場所で作っておいて、Webページにそれらを貼り付ける
というやり方をすれば、各ページごとに毎回同じヘッダー部分やフッター部分を記述
するよりも生産性を上げることができます。これは、言わばタイルを貼り付けてページ
を作るようなイメージでとらえることができます。

このやり方を容易にするために作られたのがTilesです。

Tilesを使うと、ヘッダー部分やフッター部分や本体部分をそれぞれ別々のタイル
として別途作成しておき、それらのタイルを統一されたレイアウトでWebページに
貼り付けるというやり方でWebページを開発できます。
(ヘッダー部分やフッター部分や本体部分というのは、あくまで例であり、Webページ
をどのようなタイルに分割するかは開発者の自由です。)

言わばTilesは、Webページをタイルという複数の部品から構成される構造にして、
そのレイアウトと部品(タイル)の開発をサポートすることによって、Webページの
開発の生産性と保守性を向上するツールです。
(ただし、Webページを複数の部品(タイル)に分割するというやり方は、ページ数
が少ない場合には、かえって生産性を落とす要因にもなります。あくまで大規模な
Webアプリケーションを開発するときの効果を上げるものです。)

このとき、たとえばヘッダー部分には、メニューのようなすべてのページで共通なもの
の他に、ページのタイトル文字のようなページごとに異なる情報も含む場合もあります
が、Tilesのタイルでは、ほとんど同じだけど一部ページごとに異なる情報を含ませる
ということも可能だし、すべてページごとに異なる情報を持たせるということも可能
です。



では、これから実際にアプリケーションを作りながら、Tilesの使い方を学んで
いきましょう。


◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


(次回に続く)



========================================================
◆ 02.Javaのヒント&コツ(Java Hints and Tips):配列のコピー
========================================================

[今回から、ときどき思いついたときに、Javaのヒント&コツ集
(Hints and Tips)を書いていきます。]


配列のコピー(複製)をしたいとき、コピー元の配列の変数を
コピー先の配列の変数に代入したのではダメだということは
既に学びましたね。
(なぜなら配列は参照型だから、コピー元の配列の変数targetArray
をコピー先の配列の変数sourceArrayに代入、つまり
   targetArray = sourceArray;
を実行すると、targetArrayにはsourceArrayの配列のコピーでは
なくsourceArrayの配列そのものが代入されてしまいますから。)


ところで、その配列のコピーを実際に初級者にプログラミングさ
せると、ループを使う人が多いです。

たとえば、sourceArrayという変数名の配列からtargetArrayと
いう変数にコピーするときには

--------------------------------------------------------
      for (int i = 0; i < arrayLength; i++) {
         targetArray[i] = sourceArray[i];
      }
--------------------------------------------------------

というふうにプログラミングする人が多いです。


実は、これはSystemクラスのarraycopy()メソッドを使うとループ
を使わずに

--------------------------------------------------------
      System.arraycopy(sourceArray, 0, targetArray, 0, arrayLength);
--------------------------------------------------------

というふうに1行でプログラミングできます。しかも、こちら
のほうがはるかにパフォーマンス(処理性能)がいいのです。

例えば、次のようなプログラムをコーディングしてテストして
みて下さい。

--------------------------------------------------------
import java.util.GregorianCalendar;

public class ArrayCopyTest {

   public static void main(String[] args) {
      final int arrayLength = Integer.MAX_VALUE / 2000;
      String [] sourceArray = new String[arrayLength];
      for (int i = 0; i < arrayLength; i++) {
         sourceArray[i] = Integer.toString(i);
      }

      GregorianCalendar now;

      String [] targetArray = new String[arrayLength];
      now = new GregorianCalendar();
      long startTime = now.getTimeInMillis();
      for (int i = 0; i < arrayLength; i++) {
         targetArray[i] = sourceArray[i];
      }
      now = new GregorianCalendar();
      System.out.println("ループを使った配列のコピーの所要時間:" + (now.getTimeInMillis() - startTime) + "ミリ秒");

      String [] targetArray2 = new String[arrayLength];
      now = new GregorianCalendar();
      startTime = now.getTimeInMillis();
      System.arraycopy(sourceArray, 0, targetArray2, 0, arrayLength);
      now = new GregorianCalendar();
      System.out.println("System.arraycopy()を使った配列のコピーの所要時間:" + (now.getTimeInMillis() - startTime) + "ミリ秒");
   }

}
--------------------------------------------------------

System.arraycopy()を使ったほうがはるかに処理が速いことがわかりますね。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2011 Future Lifestyle Inc. 不許無断複製