2012年1月27日金曜日

オブジェクト指向の光と影

ソフトウェアの構成物をオブジェクトという単位で捉えるオブジェクト指向は、ブームからコモディティへとこなれてきたと思う。しかし、そこには指摘する人が少ない影の部分が存在していると感じたので、それを記しておく。

1)開発プロセスの変遷からの類推

 ウォーターフォールからアジャイルへの変化や分化などは最適化の結果と捉えている。
 地図を例にとると、平面の四角い紙に表す地図(メルカトル図法)は、一定の狭い範囲での表現としては最適であるが、地球全体にまで領域を広げると形が歪んでしまう欠点がある。逆に地球儀のアイデアを狭い範囲で忠実に実現しようとしても精度的に無意味になってしまう。
 つまり、対象とする事物や扱う方式によって最適なものは変化するということだ。
 ユニファイドプロセスなどは、ウォーターフォールのやり方を部分最適な方式として捉えており、ソフトウェア開発をモジュール化してその一部を実行する時のプロセスとして採用し、これをイテラティブ・インクリメンタルに行うこととした。
 一方アジャイル開発では、ウォーターフォール的な手法を採用する場面はもっと限定的になる。

 開発方法論は、統一(Unified)のかけ声よりも、現実に即した進展をしたと思う。それは、1つの手法ですべてを統一するのではく、状況に合わせて最適なものを採用するという方式だ。

2)分析・設計手法におけるオブジェクト指向

 ソフトウェアの世界をデータと振舞を内包した要素とその関連として捉えるオブジェクト指向は、ある領域では最適だと言えるが、無制限に一般のソフトウェアを対象に出来る訳ではない。
 オブジェクトは仮想的なモジュールとして捉え、それがデータを内包し、他のオブジェクトと関連を持つと捉えるのがOOの基本であるが、この考えはある程度の固まりとしてのソフトウェアコンポーネントやサブシステムという単位ならとてもしっくりするのであるが、細かくなってくると現実と整合しずらい部分が出てくる。
 たとえば、機能や振舞を細分化し抽象化していくと、特定のオブジェクトやそのクラスに属する限定をしないほうが扱いやすい、純粋に抽象的な機能というものも見つかり、無理やりにオブジェクトと捉えると何のデータも持たない要素となってくる。また、データの方も同様にまったく何の機能を持たせる必要性がない固まりというのも存在する。さらに、振舞に関する関連とデータに関する関連では、構造を定義しているという点では同じだが、意味合いは全く異なっており、データ同士の関連は状態を意味する一種のデータとして使われるが、振舞同士の関連が状態を意味することは通常ない。
 通常と言ったのは、振舞同士の関連に状態を持たせようと思えば出来るからであり、この「やろうと思えばできる」的な曖昧さが、OOでの分析・設計をぶれの大きなものにしてしまっているように感じる。
 異なっているのに、共通的に取扱えるから同じ用語やコンセプトで押し通されてしまうと、本当に重要な”違い”が見過ごされてしまうような気がする。

ではどうするかは、これからの検討課題とする。

2012年1月12日木曜日

OSGI:felix:bundleIDの戻し方(GFv3)

uninstallしても、bundleIDがインクリメントされてしまう。同じIDを再利用できなかと調べてみたら、以下のファイルに保存されているようだ。

osgi-cache/felix/bundle0/bundle.id

このファイルを編集して番号を戻し、以前と同じIDを使用できるようにしようと思ったのだが、単に変更しただけではだめだった。

refresh かけた => だめ
update 0 => GlassFish自体が落ちてしまった
再起動 => うまくいった

結果オーライだが、くれぐれも既存のbundleを上書きしないように注意しよう。

OSGI:bundleの不思議な挙動

OSGIのbundle(モジュール)をインストールしたところ、新しく追加したリソースが見えていないような症状となった。

[#|2012-01-11T14:49:15.740+0900|WARNING|glassfishv3.0|net.korabo.cmt.spord.svc.msg.plugin.FireSubscriberPluginWRpldChk|_ThreadID=187;_ThreadName=Thread-1;|ErrorInCheckOF:[net.korabo.cmt.spord.svc.msg.CommonMsg@152886a]
com.ibatis.sqlmap.client.SqlMapException: There is no statement named MSGACCEPTANCE_ALT.selectTsRpldByPrimaryKey in this SqlMap.
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.getMappedStatement(SqlMapExecutorDelegate.java:231)

実際のパッケージ(jar)やGlassFishV3 の domains/domain1/osgi-cache/felix/を見てもファイルは更新されているはず、、、

telnet localhost 6666 (felixの場合)でOSGIのコンソールに入って様子を見ると、、、

ps
[ 219] [Active ] [ 1] spord-controll-osgi (1.0)
[ 223] [Active ] [ 1] spord-appstarter-osgi (1.0)

inspect package requirement 223
spord-appstarter-osgi [223] imports packages:
---------------------------------------------
ibatis; version=0.0.0 -> spord-appstarter-osgi [220]
org.osgi.framework; version=1.5.0 -> org.apache.felix.framework [0]
..........

となっており、PSでは見つからない220番を参照していることになっている!?

ちなみに osgi-cache/felix/bundle220 は存在しており、MANIFESTでの定義は、

Import-Package: ibatis;resolution:=optional

となっていた。

手順としては 220番が存在していた時に unistall して、同じパッケージを新たなbundleとして install しただけ。

じつは、これだけだと変更がコミットされていなかった! 変更後に refresh をかけることが必須である。

参考:http://d.hatena.ne.jp/IkeT/20090325/1237945826

んで、推奨手順:

# 新規のみ
# install xxxxx.jar
# 更新時
stop
update file:///xxxxx.jar
# 共通
refresh
start

2011年10月19日水曜日

Windws7 に SSHサーバ(Copssh)ではまる

サービスでの起動で問題発生
最初は、FreeSSHDをインストールしたが、サービスから接続すると"cannot create child desktop" だの、"入力不可" などで断念。
次に、Copsshを入れてみたが、これはCygwinのサブセットみたいなのでコマンドの少ないbashが使用できる。これもサービス起動だとうまく動かず、、、ググっていると、「サービスで使う場合はインストール時手で管理者アカウントでやるべし」みたいなのを発見し、その通りしてみると何とか動いた。ちなみに、コントロールパネルも管理者アカウントで起動してユーザを追加しないと効果ないようだ。また、インストール後に再起動も必須の模様。

 なお、ユーザ追加の時に変なドメイン「.」を指定してしまうと、エラーが発生して2度とコンパネが起動しなくなるのは困ったものだ、、、

参考:http://www.sevenforums.com/customization/19864-ssh-windows-7-a.html

Once you download this run it as administrator and accept the default settings. It will than prompt you to all the settings you would like to use.

Once done you will need to manual setup users through the Copssh folder in the Start menu. (hint if you want to add an account that is not YOURS) just type in in over the drop down.


途中までやりかけたFreeSSHDのサービスアカウントのポリシー変更に関してはこちら、
参考:http://linlog.skepticats.com/entries/2010/10/Got_freeSSHd_mostly_working.php

I believe you have to grant the freesshd service access to create system tokens.

Run gpedit.msc (or apply group policy from the directory)

replace "sshd" with whatever account the process is running as, the default is SYSTEM

Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> User Rights Assignment

Access this computer from the network -> add sshd
Act as part of the operating system -> add sshd
Adjust memory quotas for a process -> add sshd
Allow log on locally -> add sshd
Create a token object -> add sshd
Create global objects -> add sshd
Log on as a service -> add sshd
Replace a process level token -> add sshd

Comment posted on Tuesday 29 Mar 2011 at 5:54pm
By W. Strucke

2011年9月30日金曜日

開発方法

大きな流れとしては「要件定義、分析、設計、製造、テスト、配備、運用」となるのだが、
構造化にしろ、OOにしろ、DOにしろ、いまいちしっくり来ない感じがしていた。

ベストプラクティスとしての方法を紹介するというスタンスであって、
論理的でない部分が多かったように思う。
今にして思えば、論理的に説明するための基礎が不足していたからではないだろうか?

そこで、いくつかの素案をメモしておく;

・要件定義:実現したいシステムを表現したもの(単なる要望でなく、実現基準を持つ)
・分析:モヤモヤしている要件を複数の次元に分解して詳細を明らかにしたもの
  例)業務機能、基盤機能、性能、システム把握、運用性、操作性、、、
・設計:上記の複数次元からなら定義を1つのシステムとして実現(実装、運用)できるような要素に分解し、その作成の筋道を明らかにしたもの
・製造:設計指示をもとに実行できるコードを生成し、単体レベルテストを実施する
・テスト:システム全体の要求を満たすかのテスト
・配備:実際の運用環境に適用する
・運用:

■トレーサビリティ

システム開発で分析や設計に力をいれるのは、トレーサビリティを確保するためだと思うようになった。
というのは、実際のシステム運用において、障害が発生したり拡張要求が発生した場合に大元の要件と対応する実現物(コードなど)の対応がとれないことが多く、これがシステムの理解を悪化させているのではないかと思えたからだ。トレーサブルでないシステム(これが大半だと思うが)では、システムの現状に関して信頼できる資料は実際に動作しているコードのみとなる。要件とコードの対応がつかないのでは当然である。

しかし、トレーサブルでないことがデファクトとなっているシステムをトレーサブルなものにすることができるのであろうか?これに対する構想を以下に述べる;

■現在使用可能なトレーサブル

たとえば、DBのテーブルやOOのEntity定義などはほぼ完全にトレーサブルと言える。要件として、「これ、これ、これ」と指定された項目をまとめて管理するという枠組みは非常にシンプルであり、正規化などで形式が変わってみていても上流の定義に戻すことは容易である。つまり、下記のような双方向変換が容易にできる。

データ定義 <=> モデル <=> コード

■モデリングの限界

UMLなどのモデリングでは、なんでも出来そうに思われるが、それは上記のデータ構造に関してであり、動的な側面の記述という観点からは、基本的に用意された定義だけを使っている限り意外と表現力が乏しいと感じる;

例えば、簡単は電卓の動作をUMLだけで記述することが出来るであろうか? 特にNキーロールオーバのような複数同時実行する場合の挙動を記述するのは簡単ではない;さらに、それが出来たとしても、そこから何らかの言語への変換が出来るであろうか? 既存の変換ツールは状態変化(ステート図)を対応するクラスの挙動に変換するという極めて狭い領域をカバーするものが多いと感じる(すべてを見たわけではないのだが、、、)

■代替えとしてのDSL

では、UML以外のモデリングとして何が考えられるであろうか? それはDSLだと考えている。
UMLで特定のDSLを記述することができれば間接的にUMLで表記したことにはなるが、そこにこだわる必要性を今は感じない。

例えば、機能表現に特化したDSLでシステム要件の機能部分を分析し、性能に特化したDSLでシステム性能要件と記述するという形にすれば、分析作業とは「システム要件をM次元の直交要素に分解しそれを固有のDSLで記述すること」と考えることができる。

さらに、設計は記述されたDSL要素から実現コードへのコンバータの生成(定義)と捉えることができる;
DSLをテストフレンドリにしておけば、生成されたコードをDSLを使用してそのままテストすることができ、要件が変わってDSLを書き換えたらテストまで自動で流すことができるようになる。

要件 <=> M次のDSL記述 <=> 実行コード

■開発作業の変化

DSLを中心に捉えてみると、システム開発作業は以下のような形にすることができる;

1)要件定義:聞き取りと文書化
2)DSL作成
3)コンバータ開発
4)生成、テスト
5)システムテスト

DSL作成の中でもUI部分やデータ定義などで分業できる要素があり、コンバータ部分は開発会社の強みとして自社で抱え、システムテストは人件費の安いところに外注するという工程も成り立つと思う。

そのためには、DSL =>システムテスト という生成ツールが欲しいところである。

2011年8月26日金曜日

コードレビュー

レビューの目的などをまとめてみた:
参考: http://www.ibm.com/developerworks/jp/opensource/library/j_os-codereview/#resources

■目的:
 コードが問題なく単体テストを通っていても、前提とする仕様が誤っていたり誤って解釈していれば、「誤った仕様に沿って正確に動作するコード」となり当初の目的を果たしていない。そもそも単体テストは開発者が作成するのが通常であり、誤って解釈してコーディングされていれば、単体テストも同じ過ちの上に組み立てられいて整合することになり、正しい仕様との乖離は発見できない。
 そこで第3者の目を通してのコードレビューが必要になる。コードレビューは、ソフトウェアレビュー/ソフトウェアインスペクションの一つであり、コード自体を調査することで以下のことを目指す;

障害の可能性を発見:潜在的なバグ(仕様どおりに正しく動作しなくなる可能性)など
コーディングの間違いや勘違いを発見:仕様との乖離
ユーザによる誤操作や誤解を誘発する恐れのある部分を発見:表記、操作順序、UI配置など
管理、運用上での必要データの取得漏れや不適切な保持を発見
性能やりソースに問題をもたらす恐れのある部分を発見:メモリーリーク
基盤(F/W)に対して適合しない部分の発見:認証、認可、セキュリティの迂回ルートなど
将来の保守(修正、拡張など)や移植において問題なる可能性を発見

レビューの過程を通して以下の活動も行われうるが、オプションとする;

テストケースの抜け、漏れの発見と指摘
テスト条件、テストデータの抜け、漏れ、不適切値の発見と指摘
基盤部分の改善や拡張(生産性や保守性が向上する場合)
脆弱性を持つ部分の発見(意図しない情報漏えいや悪意のある操作への対応)

以下の活動は原則として目的としない;これは基盤(アーキテクチャ)や運用環境の課題とする

システムとしてのパフォーマンスチューニング
負荷分散や可用性の向上策
リソースプランニング
秘匿情報の漏洩対策
業務妨害などの攻撃への対策
管理上のファシリティ

■レビューの観点(パースペクティブ)
レビューは種々の観点から行うことで幅広く問題点を指摘することができる;

システム利用者(ユーザ)
システム業務管理担当者
システム運用管理担当者
品質管理担当者

■前提条件:
レビュー開始時点で、ソースが以下の条件を満たしていること;

コンパイルエラーなし
FindBugやCheckStyleでの重大な問題なし
単体テストはAllGreen

■レビューに必要な資料
開発対象概要(業務ユースケース、モジュール構成、データ構成、)
プロジェクト概要(目的、方針、体制)
動作基盤概要(方式、構成、I/F仕様など)
製造要件(要件定義、要件分析、S/W設計、コード表、データ)
製造規約類(コード規約、製造指針、テンプレート、コードテーブルなど)

■レビュー体制
以下の役割で複数人が参画すること;
進行役(モデレータ、司会)
レビューア/インスペクター(問題の指摘;指摘分野を絞る場合もある)
記録係
オーガナイザ (レビュー会開催および結果活用の幹事)
作成者(オーサ、コーダー)
プレゼンター (対象コードの説明役)

■レビュー結果の活用
コードレビューを通して、この種のバグや潜在バグの下地(将来の修正や拡張時にバグを生みやすい構造)を発見して取り除いていくことで、以下の効能がある。

開発者に対して実践的トレーニングをすることになり、技能的向上が見込める
これにより、手戻りが少なくなり、品質、納期、保守性などが向上する

■典型的な指摘例
コードレベルでの指摘
1)変更不可変数の扱い
 必ず使用する変数やフィールドは初期化忘れ防止のためにも「final」宣言をする
 *不変オブジェクト(生成したら変更不可のもの:String, Integer など)はコンスタント扱いとなる
=> この場合は「static final」が定数の意味合いを強調できるので更によい
 *不変でないオブジェクトは内容を変更できる
=> フィールドの場合、フィールド定義文またはコンストラクターにて初期化する

2)変数名称
 コードが読み易く、誤解を招かないような名称と長さを保つ

3)スコープの選択
可能な限りスコープを狭くする;他のクラスからの干渉を制限でき、修正や拡張に対する影響を狭くできる;
 内部変数やサブルーチン的なメソッドは「private」
 抽象クラス(abstract)で子クラスが使用するものは「protected」(同じパッケージ内の他クラスからも使える)
 どこからも使えるよう公開する場合は「public」

■基盤部分などの共用コードに対する指摘例
1)スレッド対応
同じデータに複数のスレッドがアクセスする場合、以下の点を考慮する
 ConcurrentXXXX クラスを使用する(Java5以降)
 変数に「volatile」宣言をする
 「synchronized」で囲む:ロックの発生による性能劣化の可能性に注意

2011年8月18日木曜日

JBoss/Seam の@In がOverrideできない

@In
public void setXXX(CCC ccc){...}

のインジェクションを子クラスで
@override
@In(required = false)
public void setXXX(CCC ccc){...}

としてみたが、効果なし??