asaのブログ

プログラミングの勉強まとめ

単体テストについて

 本を読んだり、サイトを参考にしていると未だにわからない単語がほいほいと出てきます。それらを1個1個つぶしていこうと思います。そういうわけで、今日はまず単体テストを取り上げようと思います。

 

 単体テスト

 引数のデータの組み合わせ計算結果が正しいか、DBに正しいデータが登録されるか、例外が発生した際の振舞いが正しいかを見ます。

 

 要するにある大きな機能が存在して、それが相互に依存関係にあるときに、それらを分離して一つ一つの機能単位で正しく動くかを見ていくということだと理解しました。具体的には書いたメソッド(単体)がきちんとした結果を返すか、条件分岐を正しく通るかということを確かめればよいようです。

 

 まず、テストを行う際、機能単体を切り出すために、それを呼び出すためのコードであるドライバーと、テストコードが呼び出すコードを代替するスタブを作る必要があります。

 

 またテストのポイントとしては、テストはブラックボックスとホワイトボックスの観点から行われます。ブラックボックスは、入力値に対して出力値が正しく出力されるかを見るテストです。ホワイトボックスは、条件分岐などが正しく行われているかのメソッドの中身を確認するテストです。

 

 ブラックテストで流す値は境界値、固定値、異常値です。境界値は流す予定の値の最大値、最小値です。固定値はminとmaxの間の値です。異常値はnullやブランク、半角/全角スペース、0などです。他には最大、最小値の外の値、違う型の値などです。

 

 ホワイトボックスでは、条件分岐などのパスの一覧を上げ、それを一つ一つつぶしていくこと機能の安定性を保証します。

 

 これらのテストは行った都度、実施した内容をまとめおくことで確認漏れを防ぐことができます。

 

 またテストを自動化するツールとしてJavaにはJUnitが存在します。JUnitの基本的な使い方については最後のサイトが一番参考になりました。

 

 以下参考にさせていただいたサイト

qiita.com

www.infiniteloop.co.jp

www.techmatrix.co.jp

tong-chang.hatenablog.com

gihyo.jp

アップローダの作成(サーバーサイド編終了)

 サーバーサイド編終わりました。約1ヶ月に渡ってあの分厚い参考書をバッグに入れて持ち運んでいた時期が懐かしく思えます。

 

 いろいろとコードを書きましたが、とりあえず使えそうなものを紹介しようと思います。今回はクライエント側にあるファイルをサーバーにアップロードするアップローダーを説明します。

 

 参考書はいつものこちらの本です。ついに見納めです。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

 

 アップローダーの概要

 ここでは外部ライブラリのCommonsFileUploadを使用しています。ファイルのアップロードの流れは、アップロードのための前準備、アップロードファイルの取得、アップロードファイルの保存の3段階で進みます。

 

 アップロードの前準備

 まず、アップロードの前準備をします。アップロードを行うクラスはServletFileUploadクラスの役割です。なのでまず最初にこのクラスのインスタンスuploadを作成することを頭においておきます。

 

 ServletFileUploadクラスのコンストラクタはDiskFileItemFactoryを要求します。そこでクラスのインスタンスfactoryを作ります。DiskFileItemFactoryはその名のとおり、アップロードファイルをいろいろと加工して扱いやすくするセッタメソッドが存在します。作成したインスタンスからメソッドを呼び出して最低限の設定をしておきます。

 

 アップロードファイルのいろいろな扱いをこうしてfactoryインスタンスに詰め込んで、これをuploadインスタンスに渡します。こうして無事にアップロードの前準備が終わります。

 

 アップロードファイルの取得

 さて、そうしてアップロードファイルがPOSTされると、それはrequestオブジェクトに入れ込まれて処理に回ってきます。この中には目的のアップロードファイルに混じっていろいろなオブジェクトが混じっています。

 

 まずはそれをまとめて、Listに入れ込みます。その役割はparseRequestメソッドです。requestオブジェクトを渡すと、FileItemオブジェクトのリストで返してくれます。

 

 目的のファイルをリストから見つけるためにIteratorをつけます。IteratorのメソッドhasNextを使ってfalseを返すまでリストの中を探索していきます。あとファイルであればtrueなりfalseを返すメソッドがあったらいいなと思いますね。それがisFormFieldメソッドです。テキストであればtrueを返すので、falseの場合にはファイルを保存する処理を行います。

 

 アップロードファイルの保存

 目的のファイルが見つかったところで、まずパス名を取得します。パス名がなかったりnullだったりしなければ保存処理に移ります。次にFileオブジェクトを作って、getNameでファイル名だけ取得します。保存したいpathはweb.xmlであらかじめ記述しているのでpath+ファイル名で指定したpathにファイルをwriteメソッドで書き込み(保存)します。

 

 コード

gist664621a8d54d0b7d5f765a8073be5aa3

 

gist0514f59aaf9a287e331f443855c1450d

 

gist1e183ff6f12d186c48bf30df17b242e5

 

終わり!

 

 

サーブレット・JavaBeans・JSPの連携

 MVCモデルを元にサーブレット・JavaBeans・JSPを連携して、BMIを計算するWebページをつくります。参考書はいつもお世話になっている下の本です。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

  MVCモデル

 最初にMVCモデルについてまとめます。動的なWebページでは、クライエントから入力を受けて、その入力を処理して、結果を再びクライエントに返すという作業の繰り返しです。

 

 この作業をModel、View、Controllerに分けて考えるのがMVCモデルです。まず分かりやすいViewから説明します。Viewはクライエントが直接目を触れる入力と出力の部分を指します。入力フォームと、返ってきた結果を出力する出力ページがViewです。次にControllerですが、Controllerでは入力値を受け、それをどう処理して、どこに返すかという機能を担っています。具体的な処理の機能についてはModelで実装されます。

 

 レストランを例にとるとより分かりやすいです。お客さんが入ってきて、ウェイター・ウェイトレスが注文を聞きます。ウェイター・ウェイトレスはオーダーを料理長に伝えます。料理長は専ら厨房の指揮をとっているとして、あれをこうしてこれを作って、あそこに置いておいてという指示をコックに伝えます。コックはそれを作って、言われた場所においておきます。するとウェイター・ウェイトレスはそれを受け取って、お客さんに料理が届きます。このレストランの例えで考えてみるのが自分にとって一番しっくり来ました。

 

 BMI計算機

 身長と体重を入力することでBMIを返すWebページを作ります。bmiBeans.jspを入力ページ、bmiBeans_result.jspを出力ページとします。ControllerにBmiBeansServlet.javaをおき、ModelにBmi.javaをおいて構成します。

 

 コードは下の通りです。なお、デプロイメントディスクリプタにはNetBeansにより自動でサーブレットが登録されます。

 

gist0ff38b4141cb7570e58baec3aa994c7b

 

gist4fdcecccd289095c837b4fa2c95efbf7

 

gist4f5c5b23dc030dcbc94d0189f0eeef9c

 

gisteedd7b5cf1bef4f2aca99b2b94b26b2c

 

タグライブラリまとめ2

 タグライブラリまとめの続きです。前回はJavaの基本的な制御構文を代替するCoreライブラリと、データベースを取り扱うDatabaseライブラリをやりました。今回は、日付や数値、メッセージの整形を行うi18nライブラリと、Stringクラスを取り扱うFunctionライブラリをやって、JSTLを終えます。

独習Javaサーバサイド編

独習Javaサーバサイド編

 

  i18nタグライブラリ

 さらっとコードだけ載せておきます。

gist6893251a052a65b33ccfaba616e372f3

 

 Functionタグライブラリ

 おなじくさらりとコードだけ載せておきます。

gist3809c692312c4a1b6e1a8a5c8319c036

 

 はい。これでようやくサーブレット入ります。

 

デザインパターンまとめ2(お絵かきソフト)

 前回からの続きです。下の参考書の22章でお絵かきソフトを扱っていたので詳しくやります。自分自身絵を描いているのと、pixivSketchが素晴らしかったので、こうした情報を参考にお絵かきアプリを作っていきます。

 

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

 

  

 Commandパターン

 ある処理を行ったときに、処理の結果はオブジェクトの状態に反映されます。ただ、どういう処理をしたかという履歴は残ることがありません。Commandパターンは、処理つまり命令をクラスとして扱い、インスタンスを保存することで、仕事の履歴を管理します。仕事の履歴を管理することで、同じ命令を実行するときや、複数の命令をまとめたものを新たな命令として再利用することができます。

 

 構成

 パッケージを”命令”を扱うcommandパッケージ、描画を行う"draw"パッケージ、実行用のMainを置く無名のパッケージに分けて作ります。

 

 Commandパッケージ

 このパッケージでは”命令”を扱うインタフェースとクラスを保存します。漠然とした命令をCommandインターフェースで扱い、まとまった複数の命令をMacroCommandクラスで表現します。

 

 Commandインターフェース 

gist1320acacecfc08a99cb14beed949cca2

 Commandインターフェースでは、単に命令を実行するという命令を表現するにとどめます。具体的な処理は実装クラスに記述します。

 

 MacroCommandクラス

gist2385e6ad569a3d483479be567ed92c20

 命令の集合をコレクションフレームワークのStackで表現しています。Dequeでやる場合はpushとpollになります。

 

 MacroCommandクラスは、Commandインタフェースを実装しているので定義されたメソッド(execute)をオーバーライドします。executeメソッドでは、Iteratorインターフェースを使って繰り返し処理を行っています。nextメソッドの戻り値はObject型なのでCommandでキャストした後で、executeメソッドを呼び出して命令を実行しています。

 

 続くappend、undo、clearはStackクラスのメソッドをそのまま利用しています。clearはVectorクラスからの継承されたメソッドで、全ての要素を削除します。

 

 Drawerパッケージ

 commandパッケージでは、命令と命令の集合、あと必要なメソッドを定義して終わりました。Drawerパッケージでは描画を表現します。

 

 DrawCommandクラス

gist382a7ccf6b63928231c1871b9bc00fe4

 このクラスは、Commandインターフェースを実装しています。漠然とした命令から、描画するものを描く命令へと降りています。Commndインタフェースを実装しているので、MacroCommandクラスへオブジェクトを渡すことが出来ます。

 

 Drawableは後で記載するDrawableインタフェースのことです。実際にはDrawableインタフェースを実装したクラスのインスタンスが渡されます。Pointはxとyの2値を格納するクラスです。描画場所を表しています。

 

 コンストラクタに先の2つのインスタンスを渡して初期化します。また、Commandクラスのexecuteをオーバーライドして、Drawab leクラスを実装したクラスのインスタンスからdrawメソッドを呼び出しています。

 

 Drawableインターフェース

gist62ca63355f0899f62281f751fe032e79

 何かを描くという処理を表したインターフェースです。抽象メソッドのdrawが定義されています。これを実装したクラスに具体的処理を任せます。

 

 DrawCanvasクラス  

gistd543b97f863f2b261677640c909705f5

 Canvasをextendsして、Drawableを実装したクラスです。フィールドで色、描画する点の半径、処理の履歴を持たせています。コンストラクタには描画全体の高さと幅、処理の履歴を渡して初期化します。

 

 Canvasを拡張したのは、paintメソッドをオーバーライドするためで、このメソッドはGraphicsインスタンスを引数に、履歴に保存された命令を実行します。

 

 また、Drawableインターフェースを実装しているので、drawメソッドをオーバーライドしています。Graphicsインスタンスを作成するのに、このCanvasコンポーネントを利用しています。あえて書くとthis.getGraphics()でしょうか。

 

 後はGraphicsクラスのメソッドを利用して色と描画範囲を指定しています。fillOvalは1、2番目の引数が描画する位置を表し、残りの引数が描画する大きさを表しています。

 

 Mainクラス

gist76a43fcae23469dbef1a6ad64466f769

 実行用のクラスです。なんだか一番複雑に感じました。

 JavaGUIを実現する場合、AWTとSwing、JavaFXがあります。今はJavaFXがあるので、あえてSwingで実現させる必要はないのかもしれませんが、参考書どおり行きます。

 

 Swingでは大元になるフレームにぺたぺたと部品を貼り付けていくことでGUIを構成していきます。Frameから部品を貼り付けるためには、getContentPaneで部品を載せるコンテナを取得します。

 

 今回そのコンテナに貼り付けるのは、mainBox、ボタンを置くためのButtonBox、そして描画を行うためのcanvasです。ButtonBoxはBoxLayoutを横軸にすることで、横にボタンを置くことができます。またmainBoxは縦軸に設定して縦に部品を置くようにしています。

 

 フィールドでは、履歴と領域、消去ボタンを持たせています。コンストラクタにはtitleを渡し、スーパークラスであるJFrameのコンストラクタを呼び出しています。イベント発生時のために、それぞれのコンポーネントに対応するリスナーを登録します。レイアウトの設定は上の通りです。

 

 消去ボタンが押された際には、イベントがactionPerformedメソッドに渡され、履歴が消去され、canvasが再描画されます。またマウスがドラッグされた場合には、イベントはmouseDraggedメソッドに渡り、命令が作成、履歴登録されてすぐに実行されています。後はウィンドウが閉じられると実行終了するためにexitだけ実装されています。

 

 空のメソッドはそれぞれ、リスナーを実装したためにオーバーライドする必要があるので書かれています。

 

 後はmainで実行すると、簡単なお絵かきソフトが起動します。

 

 

デザインパターンまとめ1

 デザインパターン(下の参考書)のコードが、とりあえず打ち終わったので復習を兼ねてまとめていきます。全部で23パターンあるので、全体をさらっとまとめて(一言程度)、22章だけ次で詳しくやろうと思います(お絵かきソフトを扱っているので)。

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

 

 1.Iteratorパターン

  数え上げを行うときのパターン。何かの集合からオブジェクトを返すnextメソッドと要素が存在するか調べるhasNextメソッドが出てきます。馴染み深いので分かりやすかったです。

 2.Adapterパターン

 クラスを再利用して、別の少し違うものに適用するときに使うパターン。すでに作られたクラスがあってそれをAPIに適用させるという説明が一番しっくりきました。

 3.Template Methodパターン

 処理の枠組みをスーパークラスで定義して、具体的な処理をサブクラスで定義するパターン。処理の大枠をabstractで決めるというのは、便利ですし分かりやすいです。その後のパターンんでも、参考になりました。

    4.Factory Methodパターン

 先ほどのTemplate Methodパターンをインスタンス作成に適用したパターン。一個一個インスタンスのために記述していると分かりずらいですし、ばらばらになりがちです。よくやってしまいます。

 5.Singletonパターン

 インスタンスが1個しか作られないことを保証するパターンです。コンストラクタにprivate指定をしています。いじって欲しくないものにはprivate指定するという考え方を得られました。

 6.Prototypeパターン

 インスタンスのコピーが欲しいときに使うパターン。図形描写をコピーするのにクラスを使うより、インスタンスをコピーしたほうが早いというのには納得しました。

 7.Builderパターン

 インスタンスを組み合わせて複雑なインスタンスを組み立てるパターンです。Main側が使用されるメソッドを全部知らなくても、内部的に処理されて複雑なインスタンスが完成します。この考え方はその後の章でも見かけます。

 8.Abstract Factoryパターン

 関連する部品を組み合わせてオブジェクトを作るときに使うパターンです。特にインターフェースだけに注目して、そのインターフェースだけを使って、抽象的な製品を作るという点が大事です。

 9.Bridgeパターン

 機能の階層と、実装の階層をはっきり分けてしまうパターンです。分けた階層を橋渡しするのがこのBridgeパターンです。

 10.Strategyパターン

 アルゴリズムの切り替えを行うパターンです。戦略の切り替えをいろいろと試したいときにこのパターンは有用です。じゃんけんの手を考えるコードがありましたが、参考になりました。

 11.Compositeパターン

 入れ子を表現するパターンに当たります。中身と容器を同一視して再帰的な構造をつくるパターンです。

 12.Decoratorパターン

 元のオブジェクトにどんどん装飾を加えていって、目的にあったオブジェクトに仕上げるときに使うパターンです。飾りと中身を同一視して、インタフェースを統一しているので、「見やすい」というのが直感的な感想です。

 13.Visitorパターン

 データ構造をいろいろと処理しなければならないときに、クラスに全て書いていると、クラスが大きくなりすぎて分かりにくくなります。データ構造をあらわすクラスと、処理を分けて実装しているのがこのパターンの特徴です。

 14.Chain of Responsibilityパターン

 責任のたらいまわしという表現がとてもしっくりきます。ある要求が発生したときに、その要求を即座に決めることができるとは限りません。オブジェクトをチェーンのようにつないで、目的とするオブジェクトを決定するパターンです。

 15.Facadeパターン

 複雑に入り組んだたくさんのクラスを、窓口となるクラスに抽象化して、要求に対して入り口を一本化するパターンです。

 16.Mediatorパターン

 多数のオブジェクトを調整する必要があるときに、ここのクラスを結び付けていると記述が大変になるうえに、後で見返すのも大変になります。Mediatorという相談役を置いて、ロジックを一任させてしまうパターンです。

 17.Observerパターン

 このパターンでは、状態変化に応じてなんらかの処理をしなければならないとき、状態を観察するObserverを設けて処理を行わせます。

 18.Memetoパターン

 やり直しつまりアンドゥを行うときに使われるパターンです。インスタンスを復元する際には自由にインスタンスにアクセスする必要がありますが、その際にあちこちでそのクラスの構造に依存したコードになり、クラスの修正が困難になります。これをカプセル化の破壊といいます。このパターンはカプセル化の破壊を防ぎアンドゥを実現させます。

 19.Stateパターン

 これまで、なにか具体的なものをクラスとして表現してきましたが、このパターンでは状態そのものをクラスに表現します。クラスの切り替えによって、状態の変化を泡ラスことができます。

 20.Flyweightパターン

 メモリの使用量はほんとに悩ましい問題です。このパターンではオブジェクトを軽くすることを目的としています。出来る限りインスタンスを共有して、無駄に新しいオブジェクトの生成を行わないことで、メモリの使用量を抑えます。

 21.Proxyパターン

 処理を行うときに本人と代理人をオブジェクトとして表現します。代理人にある程度の処理を任せて、それが出来ないときには本人に切り替えて処理を行います。

 22.Commandパターン

 あるイベントが発生したときに、その出来事をインスタンスに保存します。イベントをまとめておけば、履歴としてそれを管理できますし、まとまったものを再び元に戻すのも容易なります。Commandパターンについては、次でも紹介します。

 23.Interpreterパターン

 ここでは、Java言語をInterpreter(通訳)として、ミニ言語を作成してそれをはしらせました。ただ、記憶に残るところがあまりなかったのが正直な感想です。

 

 この参考書、とても勉強になったので機会がある度に振り返っていこうと思います。コードを読んだり、書いたりしたときにパターンを見つけることが出来たら、そこは詳しく取り上げようと思います。

 

タグライブラリまとめ1

 

独習Javaサーバサイド編

独習Javaサーバサイド編

 

 この参考書タグライブラリがかなり続きます。終わるとサーブレットなので、さらっとまとめて次に進みます(進みたい)。

 タグライブラリは、Javaの複雑になりがちなロジックを要件に応じてタグ化して、ソースを簡略にしたものです。非エンジニアにも使いやすいように、緩くコードを書いてもしっかり動作します。

 

 Coreタグライブラリ

 Javaの基本的な制御構文を代替するライブラリです。

  • <c:set>・・・変数の指定 (例:String str = "Hello,world";的な感じ)
  • <c:out>・・・文字列の出力 (例:System.out.println(str); )
  • <c:if>・・・if命令
  • <c:choose>・・・switch命令
  • <c:forEach>・・・for文
  • <c:redirect>・・・そのまま。指定したページにリダイレクト
  • <c:import>・・・指定したページをインポートします。

 はい、とういうわけで書いてみました。

gist165bd5e6f193a835cabbf487a30622f2

 

 Databaseタグライブラリ

 前回までやってたDatabaseへのデータの登録・更新・検索はタグライブラリでも行うことができます。データベース連携の基本的機能を提供するライブラリです。

  • <sql:setDataSource>・・・データベース接続を確立
  • <sql:query>・・・SELECT命令の実行
  • <sql:update>・・・SELECT命令以外の実行
  • <s1l:param>・・・プレースホルダに値をセット

  そんなわけで、前回作った全データ表示をタグライブラリで書き直しました。

gist0287c2e6d3ec79fdebd1c3a2d502015c

あと2つタグライブラリ紹介して終わります。