<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Webアプリケーション</title><link>http://blogs.wankuma.com/nagise/category/1522.aspx</link><description>Webアプリケーション</description><managingEditor>凪瀬</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>凪瀬</dc:creator><title>アーキテクチャ選定ではメリットとデメリットを考える</title><link>http://blogs.wankuma.com/nagise/archive/2008/09/25/157505.aspx</link><pubDate>Thu, 25 Sep 2008 23:16:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/09/25/157505.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/157505.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/09/25/157505.aspx#Feedback</comments><slash:comments>56</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/157505.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/157505.aspx</trackback:ping><description>&lt;p&gt;アルゴリズムであるとか、アーキテクチャというのは、必ずメリットとデメリットがあります。&lt;/p&gt;

&lt;p&gt;プログラマは前提条件に合わせてメリットが活き、デメリットは表に出ないように考えアルゴリズムの選定します。アーキテクトがフレームワークやアーキテクチャを選定する時も同等です。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/kwatch/20080912/1221174865"&gt;「大規模プロジェクトではどうするか」を考えるより、「大規模にしないためにはどうするか」を考えよう&lt;/a&gt;というエントリに対し、私は&lt;a href="http://d.hatena.ne.jp/Nagise/20080915/1221462208"&gt;ネズミかゾウかではなくて、肥満か筋肉質かだろう&lt;/a&gt;と答えたわけですが、さて、では筋肉質なシステムとはどんなシステムか？という話になります。&lt;/p&gt;

&lt;p&gt;思うに、筋肉質なシステムというのは、選定したアーキテクチャなり、フレームワークなりのメリットが活き、デメリットが隠れるようになっている、そんなシステムのことではないでしょうか。&lt;/p&gt;

&lt;p&gt;だから、それが例えばCOBOLで新規開発という話だったとしても、「過去資産を活用する」というメリットが大きく、その過去資産の活用のための工数がデメリットにならず、過去資産を流用することで未来の保守の工数が嵩むといったデメリットもでない、というなら筋肉質と言えましょう。&lt;/p&gt;

&lt;p&gt;通常は、このメリット・デメリットを秤にかけて、相応にメリットが大きいという状況でないといけないわけで、&lt;a href="http://itpro.nikkeibp.co.jp/article/NEWS/20080906/314277/"&gt;東京海上の例&lt;/a&gt;では、本当にデメリットは小さいの？と疑問に思うわけです。&lt;/p&gt;

&lt;p&gt;さて、ではJavaのフレームワークの中ではすっかり枯れた技術という評判のStrutsはどうなのでしょうか？Strutsは初出が2001年と古く、近年のAJAXなどの対応を盛り込むにはマッチしないフレームワークだと私は評しています。非同期通信を伴わない、単純なWebシステムで工数を抑えて機能を量産するというなら、それなりにメリットは活きるでしょうし、デメリットは隠れるのではないかと思います。&lt;/p&gt;

&lt;p&gt;これはStrutsに限らず、PHPやRubyでの開発でも、状況によってはメリットは活きず、デメリットが表出することになります。そうしたミスマッチな選択をしたプロジェクトは、その無理から脂肪のような無駄なソースが膨らみ、デメリットだらけとなってしまうことでしょう。私が選定するならFlexなどのリッチクライアントとかかなぁ。ユーザ容貌的にそちらの方がマッチして贅肉が少なくなる気がしますね。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/157505.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>サニタイズとハンガリアンとヒューマンエラーとアスペクト指向</title><link>http://blogs.wankuma.com/nagise/archive/2008/07/06/147607.aspx</link><pubDate>Sun, 06 Jul 2008 18:34:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/07/06/147607.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/147607.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/07/06/147607.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/147607.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/147607.aspx</trackback:ping><description>&lt;p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/gallu/20080702/p2"&gt;なぜこうもレビューされてないコードを記事に書く？&lt;/a&gt;
&lt;li&gt;&lt;a href="http://blogs.wankuma.com/jitta/archive/2008/07/06/147596.aspx"&gt;「サニタイズいうな」と「ハンガリアン」&lt;/a&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;このあたりの話題は、個々のプログラマに対して「気をつけろ」と注意喚起してもなくならない話題なのですが、
その背景的な部分をば少し。&lt;/p&gt;

&lt;h4&gt;サニタイズは消毒足り得ない&lt;/h4&gt;

&lt;p&gt;sanitize = 「無害にする」、という英単語ですが、≒ sanitate 「消毒する」と紹介されることが多いですね。
でも、この消毒という比喩は&lt;strong&gt;文学的ではあるけども、技術的には問題のある比喩&lt;/strong&gt;に思います。
XSS(Cross Site Scripting、クロスサイトスクリプティング)への対処として言われることが多いですね。&lt;/p&gt;

&lt;p&gt;現実の消毒というのは、&lt;strong&gt;過剰に繰り返しても問題はなく&lt;/strong&gt;、
消毒済みのものをそのままもう一度消毒しても構わない。
なので、食品衛生的な現場では過剰なぐらいに「とりあえず消毒」というスタンスでやるわけです。&lt;/p&gt;

&lt;p&gt;これに対しプログラム上やりたいことというのは
「その場の文脈でメタ文字となる文字をエスケープすること」
(&lt;a href="http://takagi-hiromitsu.jp/diary/20060115.html"&gt;
続・「サニタイズ言うなキャンペーン」とは&lt;/a&gt;より)なわけで、
例えば対HTMLでのエスケープ処理として"&amp;"といった記号を"&amp;amp;amp;"と置き換えたりするような処理です。
これは何度でも行える「消毒」ではなく、
&lt;strong&gt;正しい場所で一度きりしか実行してはいけない「変換処理」&lt;/strong&gt;なんですよね。&lt;/p&gt;

&lt;p&gt;しかし、プログラムにおけるエスケープは消毒とは違ってあくまで「変換処理」ですから、
&lt;strong&gt;正しい場所で一度だけ、しかも漏れなく行う必要&lt;/strong&gt;がある。
そして、その場所というのが、「HTMLを出力する場所全て」という
どうやって網羅するんだよ、と言いたくなる広範な個所なのですね。&lt;/p&gt;

&lt;h4&gt;ハンガリアン記法&lt;/h4&gt;

&lt;p&gt;話は変わってハンガリアン記法。
Jittaさんの言う「型によるハンガリアン（システム ハンガリアン）使うな」の話です。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E8%A8%98%E6%B3%95"&gt;
Wikipedia&lt;/a&gt;でも見てもらうと掴めると思うのですが、"iWindowHeight"みたいに、変数名の頭に型を表現する情報を
付加すると言う記法です。&lt;/p&gt;

&lt;p&gt;この記法、Javaなどの強い型付けの言語の場合、プログラム上の「型」と変数名での「型」と冗長になるんですね。
そしてプログラムでの「型」はコンパイル動作で機械的にチェックされるので型の相違などは
検出・修正できるわけでバグとなっていつまでも残るようなことはないわけです。
そして、この冗長を常に保つことの難しさというのが欠点として挙げられていて、
メリットがないということが言われている。&lt;/p&gt;

&lt;p&gt;ハンガリアン記法を保つためには、「全ての変数を宣言する箇所で」網羅的に命名を確認する必要があります。
そしてソースコードを修正する際に「型を変更する全てのケース」で網羅的に変数の命名も直さなくてはならない。&lt;/p&gt;

&lt;h4&gt;ヒューマンエラー&lt;/h4&gt;

&lt;p&gt;例えば、小学生低学年向けの、算数のドリルをやるとしましょう。算数の足し算を延々とやるわけです。
算数の足し算ぐらいは誰でもできますね。では、&lt;strong&gt;1万問のドリルで全問正解してください&lt;/strong&gt;、と言われたら
「そんなの簡単だよ」と言えるでしょうか？&lt;/p&gt;

&lt;p&gt;これは単純で簡単な作業であっても、&lt;strong&gt;人間はなんらかの間違いを犯す&lt;/strong&gt;と言うことです。
「うっかりして」の「うっかり」なのです。&lt;/p&gt;

&lt;p&gt;あなたがチームリーダーだとしましょう。10人のメンバー全員に1万問のドリルで全問正解させるにはどうしたらいいでしょうか？
この「うっかり」に対して「気合いを入れて」とか「集中して」とか&lt;strong&gt;精神論を掲げても、
確実性が上がるわけではありません&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;俗にサニタイズと呼ばれる処理も、ハンガリアン記法も、原理を理解して対処することは難しくはない。
(いや、サニタイズ言うなキャンペーンはその原理の理解がされていないことを憂いてのキャンペーンだったか…)
算数ドリルのような話題です。ただし、その数がべらぼうで、「うっかり」間違えることもあるというものです。&lt;/p&gt;

&lt;p&gt;10人分の計算ドリルをあなたが検算することで全問正解を目指すとしましょう。
あなたは検算を間違えないでやりとおせるでしょうか？
「うっかり」検算を間違えたりしないでしょうか？
XSSの話題というのはこの&lt;strong&gt;個々は簡単な作業なのだけども、
漏れなく実施しそれを保証するのが難しい&lt;/strong&gt;というところが本題です。
そして一か所でも漏れがあるとそれでセキュリティホールになる可能性があるって言うんだから嫌になる。&lt;/p&gt;

&lt;p&gt;ハンガリアンでもやはりきっちりと網羅して行うことの難しさというのがあって&lt;strong&gt;運用に堪えない&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;こうした部分にはヒューマンエラーがするりと入り込んでくるので頭が痛い問題です。&lt;/p&gt;

&lt;h4&gt;アスペクト指向というパラダイム&lt;/h4&gt;

&lt;p&gt;拙稿&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/03/25/129472.aspx"&gt;アスペクト指向の概念&lt;/a&gt;
でおおむね解説しているわけですが、アスペクト指向では&lt;strong&gt;「全てのXXに全部YYをする」&lt;/strong&gt;という事象を扱います。
これをアスペクト、「横断的関心事」と呼ぶわけです。
上記、挙げてきた件を解決しようという試みなわけですね。&lt;/p&gt;

&lt;p&gt;このアスペクト指向というのはOOP(オブジェクト指向プログラミング)の
概念とぶつかるものではなく、相補的なものと言えます。&lt;/p&gt;

&lt;p&gt;AOP(アスペクト指向プログラミング)に対応した言語では、関数のようなものを作って、
この処理を「全てのXX」に差し挟む、ということが記述できます。
この「全てのXX」という部分にOOPでのオブジェクトなどが用いられたりするわけです。&lt;/p&gt;

&lt;p&gt;また、AOP対応言語でなくとも、設計のパラダイムとしてのアスペクト指向というのはあって、
OOPでのデザインパターンでProxyパターンというものがありますが、これは、
Proxyするオブジェクトで前後に処理を一律に差し挟むことを可能とする。
アスペクト指向的な概念に対してOOPの枠内でできる対処法のひとつなんですね。&lt;/p&gt;

&lt;p&gt;XSSに代表されるように、横断的関心事というのは人間の手作業では
ヒューマンエラーとも密接に関わって非常に対処しにくい。
AOPはプログラミングのパラダイムとしてだけではなく、開発体制をいかに構築するか
(私はこれをシステムを構築するプログラミングの仕事と類似する事項と思っています)
という部分にも応用することができる。&lt;/p&gt;

&lt;p&gt;日常の開発の中で、こうしたアスペクトを捉えて、それを一網打尽にするジョインポイントはどこか、
そう考えると見えてくるものがいろいろあるのです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/147607.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>Seaserのホットデプロイとリフレクション</title><link>http://blogs.wankuma.com/nagise/archive/2008/06/17/144134.aspx</link><pubDate>Tue, 17 Jun 2008 15:39:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/06/17/144134.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/144134.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/06/17/144134.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/144134.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/144134.aspx</trackback:ping><description>&lt;p&gt;Seaserのホットデプロイは開発向けにはなかなか便利ですが、これを使えるようにフレームワークの構成を考えるのはかなりしんどいものがあります。今回はハマったポイントとしてリフレクションを取り上げます。&lt;/p&gt;

&lt;h4&gt;Seaserのホットデプロイ&lt;/h4&gt;

&lt;p&gt;Seaserの&lt;a href="http://s2container.seasar.org/2.4/ja/DIContainer.html#SMARTdeploy"&gt;ホットデプロイ&lt;/a&gt;は
実行時に特定箇所でクラスローダを毎回新しくするというシンプルなものです。&lt;/p&gt;

&lt;p&gt;結構、割り切った作りになっているなぁというのが感想ですが、そのシンプルさと原理からいろいろと制限事項も生まれてしまう。&lt;/p&gt;

&lt;p&gt;今回、私がハマったところはフレームワーク内でリフレクションをする際に、クラスローダの違いからClassCastExceptionを出したり、NoSuchMethodExceptionを出したりしたことでした。&lt;/p&gt;

&lt;h4&gt;クラスローダの基礎知識&lt;/h4&gt;

&lt;p&gt;まず、基礎知識としてクラスローダが違う場合、同じClassでも代入互換性がありません。Classの同一性は、Class自身とそのクラスローダによって定められます。&lt;/p&gt;

&lt;p&gt;次に、クラスローダは階層構造をなしていて、まず親クラスローダにロード処理が移譲されます。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/ClassLoader.html"&gt;ClassLoader&lt;/a&gt;
&lt;blockquote&gt;
ClassLoader クラスは、委譲モデルを使ってクラスとリソースを探します。ClassLoader の各インスタンスは、関連する親クラスローダーを持ちます。クラスまたはリソースを見つけるために呼び出されると、ClassLoader インスタンスはそれ自体でクラスまたはリソースの検索を試みる前に、その検索を親クラスに委譲します。「ブートストラップクラスローダー」と呼ばれる仮想マシンの組み込みクラスローダーはそれ自体では親を持たず、ClassLoader インスタンスの親として動作します。
&lt;/blockquote&gt;
&lt;/p&gt;

&lt;p&gt;このため、親が同じである場合は、同じクラスローダ(つまるところ親)で読み込まれることで代入互換を持つことがあります。&lt;/p&gt;

&lt;h4&gt;クラスローダを跨ぐ場合のClassCastException&lt;/h4&gt;

&lt;p&gt;Seaserのホットデプロイは&lt;a href="http://s2container.seasar.org/2.4/s2-framework/ja/apidocs/org/seasar/framework/container/hotdeploy/HotdeployUtil.html"&gt;
HotdeployUtil&lt;/a&gt;のstart()とstop()の間でクラスローダが変わることで実現しています。&lt;/p&gt;

&lt;p&gt;なので、この区間の中と外ではクラスローダが異なります。そのため、戻り値のClassCastExceptionが発生することがあります。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#000000"&gt;SingletonS2ContainerFactory.init&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;S2Container&amp;nbsp;container&amp;nbsp;=&amp;nbsp;SingletonS2ContainerFactory.getContainer&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;HotdeployUtil.start&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Object&amp;nbsp;o&amp;nbsp;=&amp;nbsp;container.getComponent&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;testLogic&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;System.out.println&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;o.getClass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getClassLoader&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Hoge&amp;nbsp;hoge&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Hoge&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;o;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;HotdeployUtil.stop&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
log4j:WARN No appenders could be found for logger (org.seasar.framework.container.factory.S2ContainerFactory).&lt;br&gt;
log4j:WARN Please initialize the log4j system properly.&lt;br&gt;
org.seasar.framework.container.hotdeploy.HotdeployClassLoader@6e70c7&lt;br&gt;
Exception in thread "main" java.lang.ClassCastException: test.logic.impl.TestLogicImpl cannot be cast to test.Hoge&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at test.LoaderTest.main(LoaderTest.java:19)
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;こうした再読込をおこなうタイプのクラスローダは親クラスローダへの委譲を行わないことで実現できます。親へ委譲してしまうと読み込み済みのクラスをリフレッシュすることができません。&lt;/p&gt;

&lt;p&gt;しかし、この場合、クラスローダ越境ができなくなります。通常は、親への委譲を先に行うことで、共通して読み込まれるクラスには互換があったわけですが、クラスをロードしなおすために、親への委譲を行わないようにすると、上記例のようにClassCastExceptionとなってしまうのです。&lt;/p&gt;

&lt;h4&gt;リフレクションの際のメソッドシグネチャにも注意！&lt;/h4&gt;

&lt;p&gt;こうしたクラスローダを跨いだ箇所でリフレクションを行っていると、わかりにくいバグに遭遇することがあります。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#000000"&gt;SingletonS2ContainerFactory.init&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;S2Container&amp;nbsp;container&amp;nbsp;=&amp;nbsp;SingletonS2ContainerFactory.getContainer&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;HotdeployUtil.start&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Object&amp;nbsp;o&amp;nbsp;=&amp;nbsp;container.getComponent&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;testLogic&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Method&lt;/font&gt;&lt;font color="#000000"&gt;[]&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;ms&amp;nbsp;=&amp;nbsp;o.getClass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getMethods&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;System.out.println&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Arrays.toString&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ms&lt;/font&gt;&lt;font color="#000000"&gt;))&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;Method&amp;nbsp;m&amp;nbsp;=&amp;nbsp;o.getClass&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;.getMethod&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;setHoge&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;Hoge.&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;HotdeployUtil.stop&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
log4j:WARN No appenders could be found for logger (org.seasar.framework.container.factory.S2ContainerFactory).&lt;br&gt;
log4j:WARN Please initialize the log4j system properly.&lt;br&gt;
[&lt;strong&gt;public void test.logic.impl.TestLogicImpl.setHoge(test.Hoge)&lt;/strong&gt;, public test.Hoge test.logic.impl.TestLogicImpl.getHoge(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]&lt;br&gt;
Exception in thread "main" java.lang.NoSuchMethodException: test.logic.impl.TestLogicImpl.setHoge(test.Hoge)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.lang.Class.getMethod(Unknown Source)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at test.LoaderTest.main(LoaderTest.java:24)
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ご覧のように、setHoge(Hoge)が存在しているにも関わらず、NoSuchMethodExceptionが投げられsetHoge(Hoge)はない！と言われてしまうのです。これは、getMethod()の引数に渡すHoge.classと、読み込まれたコンポーネントのHoge.classでクラスローダが異なるためです。&lt;/p&gt;

&lt;h4&gt;開発用と割り切って全体を囲ってしまう&lt;/h4&gt;

&lt;p&gt;クラスローダの越境は非常に厄介ですので、処理の頭からお尻までまるごとクラスローダを差し替えるように使うのが無難です。&lt;/p&gt;

&lt;p&gt;Servletであれば、ホットデプロイ用の
&lt;a href="http://s2container.seasar.org/2.4/s2-framework/ja/apidocs/org/seasar/framework/container/hotdeploy/HotdeployFilter.html"&gt;HotdeployFilter&lt;/a&gt;
が用意されていますのでそちらでリクエストの全体で差し替えるほうがよいでしょうね。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/144134.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>IE上でExcelを開くとWebDAVで通信しにいく？</title><link>http://blogs.wankuma.com/nagise/archive/2008/06/09/142397.aspx</link><pubDate>Mon, 09 Jun 2008 17:29:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/06/09/142397.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/142397.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/06/09/142397.aspx#Feedback</comments><slash:comments>241</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/142397.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/142397.aspx</trackback:ping><description>&lt;p&gt;仕事で遭遇した現象なのですが、何か情報をお持ちの方はいらっしゃいませんでしょうか？&lt;/p&gt;

&lt;h4&gt;環境&lt;/h4&gt;

&lt;p&gt;クライアント&lt;ul&gt;
&lt;li&gt;Windows Vista Business SP1
&lt;li&gt;Internet Explorer 7.0
&lt;li&gt;Office2007
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;サーバ&lt;ul&gt;
&lt;li&gt;RedHat機およびWindows機で現象確認
&lt;li&gt;Tomcat 5.5
&lt;/ul&gt;&lt;/p&gt;

&lt;h4&gt;手順&lt;/h4&gt;

&lt;p&gt;&lt;ul&gt;
&lt;li&gt;サーバに拡張子".xls"のファイルを置く。
&lt;li&gt;該当ファイルをIE上から「開く」。このときローカルに保存せず、ExcelのIEプラグインで開くようにする
&lt;/ul&gt;&lt;/p&gt;

&lt;h4&gt;現象&lt;/h4&gt;

&lt;p&gt;最初のxlsファイルのリクエストに201 OK の応答をしたのち、クライアント側からWebDAVのコマンドであるPROPFINDメソッドがサーバ側に送られます。
HTTPのOPTIONSメソッドが事前に呼ばれることもありますが、キャッシュされるのか複数回試していると呼ばれなくなるようです。&lt;/p&gt;

&lt;p&gt;この際、サーバ側で認証が掛かっており、PROPFINDコマンドに401 Unauthorized 返答がされていると、Excelファイルを開くことができません。最初の201の後に、もう一度WebDAVで取り直しに行くような挙動を示します。&lt;/p&gt;

&lt;p&gt;WindowsXP, Office2003の環境下から同様にアクセスした場合は、OPTIONSメソッドがサーバに送信されることが確認できますが、PROPFINDの送信は行われないようです。WindowsXP, Office2007の環境が用意できず、そちらは確認できていません。&lt;/p&gt;

&lt;p&gt;保存してからExcelファイルを開いた場合や、Firefoxの場合ではこれらのリクエストが投げられることはありません。IE上でExcelを開く場合のみの現象です。&lt;/p&gt;

&lt;p&gt;私の手元の環境下ではxlsxファイルの場合、IEがzipファイル扱いしてIE上で開くことができませんでした。ContentTypeに"application/vnd.ms-excel"を指定しています。&lt;/p&gt;

&lt;h4&gt;何のための機能なのか？&lt;/h4&gt;

&lt;p&gt;WebDAVはMicrosoftが推しているわけですし、ExcelはOA化には貢献したけどもIT化を阻害しているということから、
そこを打開するための仕込みなのかなぁ、と漠然と考えています。&lt;/p&gt;

&lt;p&gt;WebDAVでファイルを取得しなおすことで、Excelファイルをサーバサイドで一元管理するようなシステムを作ろうと企んでいるのかなぁ？&lt;/p&gt;

&lt;p&gt;しかし、そう考えるとOffice2007形式だとそもそも開くことすらできないというのが腑に落ちません。私のマシンの設定が妙なことになっているだけという可能性も考えられますが。&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/142397.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>Webシステムの次は</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/21/138721.aspx</link><pubDate>Wed, 21 May 2008 01:07:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/21/138721.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/138721.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/21/138721.aspx#Feedback</comments><slash:comments>33</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/138721.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/138721.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/scinfaxi/20080517/1210970917"&gt;
プログラミングのジャンルと難易度(および Web プログラミング批判)&lt;/a&gt;というエントリが人気のようですね。
ざっくりした概要は「Web プログラミングの世界ってのは、全体的に程度が低いからだ。」の一文で表現されてしまいます。&lt;/p&gt;

&lt;p&gt;JavaのServlet技術を用いた業務システムをさんざんやってきた私ですが、この感覚というのはよくわかる。
Webシステムのサーバサイドの仕事の8割は経験3ヵ月の新人でやれてしまう。&lt;/p&gt;

&lt;p&gt;ただ、Webシステムは技術がまるでいらないかというと、そういうわけではなくて、物凄く幅広い知識が必要とされる側面があります。
しかし、そうした技能を持ったアーキテクトがチームにひとりいれば、大抵の問題は解決できるぐらいに、
大半は専門的な技術を必要としない。&lt;/p&gt;

&lt;p&gt;こうしたWebシステムの側面は、経済的な面で非常に有利であり、あんなにも使いにくいUIになるにも関わらず、
多くのLAN内部で使われる社内の業務システムがWebサービスとして作られることになりました。
(アプリケーションの配布の手間がないという側面も大きく評価されたのだと思いますけども)&lt;/p&gt;

&lt;h4&gt;HTMLによるGUI作成&lt;/h4&gt;

&lt;p&gt;Webの、というよりHTMLによるGUIの作成は、VisualBasicよりもある意味では易しい。
というのは、画面サイズ固定であればVBによる画面作成は煩雑ではないものの、HTMLのような自動レイアウトが容易ではないからです。
ウィンドウサイズを可変にして、サイズの変更に際してスペースを割り付けするとか考えたらやってられなくなる。
固定レイアウトであればVBが楽、可変のレイアウトであればHTMLが楽だと思います。&lt;/p&gt;

&lt;p&gt;そしてこのレイアウト、および出力データが一体となって、HTMLという文字列で扱うことができます。
古典的にperlのCGIを作る場合はこの出力HTMLを動的に書きだす文字列操作に終始しますし、
JavaだとJSPなどのテンプレートエンジンの類、つまるところ、HTMLの可変データ部分だけ虫食い状態にしたものを用意して、
そこにデータを埋め込むという方式を用いることになります。（実際には表を出力したりする場合の繰り返し処理などもある）&lt;/p&gt;

&lt;p&gt;これらの処理は、複雑な論理演算を伴わないので、アルゴリズムを考えるという技能があまりなくとも一応形になるものを作れる。
この&lt;strong&gt;敷居の低さ&lt;/strong&gt;は確かで、経験3ヵ月の新人でもできるというのは本当です。&lt;/p&gt;

&lt;p&gt;Webシステムはことさら初級者に仕事をさせてシステムを作ると言うことがされているように思います。
&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/05/10/137150.aspx"&gt;
静的オブジェクト指向は設計者が苦労を背負込むシステム&lt;/a&gt;で挙げた
「Javaの静的オブジェクト指向というのは将軍の力でもって、初心者の大隊を常勝させるための技術」というのは
特にこうしたWebシステムの開発現場では身に染みて思うところです。
まともなGUIプログラミングとかだと初級者にやらせられる仕事なんて本当に少ない。&lt;/p&gt;

&lt;h4&gt;熟練するには幅広い知識が必要とされる&lt;/h4&gt;

&lt;p&gt;大規模なWebシステムというのは、とりあえず仕事をさせるとした場合のボーダーとなる技能は低いのですが、
熟練するためには非常に幅広い知識が要求されます。&lt;/p&gt;

&lt;p&gt;&lt;ul&gt;
&lt;li&gt;HTMLの構造
&lt;li&gt;CSSの知識
&lt;li&gt;UIデザイン論
&lt;li&gt;JSPなどのテンプレートエンジンの動作原理
&lt;li&gt;タグライブラリ・EL式の知識
&lt;li&gt;JavaScriptの技能
&lt;li&gt;AJAXの動作原理
&lt;li&gt;HTTPのプロトコルについての知識
&lt;li&gt;Cookieを用いたセッション管理の仕組み
&lt;li&gt;SSLによる暗号化通信の仕組み
&lt;li&gt;Strutsなどのフレームワークを用いる場合はその動作原理
&lt;li&gt;O/Rマッピング
&lt;li&gt;DIコンテナ
&lt;li&gt;RDBMSの知識
&lt;li&gt;バックアップなど運用についての考慮
&lt;li&gt;ロードバランサなどの理解
&lt;li&gt;システムの多重化についての知識
&lt;li&gt;セキュリティに対する知識(XSSやSQLインジェクションなどのアタックへの対処など)
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;うーん。きりがない。&lt;/p&gt;

&lt;p&gt;このように個々の専門知識は相応に深く、しかもフロントエンドからバックエンドまで非常に幅広い技術が要求されるので
全体統括をするためには知識の深さと広さを兼ね備える必要がある。&lt;/p&gt;

&lt;p&gt;とりあえず作業をすると言う時の敷居の低さに対して、熟練するためのギャップが凄まじいんですね。
このあたり、慢性的な人材不足の構造的な理由かもしれません。&lt;/p&gt;

&lt;h4&gt;ポストWebシステム&lt;/h4&gt;

&lt;p&gt;Webシステムの開発をしていれば、こんなやり方はいつまでも使えるもんじゃないというのは感じていることでしょう。
ブラウザ戦争の頃の不発弾のようなデファクトスタンダードなHTMLの仕様といい、
文字コードなんぞ考慮されていないHTTPの古めかしい仕様といい、
Webシステムに精通すればするほど、不安定な土台に乗せられた危ういシステムということが見えてくる。&lt;/p&gt;

&lt;p&gt;世紀が変わった頃にはリッチクライアントと言うことが盛んに言われ始めて、
Webシステムのプアなユーザビリティはどうにかしないといけないという問題意識が高まっていきました。&lt;/p&gt;

&lt;p&gt;しかし、そもそもがブラウザというものはPCへの標準搭載がほぼ100%という土壌があります。
新しいプラットホームを作るにあたって、この壁は大きな壁となります。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://enterprise.watch.impress.co.jp/cda/infostand/2008/05/19/12944.html"&gt;
SunがJavaFXロードマップ発表&lt;/a&gt;というニュースが出ていましたが、ここにきてリッチクライアントの
プラットホームはAIR、Silverlight、JavaFXという3者に絞られてきた感があります。&lt;/p&gt;

&lt;p&gt;AdobeのAIRはFlushなどの技術がベースにあります。Flushの普及率は高く、
当blogのGoogle Analyticsでの解析を見ると97%ほどになります。&lt;/p&gt;

&lt;p&gt;Silverlightのサポート環境は調べる手立てが思いつかないのですが、当blogのGoogle Analyticsでの解析では&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;OS&lt;/th&gt;&lt;th&gt;ブラウザ&lt;/th&gt;&lt;th&gt;%&lt;/th&gt;&lt;th&gt;Silverlight&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Windows&lt;/td&gt;&lt;td&gt;Internet Explorer&lt;/td&gt;&lt;td&gt;50.34%&lt;/td&gt;&lt;td&gt;○&lt;/td&gt;&lt;/p&gt;
&lt;tr&gt;&lt;td&gt;Windows&lt;/td&gt;&lt;td&gt;Firefox&lt;/td&gt;&lt;td&gt;33.94%&lt;/td&gt;&lt;td&gt;○&lt;/td&gt;&lt;/p&gt;
&lt;tr&gt;&lt;td&gt;Windows&lt;/td&gt;&lt;td&gt;Opera&lt;/td&gt;&lt;td&gt;4.06%&lt;/td&gt;&lt;td&gt;×&lt;/td&gt;&lt;/p&gt;
&lt;tr&gt;&lt;td&gt;Macintosh&lt;/td&gt;&lt;td&gt;Firefox&lt;/td&gt;&lt;td&gt;3.54%&lt;/td&gt;&lt;td&gt;○&lt;/td&gt;&lt;/p&gt;
&lt;tr&gt;&lt;td&gt;Macintosh&lt;/td&gt;&lt;td&gt;Safari&lt;/td&gt;&lt;td&gt;3.45%&lt;/td&gt;&lt;td&gt;○&lt;/td&gt;&lt;/p&gt;
&lt;tr&gt;&lt;td&gt;Linux&lt;/td&gt;&lt;td&gt;Firefox&lt;/td&gt;&lt;td&gt;1.87%&lt;/td&gt;&lt;td&gt;×&lt;/td&gt;&lt;/p&gt;
&lt;/table&gt;

&lt;p&gt;となっていますから、サポートされる環境の91.27%より少ない程度がSilverlightが動作する可能性があります。&lt;/p&gt;

&lt;p&gt;…。というか、この数字えらく偏っていませんか？いくら技術系のblogだからってFirefoxのシェアが40%あるってどうなんだ。
OSもWindowsが89.41%でMacintoshが7.19%もあるし…。なんかあまり信用できる数字ではないですね…。
母集団が凄く偏っているような気がする。&lt;/p&gt;

&lt;p&gt;JavaFXは当然Javaベースの技術です。当blogのGoogle Analyticsでの解析ではJavaのサポートが95.41%となっています。
これからいくらか割り引いた程度が動作環境と考えられますね。&lt;/p&gt;

&lt;h4&gt;ポストWebシステムに求められるもの&lt;/h4&gt;

&lt;p&gt;前述のようにデータは怪しいものの、3者はかなりの割合で動作することが見込まれます。
移行の為の下地は整いつつあると言えるでしょう。&lt;/p&gt;

&lt;p&gt;機能的には古典的なHTMLによるWebシステムと違い、非同期通信がサポートされますし、アニメーションを伴う
かなり高度なUIを用いることができることがウリです。かなりのユーザビリティ向上が望めます。&lt;/p&gt;

&lt;p&gt;そして、これらのより高機能で複雑になったシステムを、より簡単に開発できる必要性があります。
開発費が高沸してシステム開発の敷居が上がるなんてことでは、普及は難しいでしょう。&lt;/p&gt;

&lt;p&gt;私は最近Flex/AIRのシステムを作っていたりするのですが、高度なUIが容易に作成できるようにとの
工夫が随所に見られます。このあたりの感触からも、そろそろリッチクライアント時代が来るな、という手ごたえを感じます。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/138721.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>OOPでシステム内のオブジェクトのアクセス権を管理する</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/13/137393.aspx</link><pubDate>Tue, 13 May 2008 00:22:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/13/137393.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/137393.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/13/137393.aspx#Feedback</comments><slash:comments>106</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/137393.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/137393.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/tyappi/archive/2008/05/11/137240.aspx#FeedBack"&gt;
ちゃっぴさんのblog&lt;/a&gt;に変な返答をしてしまったので、言い出しっぺの法則に基づき、方法論を考えてみました。&lt;/p&gt;

&lt;p&gt;テーマはあるWebアプリケーション(以下、システムと言う場合はアプリケーション全体を指す)があったとして、
そのシステム全体でデータに対するアクセス権を管理するためにはどうしたらよいだろうか？です。
&lt;span class="footnote"&gt;&lt;a href="#20080513f1" name="20080513fn1"&gt;*1&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;ここではOOP(オブジェクト指向)でいうObject単位での権限管理を考えます。
これらのObjectはRDBMSなどで管理されるような永続性のあるデータを想定しています。&lt;/p&gt;

&lt;h4&gt;ユーザの保有する権限の管理&lt;/h4&gt;

&lt;p&gt;例えば、システム内でプロジェクトを表現するクラスProjectがあったとして、
参照、新規、更新、削除の４つの権限を持つとしましょう。
さらに、Projectのインスタンス単体でこれらの権限が設定できるとしたならば、
ユーザ側の情報に、どのProjectに対して何権限を持つのかの情報を持たなくてはなりません。&lt;/p&gt;

&lt;p&gt;まず、権限の種別を表す列挙を用意します。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;enum&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityType&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;参照権&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;SELECT,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;登録権&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;INSERT,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;更新権&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;UPDATE,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;削除権&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;DELETE,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;そして、権限管理クラスでは対象となるオブジェクトのID・型とその権限を保持するようにします。
今回は簡単のためIDによって対象データを特定する方式をとっています。
&lt;span class="footnote"&gt;&lt;a href="#20080513f2" name="20080513fn2"&gt;*2&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;一般的なWebシステムを想定するとすれば、このユーザの権限情報はセッションに保持されます。
このオブジェクトをProjectオブジェクトを操作するたびに権限確認のために引き渡すのはデータの取り回しがあまりに大変なので
HTTPの1リクエストごとに、1つのThreadが立てられることを利用してjava.lang.ThreadLocalに
この権限情報を格納して利用するとしましょう
&lt;span class="footnote"&gt;&lt;a href="#20080513f3" name="20080513fn3"&gt;*3&lt;/a&gt;&lt;/span&gt;。
ThreadLocalはそのThread内だけをスコープとするグローバル変数のようなものとイメージしてもらうと大体当たっていると思います。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;ユーザが保持する権限を管理するクラス&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;ユーザ単位で1インスタンスが作られる。&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityManager&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;ThreadLocalでThread内をスコープとするグローバル変数を作る&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ThreadLocal&amp;lt;AuthorityManager&amp;gt;&amp;nbsp;manager&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ThreadLocal&amp;lt;AuthorityManager&amp;gt;&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;static&amp;nbsp;final&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;SESSION_KEY&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;AuthorityManager&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;セッションから権限情報を取得してThreadLocalに設定する&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;initManager&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;HttpServletRequest&amp;nbsp;request&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;HttpSession&amp;nbsp;session&amp;nbsp;=&amp;nbsp;request.getSession&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityManager&amp;nbsp;auth&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityManager&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;session.getAttribute&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;SESSION_KEY&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;manager.set&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;auth&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;ThreadLocalから権限情報を解放する&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;releseManager&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;manager.remove&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;保有権限のList&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;List&amp;lt;Tips&amp;gt;&amp;nbsp;authList;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;static&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Tips&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;対象オブジェクトのID&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;int&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;id;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;対象オブジェクトの型&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Class&amp;nbsp;objectType;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&amp;nbsp;権限タイプ&amp;nbsp;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityType&amp;nbsp;type;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;HTTPのリクエスト毎に権限情報を設定するFilter&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;
&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityInitFilter&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;implements&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Filter&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#646464"&gt;@Override&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;init&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;FilterConfig&amp;nbsp;config&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throws&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ServletException&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#646464"&gt;@Override&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;destroy&lt;/font&gt;&lt;font color="#000000"&gt;()&amp;nbsp;{}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#646464"&gt;@Override&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;doFilter&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;ServletRequest&amp;nbsp;request,&amp;nbsp;ServletResponse&amp;nbsp;response,&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;FilterChain&amp;nbsp;chain&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throws&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;IOException,&amp;nbsp;ServletException&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;権限情報をThreadLocalに設定&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;HttpServletRequest&amp;nbsp;httpRequest&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;HttpServletRequest&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;request;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityManager.initManager&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;httpRequest&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;try&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;実際のServletの処理&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;chain.doFilter&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;request,&amp;nbsp;response&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;finally&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//&amp;nbsp;権限情報をThreadLocalから解放する&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;AuthorityManager.releseManager&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;実装は省いていますが、保有データからユーザ側に保有権限のListを持たせ、権限認証の際に割符のように
操作対象となるオブジェクトと付き合わせようという思惑なのをイメージして頂けますでしょうか。&lt;/p&gt;

&lt;h4&gt;権限チェックを漏れがないように執り行う&lt;/h4&gt;

&lt;p&gt;さて、Thradにアクセス権限の情報を持ちました。
あとは対象となるProjectオブジェクトから権限のある場合のみデータが参照できるように網羅しなくてはなりません。
これは、Projectオブジェクトへのアクセス全てに対して
&lt;strong&gt;「権限チェックをし権限のないアクセスであれば例外を投げるという処理」&lt;/strong&gt;
を差し挟むということですから、AOP(アスペクト指向)で言う「横断的関心事」となります。&lt;/p&gt;

&lt;p&gt;さて、この横断的関心事ですが、AOP対応の言語であれば、言語機能を用いてウィービング
(アスペクトはWeaving、縫い付けると表現します)すればよいのでしょうが
ご承知のとおりJavaはそうではないので、なんらかの手段を講じなければなりません。&lt;/p&gt;

&lt;p&gt;ProjectオブジェクトがDIコンテナによって管理されている場合、DIコンテナのAOP機能でウィービングする手が使えるでしょう。
DIコンテナは現行の非AOPな言語でAOPを実践するための工夫と捉えることもできます。
&lt;span class="footnote"&gt;&lt;a href="#20080513f4" name="20080513fn4"&gt;*4&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;


&lt;p&gt;DIコンテナを用いていなくとも、Projectオブジェクトの取得する口が特定できるならそこを抑えてProxyを噛ませる手が使えます。
GoFデザインパターンのProxyパターンはOOPの範囲で出来るAOPへの対処法とも言えます
&lt;span class="footnote"&gt;&lt;a href="#20080513f5" name="20080513fn5"&gt;*5&lt;/a&gt;&lt;/span&gt;
&lt;span class="footnote"&gt;&lt;a href="#20080513f6" name="20080513fn6"&gt;*6&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;p&gt;場合によってはダサいですがProxyクラスさえも用意せず、Projectオブジェクトの各メソッドに
権限チェック処理を直接実装する手法を用います。
横断的関心事を分離できていないわけですが、setter、getterなんぞそもそも処理が希薄なので割りきることもできることでしょう。&lt;/p&gt;

&lt;p&gt;注意点として、Proxyパターンや、直接Projectオブジェクトに権限チェックを実装するような場合、メソッドの網羅は保証できません。
なんせ、手で個別のメソッドに対応を差し挟むわけですから。
機械的な網羅ではないのでヒューマンエラーで容易に漏れてしまいますし、なにより記述が面倒です…。
もちろん、Projectクラス自体をアーキテクト管理下に置いて、勝手に改変されないような状況である必要があります。
&lt;span class="footnote"&gt;&lt;a href="#20080513f7" name="20080513fn7"&gt;*7&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;ここまですると、開発時に参照件のないProjectオブジェクトを取得して、その情報を参照しようとした時点で
実行時例外を起こすことができるようになるわけです。
もちろん、処理効率的にはよくないわけですが、セキュリティ的にはいくらかの安全性を担保できることでしょう。&lt;/p&gt;

&lt;h4&gt;まとめ&lt;/h4&gt;

&lt;p&gt;設計パラダイムとしては、まず該当オブジェクトへの操作に対する権限チェックをアスペクトとして捉える事。
また、これをうまくウィービングして全ての参照/設定メソッドに網羅させること。&lt;/p&gt;
&lt;p&gt;そして、処理の実行体であるThreadと、操作対象であるオブジェクト
（上記例ではProjectオブジェクト）との間の権限確認を行います
&lt;span class="footnote"&gt;&lt;a href="#20080513f8" name="20080513fn8"&gt;*8&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threadを用いないでオブジェクトを操作することはできないですし、アスペクト指向によってオブジェクトに対するアクセス全てに
権限確認処理をウィービングすることで、ヒューマンエラーによる誤操作をすべてはじき出すわけです。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;また、悪意ある故意の操作に対しても処理をはじくことがある程度できます。
もっともThreadの持つ権限管理データまで改ざんされるとアウトなわけですが…。&lt;/p&gt;

&lt;p&gt;なお、ここで挙げた設計方法は、1案に過ぎません。よりよい方法論もあることでしょう。
この方法論を試すのは自由にしていただいて構いませんが、
私はこの設計方法を採用して発生したいかなる損失に対してもなんらの責任は負わないものとします。&lt;/p&gt;

&lt;h4&gt;注釈&lt;/h4&gt;

&lt;p&gt;&lt;a href="#20080513fn1" name="20080513f1"&gt;*1&lt;/a&gt;元のコメントではシステムの範囲を誤解させてしまいました… orz
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn2" name="20080513f2"&gt;*2&lt;/a&gt;
RDBMSでのプライマリキーとなることも考慮してIDによって対象となるObjectを対応付けていますが、
本当はProjectオブジェクトへの参照によって対応付けを行いたいところです。
Projectオブジェクトの数が限られ、システム全体で完全にキャッシュされるようなケースであれば容易でしょう。&lt;br&gt;
全てキャッシュできるほどにProjectオブジェクトが少ないわけではないとすれば、
Projectオブジェクトの参照は同一に遅延ロードを実装する手法も考えられます。&lt;br&gt;
なお、アクセス速度を考えるとListよりはMapなどの構造を取った方が適切でしょう。
このあたりは実際のデータを鑑みて考慮する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn3" name="20080513f3"&gt;*3&lt;/a&gt;
ただし、通常ServletではThreadがプールされるため、HTTPのリクエストの処理開始で格納し、
処理終了時には削除するようにしておかなければいけません。
これはjavax.servlet.Filterで処理することで漏れなく確実な処理を行うことができます。
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn4" name="20080513f4"&gt;*4&lt;/a&gt;
アスペクトがDIのすべてとは言いませんが、AOP対応言語ではDIコンテナを使う意味があまりないはずです。
DIはコンストラクタに対するアスペクトとして実装することができてしまう。
強いて言えば、設定ファイルを読み込んでリフレクションで設定を行うところが面倒なので、
そのあたりをやってくれる程度には便利と思いますが。
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn5" name="20080513f5"&gt;*5&lt;/a&gt;
例えば、Projectオブジェクトを取得するためのサービスが限定されているようなケースでは、
その出口を抑えて、GoFデザインパターンのProxyパターンを適用すればよいのです。
Proxyクラスの実装はProjectオブジェクトを継承し、全機能をProjectに委譲するようにしておきます。
ただし、getterメソッド全てに参照件のチェックを差し挟むし、setter全てに更新件のチェックを差し挟むわけです。
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn6" name="20080513f6"&gt;*6&lt;/a&gt;
ProxyパターンでAOPをする場合の最大の障壁は、オブジェクトの生成箇所をどのようにして抑えるかという点。
new演算子で生成されると手の打ちようがありません。
生成に関するデザインパターンなどを用いて、オブジェクトの生成部を一元管理できているようなケースではどうにかなります。
DIコンテナも生成をDIコンテナが一身に背負うことでProxyパターンによるAOPを成し遂げているわけです。
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn7" name="20080513f7"&gt;*7&lt;/a&gt;
変更する人が状況をよく理解している少数であったとしても、修正に際してAOPの対応漏れは容易に発生します。
誰もが変更できる状況下では維持するためのコストは膨大になることでしょう。
&lt;/p&gt;
&lt;p&gt;&lt;a href="#20080513fn8" name="20080513f8"&gt;*8&lt;/a&gt;
1Threadあたり1Userという状況下である必要があります。
世の中にはあるいは1Threadあたり複数userとなるシステムもあるかもしれませんが、
そういうケースではこの手法ではうまくいかないことになってしまいます。
&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/137393.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>静的オブジェクト指向は設計者が苦労を背負込むシステム</title><link>http://blogs.wankuma.com/nagise/archive/2008/05/10/137150.aspx</link><pubDate>Sat, 10 May 2008 13:02:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/05/10/137150.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/137150.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/05/10/137150.aspx#Feedback</comments><slash:comments>133</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/137150.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/137150.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://d.hatena.ne.jp/minekoa/20080508"&gt;
みねこあさんのところ&lt;/a&gt;で挙がっていた、
静的オブジェクト指向と動的オブジェクト指向の軽さについての話題から。&lt;/p&gt;

&lt;h4&gt;Javaは経済的事情をうまく捉えて普及した&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2007/08/03/88626.aspx"&gt;
プログラミングの効率と経済&lt;/a&gt;で書いているとおり、大量生産フェーズにおいては
&lt;strong&gt;「一部のプロフェッショナルと多数の凡庸なプログラマという取り合わせ」&lt;/strong&gt;で開発することで
その費用を抑えるということが行われます。&lt;/p&gt;

&lt;p&gt;こうすることで、一定の品質のものを低価格で提供できるわけですが、現行のJavaEEでのWebシステムと
いうものは正にこのような体制で製造されているということも、多くの人が認めるところでしょう。
これはバベッジ的な分業効果
&lt;span class="footnote"&gt;&lt;a href="#f1" name="fn1"&gt;*1&lt;/a&gt;&lt;/span&gt;
というもので、とりたてて目新しい話題ではないですが、
JavaによるWebシステムが流行ったのは、こうした経済的側面からして都合がよかったという点が大きいと思います。&lt;/p&gt;

&lt;p&gt;要するにJavaというのは登場した&lt;strong&gt;1996年当時の肥大化しつつあるシステムを
いかに経済的に製造するかという点で答えを与えた言語&lt;/strong&gt;であり、
こうした経済的視点がJavaの普及の原動力のひとつであったと言えましょう。
事実、MicroSoftはJavaの改造版を作りWindows開発に利用しようとしましたし(J++ 1997年)、
ライセンス上のトラブルがなければC#(2002年)を作る必要はなく、J++がその役割を担っていたことでしょう
&lt;span class="footnote"&gt;&lt;a href="#f2" name="fn2"&gt;*2&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;p&gt;Java以前からオブジェクト指向が存在したことは周知の通りだし
&lt;span class="footnote"&gt;&lt;a href="#f3" name="fn3"&gt;*3&lt;/a&gt;&lt;/span&gt;、
Javaによってオブジェクト指向が広く使われることになったのもまた周知の通りです。
しかし、なぜ、Javaがオブジェクト指向を普及できたのか。
私が思うに、&lt;strong&gt;javaのオブジェクト指向がクラスの設計者と利用者の間のスキルの差を
バベッジ的分業効果で肯定した&lt;/strong&gt;からではないでしょうか。&lt;/p&gt;

&lt;p&gt;というのは、Javaの静的オブジェクト指向というのは、&lt;strong&gt;クラスを設計する側の立場に立つと
非常に苦労するものなのですが、クラスを使う側には非常に楽&lt;/strong&gt;なものなのです。
Java界隈で仕事をする会社の新人教育は、この「クラスを使うことができる」レベルまで
到達出ていればよいとされていると言って過言ではないでしょう。&lt;/p&gt;

&lt;p&gt;この、苦労をクラスの設計者に一身に背負わせたという点で、Javaの静的オブジェクト指向は
多数の凡庸な技術者を用いて開発を仕切らなければならないアーキテクト（先に言った設計者）の支持を得、
スペシャリストが作り上げたクラス群を使うだけという凡庸なプログラマ（先に言った利用者）にも
また支持されたのです。&lt;/p&gt;

&lt;p&gt;JavaやC#といった静的型付けのオブジェクト指向言語はまさにこのような環境下で多く活用されていますね。&lt;/p&gt;

&lt;h4&gt;初級者と中級者の間の壁&lt;/h4&gt;

&lt;p&gt;しかし、これはスペシャリストである設計者と凡庸な実装者の間に厚い厚い壁を作ることとなりました。
Javaはコーディングができるという初級者と、プログラミングができるという中級者の間に大きな壁があります
&lt;span class="footnote"&gt;&lt;a href="#f4" name="fn4"&gt;*4&lt;/a&gt;&lt;/span&gt;。
たどたどしいながらも、条件分岐とループを操り業務ロジックを実装するというレベルへは容易に到達できるが
そこから思った通りにプログラムを作れるまでの間が遠く、人がどんどん供給されてなお「人材」は
不足していると言われ続けるのは、この壁を越えて中級者となれる技術者の少なさを物語っているとも言えましょう。&lt;/p&gt;

&lt;p&gt;多分、その初心者と中級者とのあいだの落差が、LLと呼ばれる言語、つまるところ動的オブジェクト指向言語では
なだらかな斜面となっているのではないでしょうか。
それが、動的オブジェクト指向の「軽さ」のひとつではないでしょうか。
教育的な意味で、なだらかなステップアップが望めるのがLLではないでしょうか。&lt;/p&gt;

&lt;p&gt;さて、Javaで言ったクラスを利用できる初級者とクラスを作れる中級者・上級者との間の壁ですが、
これは、クラスの使い手が楽をできる分の揺り戻しというか、反作用と言うか、そうした類のものです
&lt;span class="footnote"&gt;&lt;a href="#f5" name="fn5"&gt;*5&lt;/a&gt;&lt;/span&gt;。
より&lt;strong&gt;使い手に優しいクラス設計にしようとすればするほど、クラスを作る段で苦労が増える&lt;/strong&gt;のです。
この初級者の苦労を中級者以上が代わりに背負うというシステムが、初級者と中級者の隔たりを大きくしている。&lt;/p&gt;

&lt;p&gt;しかし、クラスというのは作るよりも使う方が回数が多いのが通常ですから、作る側に労力を持ってくるというのは
非常に合理的で、うまく設計されたクラスと言うのはその使用に際して間違えることができない
&lt;span class="footnote"&gt;&lt;a href="#f6" name="fn6"&gt;*6&lt;/a&gt;&lt;/span&gt;。
ヒューマンエラーを機械的に排除した作りにすることができるのです。
これが、静的オブジェクト指向言語の何よりもの魅力なのです。&lt;/p&gt;

&lt;p&gt;逆に動的オブジェクト指向言語によるプログラミングは、初級者の苦労分まで中級者以上が背負うという責務が軽い。
これが、動的オブジェクト指向のもうひとつの「軽さ」ではないでしょうか。
他人の荷物を背負って山に登る必要がない。&lt;strong&gt;持つのは自分の手荷物だけでいい&lt;/strong&gt;のです。&lt;/p&gt;

&lt;p&gt;反面、動的オブジェクト指向言語のクラスライブラリの利用は静的オブジェクト指向言語でのそれに比べ
重いように私は感じるのです
&lt;span class="footnote"&gt;&lt;a href="#f7" name="fn7"&gt;*7&lt;/a&gt;&lt;/span&gt;。
自分で作ったクラスを自分で使う分には、両方とも自分ですからその重さはあまり気にならないかもしれない。
しかし、初級者を多数率いて行うような規模感の開発ではその重さが強く出てくるように思います。&lt;/p&gt;

&lt;h4&gt;それぞれの適所とは&lt;/h4&gt;

&lt;p&gt;つまり、LLというのは上級者であるスペシャリストが、多数の初心者を率いて巨大なシステムを作る
ということを行うには向かないが、&lt;strong&gt;中級者以上が集まったチームでは非常に手軽にサービスインまで
こぎつけることができる&lt;/strong&gt;のではないでしょうか。
ネットで話題に上がるような面白いサービスというのは正にこうしたチームによって作られていると思います。
手早くプロトタイピングし、その使い心地を評価するのに非常に向いている。&lt;/p&gt;

&lt;p&gt;逆にJavaのような静的オブジェクト指向といのは&lt;strong&gt;初心者の軍を率いて戦うには向いている&lt;/strong&gt;と思います。
業務用システムのような、大量の仕様を人海戦術で捌かなければならない状況によくマッチする。
ただし、これは軍を率いる将軍の采配が非常に重要であることをも意味しています。
上が荷物を持ってくれるからこそ一兵卒は軽い荷物で行軍できる。
上が荷物の持ち方を知らないなら、兵は生きて帰れぬ戦線で戦わされることになる。&lt;/p&gt;

&lt;p&gt;この責任の重さがJavaのオブジェクト設計の重さです。
しかし逆に、そこでさえうまくやれば、全軍を勝利に導けるという意味でもある。
Javaの静的オブジェクト指向というのは&lt;strong&gt;将軍の力でもって、初心者の大隊を常勝させるための技術&lt;/strong&gt;なのだと思うのです。
私が隊長となって、動的オブジェクト指向言語で中級者による小隊を率いるならば、
まだ戦果をあげることもできるかもしれませんが、
初心者の大隊を率いて戦えと言われたら、常勝する自信がない。&lt;/p&gt;

&lt;p&gt;だからこそ、一般には動的なオブジェクト指向言語での開発は小規模で生産性が高く、
静的なオブジェクト指向言語は大規模で生産性が高いのだと評価されるのでしょう。
この結論は個々の開発者が置かれた環境によって生産性が高くも低くもなることを意味していて、
どちらも&lt;strong&gt;一長一短あって、静動どちらかが絶対的に生産性が高いというわけではない&lt;/strong&gt;。&lt;/p&gt;

&lt;h4&gt;制約の多さは管理する側には大きなメリット&lt;/h4&gt;

&lt;p&gt;静的言語の制約の多さは、制約される側の立場、つまるところ淡々と実装作業をする側としては
わずらわしいものであると思うかもしれません。
それらを統括して管理しなければならない側に回ると、これほど統治に便利なものはない。
Java開発者では設計の自由を手にできている開発者は少ないと思います。
日々、降りてくる仕様書を淡々とコードにし、テストするような人員が大量動員されている。
彼らには多くの能力は求められません。つまり、簡単な重労働なのです
&lt;span class="footnote"&gt;&lt;a href="#f8" name="fn8"&gt;*8&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;p&gt;Javaでの開発を生業として、&lt;strong&gt;設計の自由を手に入れて楽しい開発をしたいのであれば、
どうにかして初級者の荷物を持つ力を手にしないといけない&lt;/strong&gt;
&lt;span class="footnote"&gt;&lt;a href="#f9" name="fn9"&gt;*9&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;h4&gt;静的オブジェクト指向言語の軽さ&lt;/h4&gt;

&lt;p&gt;静的オブジェクト指向での設計に慣れた者は、たとえ一人でプログラミングするとしても、
クラスを使う側というのは初心者であろうと失敗することができないという設計にしてしまう。
これは、神経質すぎるように思うかもしれません。
しかし、この神経質とも思えるクラス設計が、&lt;strong&gt;クラスを使う側に自身が回った時に幸せへと変わる&lt;/strong&gt;のです。
つまり、自分自身さえも、クラスを使う側に回ったならば初心者のレベルまで脳みそを手抜きすることが
できるというわけです。これが静的オブジェクト指向でのプログラミングの軽さなのです
&lt;span class="footnote"&gt;&lt;a href="#f10" name="fn10"&gt;*10&lt;/a&gt;&lt;/span&gt;。&lt;/p&gt;

&lt;p&gt;静的オブジェクト指向の理想は、&lt;strong&gt;コンパイルが通った時点でバグがなくなっていること&lt;/strong&gt;です
&lt;span class="footnote"&gt;&lt;a href="#f11" name="fn11"&gt;*11&lt;/a&gt;&lt;/span&gt;。
その強い型付けを最大限に生かし、間違えることができない型設計をすることが、後の生産性を高めます。
だから、クラスの設計が終わってしまえば、そのクラスについて&lt;strong&gt;忘れることが許される&lt;/strong&gt;。
強い型システムがクラスの使い方を導出してくれます。導かれるままに使うだけでいい。
私がJavaで大量にロジックを書くことができる理由は、効率よく忘れることが許されているからに他なりません。
俯瞰視点で設計するときは細部を見ることはないし、細部を作るときには全体を見ることはない。&lt;/p&gt;

&lt;p&gt;一度に大量にプログラミングすると自分でプログラムしたことさえ忘れてしまうことがあるぐらいに
&lt;span class="footnote"&gt;&lt;a href="#f12" name="fn12"&gt;*12&lt;/a&gt;&lt;/span&gt;、
型を境目とする「契約に基づくプログラミング」は思考を分断することができるのです。
型が契約を分かりやすくし、保証をしてくれる。
契約は確かに面倒臭い。ダックタイピングは慣行に基づき契約書なしでの契約締結で楽なのですが、
逆にそれゆえに契約そのものが曖昧であやふやな感じが私は嫌なのです。&lt;/p&gt;

&lt;h4&gt;注釈&lt;/h4&gt;

&lt;p&gt;&lt;a href="#fn1" name="f1"&gt;*1&lt;/a&gt;
 &lt;a href="http://ja.wikipedia.org/wiki/%E3%83%81%E3%83%A3%E3%83%BC%E3%83%AB%E3%82%BA%E3%83%BB%E3%83%90%E3%83%99%E3%83%83%E3%82%B8"&gt;
チャールズ・バベッジ&lt;/a&gt;(Charles Babbage、1791 - 1871)&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn2" name="f2"&gt;*2&lt;/a&gt;
 J++で作られたMFCのアプリケーションはMS製のJavaVMでしか動作しない。
これはJavaの世界を二つに分断することになるとJavaのコミュニティは考え反発しました。
Javaのライセンスを持つSunとの訴訟となったが、別にSunだけが反発したわけではありません。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn3" name="f3"&gt;*3&lt;/a&gt;
 JavaはSmalltalkやC++のオブジェクト指向の機構を参考にしています。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn4" name="f4"&gt;*4&lt;/a&gt;
 目的を適える為の方法論を考えられる/られないという区切りでプログラミング/コーディングと
用語を使い分けています。自分のやりたいことを自分で考えてコードにできるようになって
初めてプログラミングと言えると思います。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn5" name="f5"&gt;*5&lt;/a&gt;
 誰かの楽のためには誰かが苦労をすることになる…&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn6" name="f6"&gt;*6&lt;/a&gt;
 ただし、中級者の頃には、そのクラスの使用頻度・重要性に比べて凝りすぎたオーバースペックな
設計にしてしまいがち。でも、そうやって工夫を自分の手でやってみて設計を覚えていくのだから
教育的な視点では暖かく見守りつつ、バランス感覚を身につけるように諭さなければなりません。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn7" name="f7"&gt;*7&lt;/a&gt;
 デバッグが困難なバグのひとつに、異常データがどこからともなく紛れ込むというのがあります。
ソースの流れを追うのに比べ、データの流れを追うのは難しい。
(&lt;a href="http://blogs.wankuma.com/nagise/archive/2007/08/20/91054.aspx"&gt;
Objectよ、汝の出自を示せ&lt;/a&gt;を参照)
動的オブジェクト指向言語で私が一番不安になるのは、オブジェクトの動的さゆえに、この手のバグに
遭遇するのではないかという不安です。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn8" name="f8"&gt;*8&lt;/a&gt;
 ニコニコ動画で知られる、ドワンゴが2ちゃんねるで求人をした際のフレーズ。
&lt;a href="http://www.itmedia.co.jp/news/articles/0803/12/news131.html"&gt;ITmediaの記事&lt;/a&gt;を参照のこと&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn9" name="f9"&gt;*9&lt;/a&gt;
 設計をする自由を手に入れるとIT業界は俄然楽しくなります。技術職の本懐でしょう。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn10" name="f10"&gt;*10&lt;/a&gt;
 情けは人の為ならず。使いやすいクラス設計を呼吸をするように無意識に出来るところまで
プログラミング能力を鍛えると静的オブジェクト指向の方が楽になると私は思います。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn11" name="f11"&gt;*11&lt;/a&gt;
 実際、業務ロジックなどの単純なものであれば1000行程度なら、2～3時間ぐらいでがーっと書いて
コンパイルを通した後に2割ぐらいは1発動作します。
動作させて若干の修正というのがほとんどで、1、2回の確認でプログラミングが完了。
ただし複雑なロジックは流石にそうもいかず、JUnitのテストなどを使いつつ動かしながら完成させます。&lt;/p&gt;

&lt;p&gt;&lt;a href="#fn12" name="f12"&gt;*12&lt;/a&gt;
 &lt;a href="http://blogs.wankuma.com/nagise/archive/2007/10/10/101128.aspx"&gt;
小人さんとの出会い方&lt;/a&gt;を参照&lt;/p&gt;

&lt;h4&gt;追記&lt;/h4&gt;

&lt;p&gt;トラックバックできないとの問い合わせがありましたので、その点について追記しておきます。&lt;/p&gt;

&lt;p&gt;わんくまblog全体に言えることですが、トラックバックが分かりにくくなっているかと思います。
（自分も昔、わんくまblogにトラックバックを送ろうとして失敗したことがあります。）&lt;/p&gt;

&lt;p&gt;わんくまでは.Textというblogツールを使っているようで、挙動は.Textの使用に準じます。
また、スパムが多いらしく、厳しめにスパムキーワードを設定しているようで、リンクを書けないなど不便をおかけしています。
管理人に代わりお詫び申し上げます。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://itkz.blogspot.com/2008/05/2ch-8-8-2-itmedia-2ch-2ch-2ch-webdb.html"&gt;2ch 求人就職者の実状&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/137150.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>アスペクト指向の概念</title><link>http://blogs.wankuma.com/nagise/archive/2008/03/25/129472.aspx</link><pubDate>Tue, 25 Mar 2008 10:33:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/03/25/129472.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/129472.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/03/25/129472.aspx#Feedback</comments><slash:comments>47</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/129472.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/129472.aspx</trackback:ping><description>&lt;p&gt;アスペクト指向(AOP : Aspect-oriented programming)はオブジェクト指向(OOP : object-oriented programming)とは直行的な
概念で、相補的なものですが、2008年現在、未だ広く普及しているパラダイムではなく、その機能を取り込んだ言語もあるものの
（Javaの拡張であるAspectJ、Rubyの拡張であるAspectRなど）普及しているとは言えない状況です。&lt;/p&gt;

&lt;p&gt;近年ではDIコンテナの普及で、AOPを部分的に利用できるようになりました。
オブジェクト指向言語の普及前に、例えば言語としてのオブジェクト指向をサポートしないC言語で、
オブジェクト指向の概念を表現する工夫がなされたと聞きます。
DIコンテナによる部分的なAOPサポートは、言語機能としてAOPがサポートされた言語が普及する「夜明け」に対して、
「前夜」の趣を感じさせるものです。&lt;/p&gt;

&lt;h4&gt;アスペクト指向が解決しようとしていること&lt;/h4&gt;

&lt;p&gt;アスペクト指向の解説書でアスペクト（横断的関心事と呼ばれる。後述）の例として、よくロギングが挙げられます。
が、正直な話、私はあまりこの例でピンときませんでした。&lt;/p&gt;

&lt;p&gt;横断的関心事とはどういう事象でしょうか？&lt;/p&gt;

&lt;p&gt;オブジェクト指向では複数のクラスに跨って存在してしまう機能性ということですが、どういうものがあるのでしょうか？&lt;/p&gt;

&lt;p&gt;私がシステム設計をしてきた中で、「あぁ、これが概念としてのアスペクトなのだな」と思ったことは&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL injection対策
&lt;li&gt;XSS対策の出力文字エスケープ
&lt;li&gt;OS command injection対策
&lt;li&gt;バッファオーバーラン防止のためのバウンダリチェック
&lt;li&gt;例外処理
&lt;/ul&gt;

&lt;p&gt;といったことです。開発でこれらの対策に頭を悩ませている方は多いのではないでしょうか？&lt;/p&gt;

&lt;p&gt;これらの事象は、「すべての該当箇所に対して、一律の対応を行う必要がある」という点です。
これこそが、概念としてのアスペクト、横断的関心事なのです。&lt;/p&gt;

&lt;p&gt;こうした、XXに全部YYをする、というのは自然言語で表現すると１文にも関わらず、
プログラム言語的には該当箇所を検索して１つずつ虱潰しにコードクローンを挿入する必要があります。
アスペクト指向が解決しようとしているのは、まさにこの部分なのです。&lt;/p&gt;

&lt;p&gt;アスペクト指向の概念で重要なのはこのアスペクトという抽象概念を捉える事。
そして、どういったターゲットにウィービング（weaving : 縫い付けるの意。アスペクトを適用させること）
させるのかということです。ウィービングできるポイントをジョインポイントと呼んだりします。
端的には、メソッドが呼ばれる前、および呼ばれた後などをジョインポイントとすることが多いですね。&lt;/p&gt;

&lt;h4&gt;どのように実装するか&lt;/h4&gt;

&lt;p&gt;DIコンテナでは部分的にAOPが利用できると述べました。
DIコンテナはオブジェクトの生成をDIコンテナが管理します。
このDIコンテナに管理されたオブジェクトに対してGoFのProxyパターンを利用してAOPを実現しています。&lt;/p&gt;

&lt;p&gt;これはOOP的な環境で疑似的にAOPを実現するためのひとつの答えです。&lt;/p&gt;

&lt;p&gt;あるクラスのインスタンス生成が制御されうるなら、その段階でProxyを挟むことで、
そのクラスの特定のメソッドの前後に処理を一律に差し挟むことができます。&lt;/p&gt;

&lt;p&gt;DIコンテナではコンテナがクラスの生成を管理するためにそれが可能でした。
そうではない場合でも、Factory Method、Abstract Factory、Builder などといった生成にまつわる
GoFデザインパターンと組み合わせることで、一律にProxyを噛ませることができます。&lt;/p&gt;

&lt;p&gt;また、ウィービング対象となるオブジェクトが特定の箇所を必ず通過するようなケースでは、
そこでトラップしてProxyを噛ませるような方法論も考えることができます。
ServletでのRequest#setAttribute()のような場所をイメージするとよいでしょう。&lt;/p&gt;

&lt;p&gt;実行時による動的なウィービングでなくとも、コンパイル時に機械的に処理を差し挟むような方法論も考えられます。&lt;/p&gt;

&lt;p&gt;Java SE 5.0からはアノテーションが使えるようになりました。
これにより、こうした機械的な処理が断然しやすくなった点も見逃せません。
コンパイル時にジョインポイントを自動生成するような仕掛けを作ることで概念としてのAOPを実装することができるわけです。&lt;/p&gt;

&lt;h4&gt;関連エントリ&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://blogs.wankuma.com/tyappi/archive/2008/03/20/128781.aspx"&gt;Injection 系の脆弱性ってなんで起こるんだろ？&lt;/a&gt;&lt;br&gt;
&lt;a href="http://d.hatena.ne.jp/ajiyoshi/20080321/p1"&gt;そのやり方はXSSの元としか思えない。&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;XX Injection と呼ばれる脆弱性に共通するのは、OOPでの解決の行えない横断的関心事であるということでした。
一律に対応するためにはどのように網を張ればよいのか、設計をする人は頭を悩ませていることでしょう。&lt;/p&gt;

&lt;p&gt;現時点では決定打に欠けるところですが、概念としてはアスペクトをどのようにして漏れなくウィービングするのかということです。
そのための適切なジョインポイントはどこかということです。&lt;/p&gt;

&lt;h4&gt;アスペクト指向の問題点&lt;/h4&gt;

&lt;p&gt;アスペクトというものが横から入り込んでくるわけですから、OOPのソースコードを見ただけでは実行時の動作がわかりません。
そう言った意味でプログラムが複雑化する危険性をはらんでいます。
また、アスペクト同士の干渉が起こることもあり、アスペクトの適応順序によって挙動が変わることもあります。&lt;/p&gt;

&lt;p&gt;また、アスペクト指向でウィービングの対象をどう管理するかも疑問が多い。「全ての」の適用範囲はどこまでなのか。
あるいは、特定の範囲だけに適用したいこともあるでしょう。
現行のDIコンテナでのAOPではメソッド名のマッチングによって特定の名称のメソッドの前後に適用、
といったことができますがこれが酷く気持ち悪い。&lt;/p&gt;

&lt;p&gt;gattaislime氏の&lt;a href="http://d.hatena.ne.jp/gattaislime/20070925/1190746881"&gt;アスペクト指向の問題点&lt;/a&gt;では
&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;
　要するに、現在の典型的なアスペクト指向では、アスペクトを織り込むオブジェクトがホワイトボックスであることを要求するか、逆にアスペクト自体がオブジェクトの実装を規定するか、ということになってしまい、結果としてアスペクトが単なる暗黙的多重TemplateMethodに成り下がっているのではないかと感じてしまうのだ。&lt;br&gt;
&lt;br&gt;
　このような暗黙のTemplateMethodは非常に厄介で、ソースコードをそのまま追っても処理の流れがつかみにくく、最悪の場合ソースコード全体をメソッド名や属性名でgrepして、関連するすべてのアスペクトを洗い出さなければならない。
&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;と指摘しています。&lt;/p&gt;

&lt;p&gt;ウィービング対象は集合論的に抽出されるわけで(つまり、SQLのWhere句のようなイメージ)Javaなどの強い型付け言語でなされる
型の安全性のような安心感がまったくない。&lt;/p&gt;

&lt;p&gt;しかし、集合論というとジェネリクスも集合論ですが、型の安全性を確保できている（
&lt;a href="http://blogs.wankuma.com/nagise/archive/2007/08/04/88855.aspx"&gt;参考:ジェネリクスと代入と落とし穴&lt;/a&gt;
）わけで、ウィービングのための型のような
システムが必要なのではないかと思う次第。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/129472.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>議論をするためのシステムを考える</title><link>http://blogs.wankuma.com/nagise/archive/2008/02/01/120404.aspx</link><pubDate>Fri, 01 Feb 2008 18:02:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/02/01/120404.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/120404.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/02/01/120404.aspx#Feedback</comments><slash:comments>39</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/120404.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/120404.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/nagise/archive/2008/02/01/120363.aspx"&gt;掲示板は何のためのシステムか&lt;/a&gt;では
技術系のいわゆる電子掲示板と呼ばれるものは、実際には単なる「掲示版」ではなく、
知識の集積の機能と、議論のための機能が求められているのではないか、ということを述べました。&lt;/p&gt;

&lt;p&gt;この稿ではそのための機能性についての案を考えたいと思います。&lt;/p&gt;

&lt;h2&gt;知識の集積に必要な機能性&lt;/h2&gt;

&lt;h4&gt;カテゴライズ&lt;/h4&gt;

&lt;p&gt;投稿された質問などはネタ振りで、それを取り上げ知識の形にまとめて集積を行うというスタンスのシステムを考えましょう。&lt;/p&gt;

&lt;p&gt;まずはネタ投稿。これは一般のスレッド式掲示板などとそれほど変わらないと思います。
ただし、ジャンルのカテゴライズは投稿者によってある程度事前の選定は可能ですが、
&lt;strong&gt;後にジャンル変更できるようにすべき&lt;/strong&gt;と考えます。また、複数のジャンルに及ぶものもありますから、
複数のカテゴリをタグ付けするような方法論が適しているのではないかと思います。&lt;/p&gt;

&lt;p&gt;とくに質問を投稿する方には初心者も多く、カテゴライズがそもそも出来ないケースを
想定しておく必要があると思います。&lt;strong&gt;JavaとJavascriptが混同されるのはもう沢山&lt;/strong&gt;です。&lt;/p&gt;

&lt;p&gt;この先はおぼろげにしか考えていない部分なのですが、カテゴリは「はてな」などで使われている
タグ付けの機能ではちょっと弱いのではないかと考えています。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;タグ自体が暗黙に木構造をなしているのではないか。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;たとえば、Strutsというフレームワークについての質問にはStrutsタグが付くと思いますが、
StrutsはJava上で動作するフレームワークですから、暗黙に上位にJavaタグが存在するはず。
いちいちタグ付けをする際にJava、Strutsと療法記載する必要はないと思うのです。
木構造をなしたタグがあり、それにより投稿をフィルタリングしていけるという作りがよいのではないでしょうか。&lt;/p&gt;

&lt;h4&gt;情報は編集された後に保管される&lt;/h4&gt;

&lt;p&gt;既存の掲示板のシステムではネタ振りをした質問者と回答者とのやりとりが、
そのままの形で保管されるわけですが、実際にはそんなものはいらないのではないか。
&lt;strong&gt;知識の集積という観点では、一度編集が入った、
純度を高めた情報があればそれでよいのではないか&lt;/strong&gt;と思うのです。&lt;/p&gt;

&lt;p&gt;もちろん、元ネタというか１次資料となる会話、やりとりは保管する必要があるでしょう。
しかし、それはメインで参照されるものではなく、編集された知識の部分に違和感を覚えた際に
その元を辿るような意味合いのものだと思うのです。&lt;/p&gt;

&lt;p&gt;ある意味でこれに近いのはwikipediaの編集があたるのかもしれません。
ノートによる議論は裏方として隠れており、編集後の純度を高めた知識、
つまり、普段我々が目にしている記事がメインで参照されるわけです。&lt;/p&gt;

&lt;p&gt;掲示板を知識・経験の蓄積の元ネタとするならば、
ちゃんと編集し集積するところまでを考慮に入れてシステム化するべきではないかと思います。&lt;/p&gt;

&lt;h2&gt;議論を支援するための機能&lt;/h2&gt;

&lt;p&gt;掲示板での議論で問題となるのは、その時点での論旨をとらえるのが難しい点、
またそこまでの議論で出てきた前提条件を把握することが難しい点にあると思います。&lt;/p&gt;

&lt;p&gt;時系列的に、どこでどういった問題提起がなされ、その問題に一定の解が出たのかどうか。
この辺りのまとめが付随していれば、長く延びたスレッドに途中参加で議論に加わることも可能でしょう。&lt;br&gt;
@ITなどでは&lt;strong&gt;長くなったスレッドでは、繰り返し同じ趣旨の発言がなされたりしています&lt;/strong&gt;。
これを、「スレッドの流れを把握した上で発言しろ！」と人間側で注意するという方向性に持っていくと、
繰り返しマナーについての議論がなされるような事態となります。
ここは是非、システムで前提把握、提起されている問題把握のサポートをしたいところ。&lt;/p&gt;

&lt;p&gt;このようにシステムでサポートすることで、自己矛盾に陥るような一貫性のない発言を繰り返す
「議論のできない人」にも、論理的考察をする方向へコーチングできるのかもしれません。
そして、そういう場を作ることで、論客が集う、活気のある場となるのかもしれません。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/120404.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>凪瀬</dc:creator><title>掲示板は何のためのシステムか</title><link>http://blogs.wankuma.com/nagise/archive/2008/02/01/120363.aspx</link><pubDate>Fri, 01 Feb 2008 13:37:00 GMT</pubDate><guid>http://blogs.wankuma.com/nagise/archive/2008/02/01/120363.aspx</guid><wfw:comment>http://blogs.wankuma.com/nagise/comments/120363.aspx</wfw:comment><comments>http://blogs.wankuma.com/nagise/archive/2008/02/01/120363.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.wankuma.com/nagise/comments/commentRss/120363.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/nagise/services/trackbacks/120363.aspx</trackback:ping><description>&lt;p&gt;技術系の掲示板で「利用マナーについて」というのは幾度となく繰り返された議論だと思います。
私はそこに潜む問題点をシステムではなく、運用でカバーしようとするから根絶できず、
そして対策会議的に議論が繰り返されるのだと考えています。&lt;/p&gt;

&lt;p&gt;まずはいわゆる「電子掲示板」が、そもそも何を目的としたシステムなのかを考えてみましょう。&lt;/p&gt;

&lt;h4&gt;技術掲示板は掲示板なのか？&lt;/h4&gt;

&lt;p&gt;掲示板というのは、そもそも「掲示」をするためのものです。
gooの国語辞典で繰ると&lt;/p&gt;

&lt;p&gt;&lt;blockquote&gt;
（名）スル&lt;br&gt;
人目につきやすい所に掲げ示すこと。また、示された文書。&lt;br&gt;
「日程を―する」「―を読む」
&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;とあります。みんなが見る場所で質問などをすれば答えてくれる人もいるかもしれない。
みんなが見る場所で何か話題を持ち上げれば話に乗ってくれる人もいるかもしれない。&lt;/p&gt;

&lt;p&gt;しかし、「みんなが見る」という時点で多数の利用者を想定しているのですから、
思惑が違う人がいろいろな掲示をすると混沌として訳がわからなくなる。
ですから、用途を限定した掲示板が生まれ来るのはごく自然なことです。&lt;/p&gt;

&lt;p&gt;では、我々技術者が使う掲示板というのは、カテゴリを絞って「掲示」だけできればいいのでしょうか？&lt;/p&gt;

&lt;p&gt;ある掲示板では「双方向の情報交換のためのコミュニティ」としています。
単なる一方通行のやりとりは控えるように記載されていたりする。これはもはや「掲示」ではない。&lt;/p&gt;

&lt;p&gt;では、一体何ができる必要があるのか。そこは立場により、考え方によりいろいろあるでしょうが、
私が欲するものは大体以下の通りです。&lt;/p&gt;

&lt;p&gt;&lt;ul&gt;
&lt;li&gt;質問と解答の組を蓄積することで、Q&amp;A集としての知識の集積を行う場
&lt;li&gt;議論を行う場
&lt;/ul&gt;&lt;/p&gt;

&lt;h4&gt;掲示板が提供するものは個人の問題解決ではない&lt;/h4&gt;

&lt;p&gt;既存の掲示板の利用者には「自分の抱える問題を解決してくれる場」として
掲示板に書き込む方も多いかと思います。
しかし、掲示板で回答する立場の人というのは「その個人が問題解決」さえすればよい、
と考えている人は少数派なのではないでしょうか。&lt;/p&gt;

&lt;p&gt;もし、個人の問題解決だけすればよいのであれば、延々と履歴を残す必要はないし、
解答は公開の場で行う必要もない。
なにより、「答えさえ得られればよい」という立場でマルチポストをするなどした場合に
強く非難される風潮も「個人の問題解決」を是とするなら否定されるべきです。&lt;/p&gt;

&lt;p&gt;これらのことからも、「個人の問題解決」はおまけでしかなく、
問題事例とその解答というものを共有するということが主目的ではないかと思うのです。&lt;/p&gt;

&lt;p&gt;しかし、現在の掲示板は問題点を把握するためのやり取りが多く、
後で参照して利用するには適さない形となっているものも多いのではないでしょうか。
少なくとも、「まとめ」が必要になるのだと思うのです。
類似事例や過去事例への補足といった形で情報資産を活かすべきだと考えます。&lt;/p&gt;

&lt;h4&gt;時には議論も行いたい&lt;/h4&gt;

&lt;p&gt;技術的なトラブルなど、問いに対して明確な解があるものばかりで利用されているかといえばそうでもない。
技術者はやはり議論が好きな方が多い。やはり、「問い-答え」に縛られない議論もしたいところです。&lt;/p&gt;

&lt;p&gt;しかし、議論というのはスキルのいるもので、話の流れ、議題を的確にとらえなくてはならない。
多数の人が参加し、長く議論されているスレッドなど、話の流れを把握するのも大変だし、
議題をとらえるのも大変です。&lt;/p&gt;

&lt;p&gt;「それは過去に結論済み」といった発言も出てきますし
「XXという趣旨の発言はしていない、何か取り違えていないか？」といったこともあります。&lt;/p&gt;

&lt;p&gt;これは、１次ソースである、個々の人の発言そのままというものしか与えられず、
要約という大変労力のかかる作業が個々の読み手に任されているということが
難点ではないかと思うのです。並行してまとめサイトが作られる必要があるのではないか。&lt;/p&gt;

&lt;p&gt;炎上状態になると、多数の人から同じ趣旨の質問が大量になされたりすることもある。
これも、論旨をまとめることで重複をずっと減らせると思いますし、
解答せずに放置されている議題なども明確化され、真の意味での議論を進めるには非常に有効だと思います。
また、「議論」のつもりで自己の主張を叫ぶだけの人は、議論ができていないことが明確化されるとも思います。&lt;/p&gt;

&lt;h4&gt;ではどのようなシステムにするべきなのか&lt;/h4&gt;

&lt;p&gt;というところは、次のエントリにて具体案を提示することにします。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/nagise/aggbug/120363.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>