トップ 最新 追記

日々の破片

著作一覧

2004-04-01

_ グートルデ

ドライヤーじゃないんだからグートルネだな。

_ ハーゲン

狩から帰って来て、黒い下着姿のグートルネにジークフリートの死を告げるシーンの演出、妙な感じだったが、この2人も兄弟であった。

もしかすると、ここでは(方法は異なるが)ジークムントと重ねているのかも。

であれば、ヴォータンと重ね、ジークムントと重ね、ジークフリートと重ねることで、ハーゲンに収斂するというかハーゲンこそが主役であるという構造を作りたかったのかも、と思う。

もちろん、すべてはアルベリヒの呪いの上で舞台が回るわけだから、ハーゲンに収斂するのは当然だし、性格の複雑さという意味では、ヴォータンとハーゲンが双璧なわけだし(だから神々の黄昏ではそれまで出ずっぱりで舞台を回すヴォータンが不在でも済むとも言える)、なかなかに興味深い。

というか、耳に残っているのは意外と葬送の部分なのであった。ドンドン。

・舞台のスティールで、ラインの黄金では、ローゲだけ黒い服だったのを知る。

ローゲ(半神)、ジークムント(半人)、ハーゲン(半ニーベルンゲン)。

_ ハーゲン(続)

(唄マーク)陽気な連中はまだ4月だと言うが、土気色したオレはもう4月だと言う。

_ 今日届いた本

大正天皇 (朝日選書)(原 武史)

以前、誕生日をずらすのは無理だろうな、と書いたところ、大正天皇の時、それが行われたと教わった。全然、知らなかったが、考えてみれば、もともと大正天皇については、ほとんど何も知らないことに気付く。

唯一知っているのは遠眼鏡事件と、実母は公の席では母ではないからとても悲しがっていたのを見て息子が一夫一婦制を守ると決めたというようなエピソードくらいだ。というわけで紹介していただいた本をクリック。

パラパラ読んだ感じを稗史風に描くと、大隈重信らと語らいながら、開放(デモクラシー)路線で突き進もうとする大正天皇に対し、山縣(また長州か……)らが抑圧をかけ(稗史だと、わかりやすく一服盛ることこになるが)大正デモクラシーを圧殺。それと同時に、天皇が病気になるという事実を国民が知ることから、神ではなく超権力を携えた人間としての天皇が思想史的に姿をあらわし、かくして、昭和の道を突っ走ることになる、ということのようだ。なぜ、大正デモクラシーというものが生まれ、生まれた瞬間に圧殺されたかという問題ともからむんだろうなぁ。

日本の近代史において、いち早く海を渡ることで近代的な政治や経済を司る官僚として目覚めた幕府の有能(かどうか手腕を振るう前にほとんどが始末されてしまったわけだが)な役人や高度に発達した市民文化を育んでいた江戸の町人を追いやって、藩閥の利権争いの延長で海まで越えていった長州の連中の存在ってのが、この時代まで暗雲を投げかけていたという事実にあらためて嫌な気持ちになる。

ここに描かれた、諸国を回って民情を視察し(政治的には地域開発のための利権などを生んで石橋湛山に文句を書かれたりしているが)同情したり疑問を聞いたりする本当の意味での人間的な天皇という路線が長続きできればいろいろ違ったんだろうな、と思いを巡らして見たり。

結局は、巡幸が人間的であってはならないという教訓を与えてしまったために、次の時代のただただうなずくだけの人間天皇というシステムを作らせてしまう原因となって、その存在もあってはならない人間天皇の実証実験として封印されてしまうことになったわけで、おそらくそれは国民にとっても天皇にとっても残念なことだ。


2004-04-02

_ rave

辞書を引くと第一義は「うわごとを言う」で、次が「どなりちらす」。

名詞では、第一義が「怒号」で、次が「激賞」。最後に「夢中」。

春の祭典の初演の話とかシェローのリングとかを考えると、そういうのをraveと言うのかな?

好悪がはっきり分かれるとか? それでProject Raveなのかなぁ。

_ カマンベール

アライグマ博士と仲間たち 全3話 (福音館文庫 物語)(ベン・ルーシャン バーマン)

も、えとせとら経由で購入。したと思うんだけど。

しかし、親子ともどもそれほど余裕がない(子供はアライグマ博士を読んでるし)ので、いつ読むかはわからない。が、なんか楽しい本だなぁ(カマンベールのほう)。

アライグマ博士は、子供と立ち寄った本屋でナニゲなくパラパラ見たらおもしろそうだったのでなんとなく買ってやったのだが、ちょっと(さすがに瀬田貞二ほどじゃないが)翻訳が古風なのでどうかなとは思ったが、語り手が川を見ているとそこにアライグマ博士がやって来て昔話をはじめるという導入のせいか、すんなり読んでいるらしい。

翻訳が古風になるというのは、赤木かんこも指摘してたが、確かに問題かも知れない。実際、ライオンと魔女はどうにか読んでたものの、カスピアン王子の角笛は途中で捨てられてしまったし、それより遥か前にドリトル先生の短篇(楽しい家のあたり)でも読んでやるかと思って声に出す日本語をやらかした瞬間に後悔したくらい、完全に今の言葉ではなくなっている(ので、やめた)。

じゃあ、子供の頃の本を後生大事に抱え込んでいたのは全く無駄だったのかと言えばそんなことはない。

瀬田貞二よりも時代的には前になるにも関わらず、たとえば宮沢賢治なんかのほうがよっぽど現在でも通じる言葉なのはなぜなんだろう? それが母国語ってことなんだろうかなぁ、とか。小川未明にしろ、新美南吉にしろ問題ないし。文化的背景ってのはそれほど変わらないから、翻訳で無理矢理持ってきた背景と異なり通じ合うってのはあるかも。

くらむぼんは笑ったよ

家庭教師の青年は黒い洋服を着ていると描写されているが、ジョバンニやカムパネルラやザネリについて何も書いていない。だから、すんなりと自分の小学校の教室を想像する。僕が読んだ当時の想像と、子供の想像では異なる教室だ。おそらく宮沢賢治の想像では、カスリの和服だったり。ランプはガス灯かも知れないし、汽車は石炭で走るんだろうが、おそらく子供は電灯や電車を想像しているかも知れない。ジョバンニの家は茅葺屋根で母親は「寝んでいる」のだが、きっと煎餅布団に違いない。が、僕はベッドを想像したし、これは子供もそうだろう。新美南吉になると遥かに描写は多いが(たとえばおじいさんのランプとか)、この場合の光景はそれでもなんとなくテレビとかで見覚えがないわけではない過去の日本として立ち表れてくるからそれほど違和感は覚えない。

また描写が少なければ、翻訳の古さはそれほど問題とならないかも知れない。たとえば、エルマーの冒険の訳は古いが、問題ない。描写されるのはもっぱら動物とジャングルだ。

しかし、ドリトル先生あたりになると、そこに出てくる小物のレベルからして格段に難しくなってくる。翻訳当時の日本で一般的に知られていないものをリアリティを出すためにひねって翻訳したものがすべて裏目に出ている感じだ。

本日のツッコミ(全1件) [ツッコミを入れる]

_ るいも [音楽ジャンルのRaveにかけている様な気も。SwingもDukeが踊ってましたし。]


2004-04-03

_ Rave

ミュージックシーンのレイブって言うことは、おー、たくさんの開発者が集まってきたぞということですね。っていうか、このサイトは異色だな。

ちょっと疲れ気味。

_ 職場に来た謎メール

spamなのか真摯なのか、さーぱりわからない、謎メール。こんな文面(英語だけど)。

君の名前はタロウ(ということにしておく)だよね。実は、家内と相談したんだが、もうじき生まれる子供にタロウと付けるつもりなんだ。

でも、どういう意味かちょっと不安になったってわけだ。

それでyahooで探したら、君のメールアドレスを見つけたって次第だ。

タロウ、もしよければ、意味を教えてくれないか?

それではよろしく

アラビアな名前 UAE

しかし、yahooで探したがそんなの出てこないぞっていうか、職場のメールアドレス知っているのは社内の人間を除けば50人に満たない勘定だ(全く、公開してないから名刺の消費量くらい)。

したがって、spamなんだが、それにしてもわけわからん。

これで返事を書くようなお人よしだと考えたら、次に、「それでは100ドル貸してくれ」となるんだろうか? しかも、ヘッダを見ると名前がわかるエイリアスじゃないほうのアドレス使ってるし。っていうことは社内からの名簿流出と考えるべきだろうが。

_ rjb-0.0.6

大体、できた。
test.rbから抜粋。
  class TestIter
    def initialize()
      @i = 5
    end
    def hasNext()
      @i > 0
    end
    def next()
      @i -= 1
      @i.to_s
    end
  end
 
  def test_newobject()
    it = TestIter.new
    it = bind(it, 'java.util.Iterator')
    test = import('jp.co.infoseek.hp.arton.rjb.Test')
    a = test.new
    assert("43210", a.concat(it))
  end
で、対応するjp.co.infoseek.hp.arton.rjb.Testは、
package jp.co.infoseek.hp.arton.rjb;
import java.util.Iterator;
 
public class Test {
    public String concat(Iterator i) {
	StringBuffer sb = new StringBuffer();
	for (; i.hasNext(); ) {
	    sb.append(i.next());
	}
	return new String(sb);
    }
}
Rubyのオブジェクトを、Rjb::bindを呼び出してjava.util.Iteratorインターフェイスに束縛している(なんか、やっぱり変かな?――より良い関数(モジュールだから)名があればコメント欲しいところ)。
したがって、Java側からは(Test#concatメソッドの引数として)インジェクションされたRubyのオブジェクトをjava.util.Iteratorとして呼び出すことができる。
注意点は、束縛されたメソッドからの返送。TestではbooleanやStringのような自動変換が可能なものを使用しているからへっちゃらだが、実際には、Javaのオブジェクトを移入して、それを明示的に返送に利用しないとだめだろう、といったあたり。
MS-Win32は、OK。Linuxはちょっと微妙(LD_LIBRARY_PATHの設定は別として)だが、問題ないと思いたい。
MSwin32なら
set JAVA_HOME=j2sdkインストールディレクトリ
vcvars32
ruby extconf.rb
nmake test
makeで、テスト用のセットアップするから、
nmake
ruby test.rb
ではうまくいかない。Linuxも大体これと同じ。
export JAVA_HOME=/usr/java #とか
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib:$JAVA_HOME/jre/lib/i386:$JAVA_HOME/jre/lib/i386/client
ruby extconf.rb
make test
i386とか、JAVA_HOMEの位置とかは実際の環境依存。i386以外の動作は怪しい。特に64ビットCPUだと。
というわけで残る問題は、 ポインタ64ビット環境は???
Cygwinも???
といったところだが、そのへんはRAAで公開してからだとして(どうせ試さ/せないから)、英語ドキュメント、サンプルとかを作らなきゃならないな。
あと、公開までに次の処理の動作方法を決定しなければならない。
前提)Rjbは、RBridge.classを動的にロードする。
  • 方法1)ソース内のバイト配列にバイトコードを埋め込む。
  • 方法2)リソースへ埋め込む。
  • 方法3)lib/ruby/site_ruby/version/os_dependedにsoと同時にclassをデータとしてコピー
  • 方法4)lib/ruby/site_ruby/version/rjbにclassをデータとしてコピー
ASRやSWinのようにWindows専用なら、方法2で決まりだが、Linuxなんかもターゲットに含んでいるから、どうやってやるのかわからないので、これはパスかな。
方法1は、固いしsoの可搬性に優れているが、ちょっとなぁ。
方法3は、classがなぜ、そのディレクトリにという疑問が。
方法4は、分離度は良いとして、やはりなぜ、そのディレクトリにという疑問が。
方法5というのもあって、文字列としてrjbにRBridge.javaのソースを埋め込み、ロードの都度、/tmpでjavacを実行するってやつだが、さすがに無駄くさいからパス。ソースを方法3や4の方法でlibにコピーってのも避けたいところ。

2004-04-04

_ 4/4

ナイト・オン・ザ・プラネット [DVD](ウィノナ・ライダー)

「わかった、わかった、どうせオレの名前はロシア系で、ここじゃあイカしてないよ。で、そういうお前さんの名前は?」

「……」

「で、そういうお前さんの名前は?」

「……」

「もったいつけるなよ」

「……ヨ」

「ヨ?」

「……ヨーヨー」

「……(激笑)……ヨー……ヨー!(激笑)」

「……そーだよ、ヨーヨーだよ。文句あんかよ」

――記憶の中のナイトオンザプラネットから引用

_ 歴史と権限委譲

歴史が進むと権限委譲も進む。本当か?

かって権力は王にあった。今では民にある。

複雑化した権力を1人がさばくのは、建武の親政(だよな、意味的に)の時代ですら無理だったことは歴史が証明している。絶対的に1人では処理できないからだ。それは国家が肥大化したからだ。10人の村落なら1人の村長がすべての政務をさばけるだろう。100万規模になったら1人でさばくことは不可能だ。それは、後醍醐の夢想(たった一人の権力者がすべてを支配しようという下劣な妄想だ)とは無関係な現実的な必要性の問題だ。

かって設計は設計者にあり、今ではプログラマにある。

設計→実装→検証 というサイクルを分散したほうが効率が良いからだ。

その頃(分業の時代)は、プログラマとコーダは別物と考えるとわかりやすい。言葉の違いは役割の違いだ。

コーダは、設計をコードに落とす人で、プログラマはプログラムを作る人だ。コーダは多少気の利いたプログラム言語と仕様書の翻訳機に過ぎない。プログラマは自分で考え作らなければならない。

大まかに言ってしまえば、企業情報システムのプログラミング言語エキスパートはコーダでそれはユーザーではなく、ワークステーション分野のプログラミング言語エキスパートは大抵ユーザーを兼ねているからプログラマだった。

設計者を排除するには、コーダもコーダのままでいることはできない。プログラマになる必要がある。

民主主義を成立させるには、民主的組織の構成員にリテラシーが必要となることと規を一にしている。

歴史に反省点を求めればダウンサイジング戦略に失敗したと考えるべきだろう。もちろん国家運営と同様に、規模の拡大も忘れてはならないが、それは結果論であって、むしろダウンサイジングに由来すると考えるべきだ。理由:規模の拡大というのはいつでも発生し得る。ダウンサイジングは歴史的事象であり、それによりエンタープライズコンピューティングへのUnix、C、オブジェクト指向言語、それにPC(Wintel)の進出が始まった。

ダウンサイジングの結果、プログラマが必要な分野に、コーダがコーダなまま進出してしまい(同様にプログラミング言語の非エキスパートの設計者も設計者として進出してしまい)、しかもツールだけはプログラマを必要とするワークステーション由来のプログラミング言語が勝ち残ってしまいつつあるからだ。

流れには棹を差せ! 嘘から出たマコトしやか。

ダウンサイジングの結果もたらされたエンタープライズコンピューティング分野へのワークステーション分野の流入を止めることは不可能だと決め付けろ。

言語を知らない設計者や設計を知らない言語エキスパートは不要だ。

メモ)

ここを出発点から始め、第1の通過ポイントと想定する。ここでは要件定義=機能定義と設計=実装の2段階が必要。(その後の検証過程はここではスコープ外と規定)

第2の通過ポイントで、要件定義=機能定義=実装/検証の1段階にする。この段階で、コミュニケーション能力、洞察力、業務知識(以上、要件定義に必須)、インターフェイス定義能力(機能定義は核に収斂)も、必要となるだろう。右端については可能な限りの自動化が必要となるか、あるいは不要化(エンドユーザーにお任せ可能ならばそういう方法もあるだろう)していなければならない、あるいは、しなければならない。

現在は、木構造(階層型分業)からネットワーク型(機能型分業あるいはサービス単位分業)への移行過程だと見なした場合、このネットワークを太陽系に喩えられることができる。要件=機能と実装はまだ分離しているからだ。この分離を太陽と惑星にたとえてみる。1つの要件/機能を実現するために複数の実装が周囲を回転している。エンタープライズシステム全体は銀河系に喩えることができるだろう。

・サービスの疎結合、サービスを構成する個々のモジュールの疎結合

このネットワーク型の分業体制であっても、期限がある以上、全体の進行管理は相変わらず必要になる。

木構造型分業においては、情報伝達はツリー構造に従って上にも下にもまんべんなく行い得る。管理しやすい構造だ。

ネットワーク型では話が異なる。本来管理できない構造だ(各系の求心力によって位置関係が均衡しているんじゃないかな?)。そのため、新たな方法論がここにも要求される。

具体論:

固定レイアウトの帳票:HIPOで記述可能な領域→設計からコード化可能

これをネットワーク型で開発するメリットは? ――本質的には無い。

構造化では例外処理の記述が現実的には不可能(正確には無意味)。大域脱出はGOTOと等しくなるためそれを回避するには、エラーフラグのような大域状態変数の導入が必要(残りの工程では状態を判定してスルーする条件判断がすべてに必要となる)。かと言って、その帳票が固定レイアウトであり変化を求められないのであれば、モジュール分割も意味を持たない。レイアウトテンプレートへのデータ変換ライブラリがあれば、他は不要。→自動化へ。

_ 突然大人買い

ワイルドライフ (Volume1) (少年サンデーコミックス)(藤崎 聖人)

1〜6まで全部まとめて買っちまえなのだが、なんでだろう?


2004-04-05

_ 風は冷たいが天気は良い

よく眠ったはずが、まだ眠い。


2004-04-06

_ 風は冷たいが天気は良い

よく眠ってないので、なお眠い。

_ ちょっとイヤ(内部クラスは仮想化が甘いと思う)

Javaは、すべてのメソッドが仮想化されていると考えていたが、インナークラス(追記:のコンストラクタ)については静的な評価が行われるようだ。きっと仕様を確認すればそう書いてあるんだろうが(今はその余裕が無いので後回し)これは直観的では無い。
// O1.java
package com.example;
public class O1 {
    public void hello() {
	System.out.println("hello!");
    }
    public class I1 {
	public void hello() {
	    System.out.println("hello");
	}
    }
}
に対して
//O2.java
package com.example;
public class O2 extends O1 {
    public void hello() {
	System.out.println("hell!");
    }
    public class I1 extends O1.I1 {
	public void hello() {
	    System.out.println("hell");
	}
    }
}
に対するクライアント
// Oc.java
 package com.example;
public class Oc {
    public static void main(String[] args) {
	O1 o = new O2();
	o.hello();	 // 仮想化されているのでhell!
	O1.I1 in = o.new I1();
	in.hello();
	in = ((O2)o).new I1();
	((O2)o).hello(); // 当然hell!
	in.hello();
    }
}
コメントの通り、メソッドについてはO2のメソッドが呼び出される。
しかし、インナークラスのコンストラクタは、呼び出したインスタンスの静的なクラスの宣言が参照される。
と、ここまで書いて気づいたが、同名staticメソッドはどうなるんだ? それと同じ扱いってことかな? でも、インナークラスのコンストラクタは明示的にインスタンスに依存したメソッドなのだが(だから、インスタンス.newという構文)。
上の出力は以下のとおり。
~/test>java com.example.Oc
hell!
hello
hell!
hell
~/test>
最初の呼び出しで作成されるのは、O1$I1のほうで、呼び出したインスタンスoの静的な宣言に従っている。
っていうか、1時間ほどハマった。
追記:書いたらわかったが、クラスのコンストラクタを呼び出すわけだからクラス名が必要となり、かつそのクラスはコンパイル時に評価せざるを得ないわけだから、呼び出しクラスの静的な宣言が有効なのは、ある意味当然ではある。が、静的に解決させずに実行時にインスタンスのクラス名からコンストラクタを呼ぶっていうのがあっても良いような気も。その場合には、ファクトリメソッドを作っとけばいいのか……

2004-04-07

_ いやなに日記

いや、なに、その、あの、……と続く。

_ なんとなく違和感

nullがオブジェクトじゃないのがいかんのかな。
class Foo
 def initialize()
   @bar = nil
 end
 attr_accessor :bar
end
 
foo = Foo.new
if foo.bar.nil?   #foo.barがnilという状態か判定
  puts 'nil'
else
  do_something(foo.bar)
end
いちいち変数に代入しなければどうか?
 class Foo {
     Bar bar;
     Bar getBar() {
         return bar;
     }
 }
 ...
 foo = new Foo();
 if (foo.getBar() == null) {
    System.out.println("null");
 } else {
    doSomething(foo.getBar());
 }
 ...
ゲッタで戻されるのは常にBarのインスタンスであり、そのインスタンスが自分はnull(アクセス不可能な存在しない状態である)と答えるということだ。
どこにもモデル的な破綻はない。
追記:別に元ネタに反論する気はないのだが、見方が一方的なのが違和感の正体だろう。
基本的にはnullオブジェクトを返すというのが正解(nullを取るのが例外的な状態であれば最初からIllegalStateExceptionをスロー)だとは思うが、== nullというのは、JavaにおけるRubyのobject#nil?と同義だと考えればreturn null;を排斥する理由にはならない。
コンテキストが2種類あるからだ。
  • 直接の操作対象のオブジェクトが現在その属性を返送できないという状態(元ネタで指摘されている状態)(追記:これは1---[1|1..*]の関連の場合だけのような気がしてきた)
  • 操作対象のオブジェクトの属性から返送されたインスタンスがnullだという状態(1----0..[1|*]の関連で現在0)
後者であれば、return null;で良い。まあ、配列ならば要素0の配列を使用すべきだとは思うが、それは利便性の問題に過ぎない。あと、1対0..*の関連なら最初からコレクションのインスタンスを生成しておいて常にそれを元にして(イミュータブルにして)返すのが正しい実装だろう。
追記:つまるところ、object == nullという記述は、objectに対して「おまえはnullか?」というメッセージの送信なんだから、全然、おかしくないということ。
呼び出し側がいちいちメッセージをオブジェクトに送るのが面倒くさいという理由なら別に、利便性の追求は悪いことじゃないからどうでもいいです。その場合は、#isBarNullは単なる便利な(オブジェクトの取得をスキップして直接該当オブジェクトの)状態判定が可能なヘルパメソッドかな。

_ まとめ

オブジェクトの関連に着目するならば、

1対0...1の関係ならば、return null;またはreturn インスタンス; というより何も考えずに、return フィールド;

1対{0|1}...*の関係ならば、return コレクションフィールド; ミュータブルかイミュータブルかはメソッドの定義次第。単なるゲッタならばイミュータブル。最小数と最大数が固定なら配列でも可(100万要素なら配列のほうが絶対的に早いから、配列はパフォーマンスオプションとして利用できる)。

1対1 これでnullなのは異常な状態なんだから、アクセスしたやつがNullPointerExceptionで死ぬも良し、IllegalStateExceptionをスローするのでも良し。

取得可能かどうかの判定メソッドというのは、オブジェクト間の関連とは無関係なヘルパメソッド。

もちろん、それがオブジェクト間の関連ではなく、操作しているオブジェクトの状態ならば、その状態の取得メソッドとなるからヘルパメソッドではない。

_ って言うか

最近は、TELL, DON'T ASKを再考しているところなんで、最初から違う方向で片づけるべきだという考えに近づいている。つまり、
 Bar bar = foo.getBar();
 doSomething(bar);
ってのは、fooにASKしている。これをTELLに変えればこの問題は起きない。
 foo.doSomething();
 ...
class Foo {
  Bar bar;
  void doSomething() {
    if (bar != null) {
       bar.doSomething();
    }
  }
}
なぜ、ASKする?

_ Tell, Don't Ask

プラグマティックプログラマーから。

プラグマティックに考えると値オブジェクトの場合はどうよ? とかあるけど、値オブジェクトってのは方便だからそれを基準に考えてもしょうがなかろう。

atomicityまで考えると、状態問い合わせっていうのはまずいですね。その場合は、上のが全部、やばくなる。TELLの例にsynchronizedを付ければOKかな?

_ おまけ

達人プログラマー―システム開発の職人から名匠への道(ハント,アンドリュー)

本そのものは読んでもいないのに書影を貼ってみたり。

プラグマティックプログラマーの本。とっても良いらしい。

_ どこまでTellできるのか

えーと、良心の問題として付け加えると、自分で完全に制御できるものについては、こんな感じになるけれど、仕様を切って渡す場合には、手続き的になるのは気にしてないです。また、できたプログラムを後はよろしく、する場合にもask, get, and do it myselfのようなものは書きます。(追記:つまりトランザクションスクリプトパターン)

仕様をプログラムに落とし込むところで、誰もがプラグマティックプログラマーのように考えられるとは想像できないし、仕様というものを箇条書きにしろ、文章で書くにしろ、手続きとして記述せざるを得ない以上、また、細粒度のオブジェクトまでダイアグラムに書くのは無意味(だと思うからTDDマンセーなのだが)だと考えているから、誰もにオブジェクトのインタラクションとして頭に浮かべろというのは、いささか無謀ではないかとも思います。そこで工夫をしながら限られた時間の中で、やってのければそれに越したことは無いというスタンスです。

ちなみに、== null が複数の意味を持つというのは理解できませんでした。C++だとオペレータオーバーロードがあるから複数の意味を持たせられるけど、そうでなければ左辺のオブジェクトにnullかどうか問い合わせるということ以外にどんな意味があるんでしょう?

ゲッタを使って取り出したオブジェクトに、お前はnullかと問い合わせるのがダメで、取り出す前に問い合わせるのがOKってのは、カプセル化を破ってると端的には思います。だって、自分が存在しているかどうかは、そのオブジェクトが知っているべきことですな。そのオブジェクトの持ち主が知っているってのは持ち主がエラ過ぎです。でも、持ち主が知っていても構わない場合もあって、それはその持ち主と持たれているオブジェクトの関連によって決定されます。一意ではありません。でも、== nullという記述は一意です。

(追記:nullが一意ではないという意味かな。nullはan invalid or uncreated objectだから2種類の意味を持つ。それにそもそも型を持たない。だから一意ではないということなのかな。とは言えある型の変数に入れられたら、その型のオブジェクトの参照という意味付けはされているわけだし、invalidかuncreatedかはその時点で問うても意味ないような気がする。)

ちなみに、マジックナンバーは大好きなので、壁に/etc/magicをプリントアウトしたものを貼っていたりします(ここまで書くとネタだと思うかな)。

_ さらにおまけ

なお、Javaでも、こういうことはできます。
public class St {
    public static void main(String[] args) {
	String s = null;
	System.out.println(s.valueOf(123));
    }
}
sは、Stringオブジェクト(追記:わけわからん。正しくは、「Stringオブジェクトの参照」)なので、StringクラスのvalueOfメソッドは呼べます。ただし、インスタンスは== nullが真なので、インスタンスメソッドは呼べません。
本日のツッコミ(全7件) [ツッコミを入れる]

Before...

_ arton [そんな解釈を許容させるということは、モデリングが失敗しているのではありませんか? その例だと、順に状態遷移があるオブ..]

_ arton [TDDが好きなのも当然、こうやってイテレーションするスタイルなんだからしょうがないね、推敲大好き。 モデリングが失敗..]

_ Saisse [インターフェースと実装という切り口ならば...と思いましたが、もう少し煮詰めてみます。 getHoge()に機能を..]


2004-04-08

_ NULLとnull

完全にネタなので、だからどうしたっていうようなことではないので注意。また、非常に限定された知識だけで書いてるからこの内容に価値があるわけでもない。でも、おもしろいから書く。(追記:要するに、SimlulaとかSmalltalkでのありようを知らない人間が書く内容じゃないだろうって意味であって、別にデタラメを書いているわけではないと、注しておこう)

初めての人のためのLISP (ソフトウェアライブラリ (3))(竹内 郁雄)

次の2つの概念が重要じゃ。

atom。(後略)

もう1つがnull。nilと似ていると思ったとしたらエライ。事実、英語の意味は両者とも同じだ。nullを使うと、nilだけがハイと答えて来る。それ以外のものはイイエと答えるわけだ。

この世界ではnullは、マジックナンバーどころか、万物は陰と陽から成立しますというような世界の陰に相当するくらい重要な概念。(とは言え、ここでのnullは述語で名詞となるのはnil)

よく似た言葉にNULLがある。これは

(VC++6のstdlib.h)

#ifndef NULL

#ifdef __cplusplus

#define NULL 0

#else

#define NULL ((void *)0)

#endif

#endif

で、Cのほうでは何も指さないポインターという意味だが、C++では単に0というだけで、それがメモリーのアドレスなのか数値なのか文字列の終了マークなのか、なんだかさっぱりわからない。

で、NULLを想像してマジックナンバーというのならば、それは確かに魔法の数字以外の何者でもないので理解可能かも。

とは言え、JavaはJavaで、LISPでもなければC/C++ではない。その言語の世界観がある。

そこでちょっと考えてみる。

Javaのコーディング規約では定数は大文字とされている。したがって、nullは単なる定数(constants)のNULLではない。先頭が大文字のNullでもない。だからクラスではない。nullは全部小文字だ。このタイプのものは他にはtrueとfalseがあるだけだ。ちなみにこっちは直定数(literals)。

これはC/C++のNULLよりは、はるかにLISPのnil(nullではなく)に近い。違いは、LISPのnilはfalseの意味も持つこと。だが、これはJavaは型が厳密でbooleanとObjectの参照を分けざるを得ないからnilではなくnullとfalseに泣き別れさせたという印象を受ける。

たった、3個しかないシンボルで表記されたリテラル(数値リテラルや文字列リテラルはシンボルではない)について言えば、== false、== true, == null および != false, != true, != nullはすべて同等に一意である。まあ、バグを少なくする記述方法として条件節内で明示的にtrueやfalseを書くべきではないというのはあるから、常に== nullとやって検査する必要は無いけど。

_ メソッド名補完

VS.NETに比べると、(使った時点/使ったマシン上では)Eclipse、NetBeansとも僕には耐え難いほど反応が鈍かったので、JavaはEmacs/Meadowで記述している。だから意識してなかったが、考えてみれば== nullってのはメソッド名補完がきかないから、イヤンと考えるっていうことはありそうではあるなぁ。

_ 宣伝というか報告というか

日経ITProにコラムを書かせていただいています。

技術者からの視点ってやつで、仕様、設計、実装、開発プロセスあたりを書いていく予定です。


2004-04-09

_ おもしろいからもう一発

これはやり過ぎだと思う。でも、こういうのもありかも。
public interface BarReceiver {
  void setBar(Bar bar);
}
 
public class Foo {
  private Bar createBar() throws OperationException {
    ....
  }
  /**
   * 〜して〜して〜したうえでbarを設定する。ただし〜の場合にはbarを設定しない。
   * @param barReceiver barを設定するオブジェクト
   * @return barを設定したら真。設定しなければ偽。(注:明示的にnullを設定することはない)
   * @throws OperationException 処理に失敗。この場合、barの設定は行われない
   */
  boolean fetchBar(BarReceiver barReceiver) throws OperationException {
     boolean isBarCreatable = false;
    ...
     // いろいろ前提条件のチェック
    ...
     if (isBarCreatable) {
       barReceiver.setBar(createBar());
     }
     return isBarCreatable;
  }
}
 
public class Client implements BarReceiver {
  private Bar bar;
  public void setBar(Bar newBar) {
    bar = newBar;
  }
  void someMethod {
    ....
    Foo foo = new Foo();
    bar = Bar.createDefault();
    foo.fetchBar(this); // 設定/未設定を問わない
    bar.doSomething();
    ...
    bar = null;
    if (foo.fetchBar(this)) { // 設定された場合のみ処理
       bar.doSomething();
    }
    ...
  }
}
これがやり過ぎなのは、Clientクラスが全知全能なところ。こいつはthisを知っているのは当然として、FooもBarも知っている。また、直観的なインターフェイスかどうかは怪しい。
こういうのもありかなぁ、というのは、Fooの実装の自由度の高さ。およびClientがBarが未設定の場合の処理を制御できる点。
この場合、BarReceiverは、Barのインナーインターフェイスか、Fooのインナーインターフェイスとしてスコープを狭めたほうが良いかも知れない。Clientのやり過ぎ性をそれによって気分的に抑制する。
BarがFooに特化した処理オブジェクトの場合とか(たとえば、Fooの後付けのビルダーとか)には面白いかも。
IoM(Inversion Of Method)メソッドの逆転(って言うか、単なるコールバックだけど)。考えてみたら列挙処理とかだと良くあるパターンだな。

_ さらに考察

Tellでやる場合、追加に弱いというのがある。

呼び出し側と、呼ばれる側、必ず2つのソースが修正される(状況によっては、できるだけ少ないファイル数だけ交換したい場合もある)。

スクリプティングだと、処理の追加は、スクリプトメソッドの修正で済ませられるかも知れない。

そのため、Barを取り出すという処理が不可欠なのだと前提する。

もともとの論点は、へまなプログラマはnullチェックしないとか、nullチェックは変だ、ということで、問い合わせメソッドを追加すれば解決ということだった。しかし、nullチェックしないへまなプログラマは問い合わせメソッドも呼ばないかも知れないから、抑止効果は限定的だ。

一方、Tellにしろ、上の方法にしろ(戻り値をチェックしない、デフォルトもセットしないだとだめだけど)、最初から検証を不要にしているから、論点をほぼ完全に(だって戻り値をチェックしなかったりしたら)クリアしている。Tellは手元にBarを戻さないが、上のやつ(コールバックだけど)は手元にBarが戻る。

あと呼び出しの原子性についていえば、前提がnullチェックもしないへまなプログラマを想定しているのだから、当然、クリティカルセクションを作るかどうかも怪しいので状態チェックメソッドではだめでしょう。でも、Tellやコールバックなら、Fooの実装者が制御できるから安全。

ルール(手順といっても良い)を減らすというのが良いインターフェイスだと思う。とは言えケースバイケースだけど。一般論として。

_ さらに進めて

こっちのほうが好きだな。ここまで来ると、わりと普通のあり方となる。
public interface BarReceiver {
  void doWithBar(Bar bar) throws OperationException;
}
//Fooはほとんど同じ(呼び出すメソッドが上のに変わる)
 
//Client
  void someMethod {
    ....
    Foo foo = new Foo();
    foo.fetchBar(new BarReceiver() {
        public doWithBar(Bar bar) throws OperationException {
           .. barを使った処理
        }
    });
    ...
  }
後腐れないし、処理の実行順序はソース上と一致(無名インナークラスのメソッドが実行されるのは、記述した場所と同じ)しているから、スクリプトの流れがとぎれない(ブロックは途切れるが、そこは適宜finalを使ったり)。
この場合、Fooは、Barの生成方法は知っているが、それ以上Barのことは知らなくて良い(完全なTellだと知っている必要がある)。したがって、全知全能のスクリプターのClientに対して、Fooは単なる値オブジェクトに毛が生えただけのオブジェクトコンテナの状態に留めておけるところがミソかも。

2004-04-10

_ 初台

なんだかんだと初台には縁がある。お隣の幡ヶ谷は甲州街道で通り過ぎるだけなんだが。

でも、もうアスキーは無いんだな。


2004-04-11

_ シマチュー

中野は紅葉山に蟠踞し、付近の狭い道を塞いでしまうのが特徴。

_ 文章を書くこと

知ってることを枚数気にせず書くのは、それなりに簡単。

調べたことを再現させることも、J2EEのDeploytoolのようなシロモノじゃなければどうってことはない。

概念を知ってる人に実装を説明するのも大した問題じゃない。

概念そのものを説明するってのは、気が遠くなるようなことだな、しかし。

問題は相手の知識レベルをどこへ置くかだ。

ユニットテストというのが、人間が目で確認する結合テストの直前の機能監査のようなものしか意味しない世界の人に、どうやったら、ユニットテストするんだから、非依存性重要とかって、説明できるんだろう? そりゃ、ユニットテストというタームを引っ込めるしかないわな。

その前に、テストファーストから教えなきゃだめですな。

しかもその前に、オブジェクトインタラクションの決定ってのが、机上じゃほとんど無理(もちろん、実装と同程度に時間をかければできないことがないだろうが、そりゃ無駄でしょう。ということから、テストファーストというかTDDとMDAというのは同じ現象に対する実装側および設計側からのアプローチで目指すところは同じではないかとか)だということをどうやって説明すりゃいいんだろう。「机上じゃ無理? そりゃ、根性が足りないからだビシバシ」ですか? (VDMという開発手法はそのへんを考慮しているらしい)

って言うか、歴史が証明してるってのじゃだめなのかな?

MFC1、2、3が無くて、4、5 + ATL、6 + ATL、7 + WTLっていうのは別に商売のためのバージョンアップということだけじゃない。OWL1、2の断絶だって妙な記法をマクロに変えたということだけじゃない。Strutsの1.0と1.1(とその間のRCとか)の差ってのも、別に気まぐれで変えている訳では無い。

骨組みしか提供しないフレームワーク(しかも十分な開発力を持った)ですら、最初から完全なモデル(MVCのモデルじゃなくて、モデル図のモデル。オブジェクト(動的)/クラス(静的)インタラクションモデル)を提供できないのだ。

まして、アプリケーションのモデルがそんな簡単に組めるわけがなかろう。

リサーチに時間をかけて最初から完全なモデルを構築するという、開発モデルの問題点は、時間をかけるってことが、既に問題点だということだ。

あるいは、OOPのメリットって、再利用性ですよね、というナイーブな人を前提として、AOPのメリットを説明するってのも困難かも知れない。へたすりゃ、単に「おおー、また3文字のバズワードですな」で終わりだよチャンチャン。

_ ああ(驚きの声)

英語風だとSeaser。今の今まで間違えていたですよ。あぶない、あぶない。それにしてはなぜ、orgに行けるのか? それはブックマークのおかげですなぁ。


2004-04-12

_ インターフェイス重要

しかし、CORBAとかCOMとかだとIDLで定義したインターフェイスと実装はイヤでも分離されるわけだが、それが正しいとJ2EEな人達が言うような時代になるとは思わなかったといえば思わなかった。

It's best to program to interfaces, rather than classes.

恣意的な引用

思えば、ATLとかでCOMのコンポーネントを作る場合、最初はWizardでテンプレートを生成するわけだが、次にやるのは、IDLにメソッドを定義することだ。helpstring属性を記述したりしながら。

で、midlでヘッダを生成して、それを実装クラスのヘッダにコピペして、=0とかを削除して、次に編集したのをソースにコピペしておもむろに実装に取り掛かるわけだが、ほとんどこういう作業になるってことなんだろう。

最初にinterfaceのソースをJavadoc書きながら作って、それをコンパイルしてからおもむろにclassの実装に取り掛かるということだ(少なくてもEmacsで記述する場合には。もしかしたらEclipseとかだとVBでCOMのコンポーネントを作るみたいに、いきなり実装するとpublicメソッドを抜き出して勝手にinterfaceを作成するとかだったりするのかも)。

ということはだ。

あれだけクソだ、カスだ、と言われているVB6のOOPだが、あれでも十分ってことになる。少なくてもインターフェイス継承は可能なんだから(実際、VB6でストラテジパターンというのはやっている)。

かくして、ますますOOPという言葉が意味するものが人によって全く異なってくるということでもある。

例)

A「OOP、もちろん経験ありますよ」

B「ほー、でどんな言語で?」

A「VB6です。」

B「(ニヤリ)」

A「やっぱーり、違いますかねぇ(卑下)」

B「うーん、あれはねー。やっぱりJavaとかじゃないとねぇ、OOPとは言えないんじゃないですかねぇ」

でも、Aはストラテジパターンで業務ロジックを実行するアプリケーションを組み立てていて、Bは継承地獄でのたうっているという罠とか。

#ogijunさん、一昨日は失礼しました。思い出しましたというか、確認しました。

本日のツッコミ(全7件) [ツッコミを入れる]

Before...

_ Saisse [わかりにくくてすみません。 ソースにclass ClassAがあったとしたら頭の中だけでinterface Clas..]

_ arton [ああ、なるほど。ただ、それならば、別にC++のヘッダを引き合いに出すことはありません。ヘッダは必須ではないからです。..]

_ WR [インタフェース重要!っていうのは、Coad先生が昔からひたすら力説してた気が。 #「J2EEな人たち」を誤読している..]


2004-04-13

_ スーパーなものづくり

以前書いた『町工場・スーパーなものづくり』だが、今日は今日とてこんな条りにしびれた。

NC旋盤機をはじめとしてME工作機械が導入された当初は、「けっ、ハンドルがない道具を使えるかってんだ」っていうような職人からの軽蔑と、「おー、これで高い金払って熟練工を雇う必要ないですなぁ」っていうような企業人の期待ってのがあったわけだが、ところがどっこい、実際に使っているうちに皆、わかってきた。これは、熟練労働者が使えば使うほどより優れた結果が生み出されるのだ、と。(もちろん、どうでも良い仕事なら、素人に毛が生えたような職人でも使えるという面はある)

で、実際に、工場に要求される加工とかは、どんどん精度も上がり、複雑になり、ようするに機械や素人のような連中には作れないものになってきた。だから、熟練労働者がME化された機械を使うのが重要だってことだ。

――要約

それって、OOPLですか?

「てやんでぇ、いちいちvtbl経由(メソッド名探索でも良いけど)でcallできるかってんだぁ」っていう声と、「これで再利用性でウマーですなぁ」のことですか? でもどうだい、蓋をあけてみると、誰がそれをうまく利用できるのかとか。

あるいは、ロボット化工場がうまくいかなかったあたり(70年代のことかな?)

そりゃ、ロボットは正確に文句も言わず飯も食わず作りつづけることができる。しかし、100万個作っても同じものだ。

人間様は、1000個も作らされりゃ、しまいにゃうんざりして工夫を始める。その結果、これまでとは違ったものが生み出される。もっとうまい方法も出てくる。

永遠に同じモノをこさえてりゃいいんだったらそりゃロボットで十分だろう。しかし、永遠に同じモノこさえていたら、そりゃだめだろう。

――要約

あるいは、目からウロコの流れ板じゃなかった、流れ工の条り。

肩から道具袋ぶら下げたイナセなお兄さんが工場へやってくる。

「へぇ、悪かない仕事場だな。ここで働いてやってもいいぜ」

「ちょっと待った。ウチは仕事にゃ厳しいよ。まずは、なんちゃらを削ってみな」

「へ、なんちゃらじゃ物足りねぇから、なんちゃらちゃらでもいいかい?」

「できるもんならやってみな」

「お安い御用だ……ガリガリガリ……ほれ、どうだい」

「おー、是非とも働いてってください、おながいします」

てな調子でやって来て、

「困った、困った」

「どうした親方」

「こんだの注文は、星型のやつがこうやってこうやってピタッとくっつくってような注文だ。断るしかないよなぁ」

「ふーん、そいなら、こないだ働いたことでやってみた、アレでいけそうだな、ちょっと待った……ガリガリガリ……こいつでどうよ?」

「どれどれ?――キタッー! じゃ、早速注文を受けてくるわ」(退場)

「じゃ、おまいら、おいらが教えてやるから、ここに集まれぇ」

「ふむふむ」

それまでその工場じゃできなかったような技術を伝播してまたふらっと去って行く。

こういった風来坊のような流れ工が、結果的に最新の技術を方々に播いていったというような事実が書かれているのを見たことがない。だいたい、職人気質の気難しい、腰が据わらない……のようなネガティブなことばかりが強調されるようなので、こういう事実を記録しておく。

――要約

おいら、ここ読んだとき、なんとなくなかださんやもりきゅうさんのことが目に浮かんだぜ(実際に流れてるかどうかは知らないけど)。

ハッカーズ(スティーブン・レビー)

なんか、読めば読むほど、たとえば、レヴィのハッカーズとかに通じるものがあっておもしろい。

_ やっと落ち着いた

Seasarのからさわぎに参加させていただきました。

個人的にはSeasarでのAOPの扱いに1番興味を惹かれましたが(Seasarとは関係なくIoCコンテナについては、意味はわかるんだけど、判断はまだ留保しているのだが、それがなぜかは全然、考えがまとまっていない。もう一越え、何かがあるような気がするってことなのかな)、それ以上に、はてなダイアリーによる繋がりというものにいろいろ考えることがありました。

はぶさん、ひがさん、まさたかさん、高井さん、熱い一日をどうもありがとうございました。

追記:ITProにレポート(? 後述)を書かせていただきました。

?の理由: すみません、へたれです。「からさわぎ」という名前は使いませんでした。Seasarだけで完結させずに、権威によりかかる手法も使ってます(もうちょっと言い方を変えると有名なものを引き合いに出す手法ーーこれは潮流を示すという意図もあるわけですが)。しかし、一番の問題は、うまくおさまらなかったため、開発者のひがさんのお名前が出ていないことです。ひがさん、ごめんなさい、今度はもっとうまく考えます。

本日のツッコミ(全1件) [ツッコミを入れる]

_ ひが [いえいえ、何の問題もありません。取り上げていただいてどうもありがとうございました。]


2004-04-14

_ インターフェイスとVB

誤読ってことはないです。

一面的な見方で書いているので(「恣意的」って言葉でそれを否定はしているけど)そう読めるようにしています。

VBについては、そういう一面的な(ネガティブな)見方のほうを良く見かけて謎ってのがあるので、入れ子にして書いてみたのです。ここではJavaが一面的な(ネガティブな)見方の対象として記述されています。

VBは2面性があって、単に好き/嫌いだと嫌いな言語ですが、たとえば

・値を戻す呼び出しは引数に()を付け、そうでなければ()付けないかまたはcall を付ける

->バッカじゃなかろうか。そんなもの1種類にしておけ

->メイヤー言うところのファンクションとプロシージャの分類の強制=圧倒的に正しい

・条件節で等価性検査に==じゃなくて=を使う

->紛らわしい(C頭)

->文脈依存で演算子の意味が変わることより、演算子の種類を少なくしておくほうが覚えることが少なくて済むから良い

・条件節を全部検査する

->紛らわしい(C頭)――って言うか、これには泣かされた過去があったり

->書かれていることは実行されることとしたほうが明確である

などなど、Cと違うだけで、それはそれで合理的な言語デザインなのです。

でも、どうもカス言語みたいな印象が強いようなので、それはなぜかと考えると、要は、使い方にあるのかなぁ、と。

で、現在のCOBOLの置き換えとしてのJavaというのが、適用業務の置き換え(使われ方)なら良いのですが、設計手法(使い方)までそのままだと、簡単にVBのようになりかねないだろうな、というあたりです。(これは他人事)

上で、条件節の評価で泣かされたと書きましたが、結局、VBをなめてかかって(だってお手軽に使えるから)、最初に言語仕様(しかし、どこにあるんだ?)を読まずにほいほい書いてしまったのが原因です。これは逆にC++を知っていれば、同じようにJavaでもほいほい書いてしまう可能性がある、でもそうすると、C++にはインターフェイスは無いので(ちょうど、VBにはプロシージャとファンクションの明示的な区別があるのと同じくJavaには明示的なクラスとインターフェイスの区別がある)最初から設計に問題が出てくるかもなぁ、という自戒の念を書いたのです。(これは自分事――でも無いか)

ちなみに、昨日るいもさんから仕入れたネタ。

――MSDNを読んでいたら「VB6で実装継承する方法」というのが出ていた。で、読んでみたら、コンポジションの説明が出ていた……(くず折れる人)

VBをカス言語に仕立てたのは結局MSではなかろうか?

_ rjb(sparc)

~/ruby/rjb-0.0.6>ruby test.rb
start RJB(0.0.6) test
Loaded suite test
Started
Error occurred during initialization of VM
Signal chaining not allowed for VM interrupt signal, try -Xusealtsigs.
~/ruby/rjb-0.0.6>
Rubyがシグナルを使うからか……。先は長そうだなぁ。っていうか、どうやって-Xxxxを与えるのか調べなきゃな。

_ ビッグエンディアンか!

本日のツッコミ(全2件) [ツッコミを入れる]

_ takubo [プロのコード、アマのコードが盛り上がってますが、"VBの2面性"、思い当たることばかりです。 使いづらいところもあり..]

_ arton [いえ、全然、ずれていないと思います。確かにクローズドな開発中心+MSの売り方の問題(しかも誤用した用語を押し付けたり..]


2004-04-15

_ rjb

LinuxだとJNI_GetDefaultJavaVMInitArgs がSEGVと書いていたが、JNI_GetDefaultVMInitArgsに与える引数を間違えていた。

JDK1_1InitArgsを使っていたが、実際には、JavaVMInitArgsを使用する。

Solarisで、-Xusealtsigsを与えるためにいろいろ調べたら、結局、JavaVMInitARgsのJavaVMOption *optionsメンバに設定するらしいとわかったからだ。

で、JavaVMInitArgsを利用するように修正したら、Linuxでも通るようになった。では、JDK1_1InitArgsってのは一体どこで使えるんだろう?

追記:寝ぼけてるようだ。1_1なんだからJDK1.1用で、Java2(1.2)以降は、JavaVMInitArgsになったということだろう(データメンバが少ないので逆に考えてしまったらしいが、万能のoptionsメンバが追加されてるわけだし)。

_ あわや読まずに捨てるところ

なんか、最近やたらめったら「アドレス変更しました(音符マーク)」というサブジェクトのspamが来る。とにかく来る。連続5個くらい来たりする。

という状況の中で、「サイト移転のお知らせ」というのが来たので、即効削除しようとしてふと一瞬出た文面がそれまでと調子が違うので、あわてて手を止めた。Fe2+さんからのRuby256倍勝手に正誤表の移転のお知らせだった。危なかった。

で、思い出したが、ここまでspamがガンガン来ると、もう、「常識ではsubjectはASCIIで書くべきですな」とは言えないし(「アドレス変更しました」はとりあえず置いておいて)、用件だけ手短にってのもあまりうまくなさそうだな。

_ なんとなくやってみたが

プロのコード、アマのコード(4/23アンカー変更) 面倒な部分は再利用
import java.io.*;
public class Gcp {
    private static final String te[] = {"グー", "チョキ", "パー"};
    private int win;
    private int loose;
    private int fair;
    private BufferedReader reader;
    private final Result[][] state;
 
    public Gcp () throws IOException {
	reader = new BufferedReader(new InputStreamReader(System.in));
	state = new Result[3][3];
	state[0][0] = state[1][1] = state[2][2] = new Fair();
	state[0][1] = state[1][2] = state[2][0] = new Win();
	state[0][2] = state[1][0] = state[2][1] = new Loose();
    }
    private abstract class Result {
	void execute(int you, int com) {
	    System.out.print(" コンピュータ:" + te[com] + 
			       ",プレイヤー:" + te[you] + ":");
	}
    }
    private class Win extends Result {
	void execute(int you, int com) {
	    super.execute(you, com);
	    System.out.println("あなたの勝ちです!");
	    win++;
	}
    }
    private class Loose extends Result {
	void execute(int you, int com) {
	    super.execute(you, com);
	    System.out.println("あなたの負けです!");
	    loose++;
	}
    }
    private class Fair extends Result {
	void execute(int you, int com) {
	    super.execute(you, com);
	    System.out.println("引き分けです!");
	    fair++;
	}
    }
 
    public void execute(int count) {
         win = loose = fair = 0;
	for (int i = 0; i < count; i++) {
	    int you = read();
	    int com = (int)(Math.random() * 2 + 1);
	    state[you][com].execute(you, com);
	}
	System.out.println("プレイヤーの勝敗数:" + win + "勝" +
			   loose + "負" + fair + "引き分け");
    }
 
    private int read() {
	for (;;) {
	    System.out.print("あなたの手(0:グー、1:チョキ、2:パー)");
	    String s;
	    try {
		s = reader.readLine();
	    } catch (IOException e) {
		continue;
	    }
	    if (s.length() > 0) {
		if (s.equals("q")) { // バックドア
		    System.exit(1);
		}
		try {
		    int n = Integer.parseInt(s);
		    if (n >= 0 && n <= 2) return n;
		} catch (NumberFormatException e) {
		}
	    }
	}
    }
 
    public static void main(String[] args) throws Exception {
	Gcp gcp = new Gcp();
	gcp.execute(5);
    }
}
添削結果:
1.コメントがありませんね
プログラムのどこにもコメントが付けられていませんね。プログラムを読みにくいと感じました。
(追記:× この程度の行数のまとまりを読めないのはだめ。ただし各メソッドやフィールド、クラスにJavadocは付けるべきでしょう。)
(更に追記:そうだ、コメントをつけましょうというのを見るたびに感じる違和感ってのは、単純なことなのだ。あなたがプロなら、読む相手もプロなのだ。プロをなめるな、ということだ。アマはプロの能力を知らないから文章による解説が必須だと考えてしまう。大丈夫、あなたの先輩や同僚はあなたと同等かそれ以上のプロだから、まともなコードを書けば、必ずそれを理解するってことだ)
2.おやおや実装継承ですか?
たかだか1行の出力くらい、バーといきましょう。せこいですよ。
(追記:微妙。状態表示をスーパークラス、結果表示をサブクラスというメッセージ表示の責務分割と考えれば合理的。それにこれ以上の継承=スパゲッティ化はありえないはず。取り得る数を考えればせっかく実装継承可能な言語なんだから使わなければ無駄。7項を参照)
3.おやおや3文字変数ですか?
comってcomponent object modelですか? それともcommunication portですか? さっぱり意味がわかりませんね。せめて、computerPlayerにしてください。
(追記:微妙。正直最初comとは何かわからなかったが、youの対照だということはわかるから、ゲームの言い回しとしてはありなのかも。これはオリジナルから持ってきた)
4.おやおや1文字変数も使ってますね
iではなく、kaisuのほうが良いでしょう。sではなくyomiTottaMojiretsuにしたほうが適切ですね。
(追記:×。これがスコープが短く、初期化時が明確なので意味の失いようが無い例。特にkaisuはともかくyomi……はダメな例。なお、英語ローマ字混じりは避けるべきなので、kaisuならKati、Make……、Win、Loseならcountかな)
5.0,1,2は定数にしたほうが良いでしょう
0をGOO、1をCHOKI、2はPAAとすべきですね。
(追記:○。特に最初の配列の初期化時)
6.バックドアとはなんですか?
デバッグ中はともかく、ちゃんと削除しましょう。(うむ、これは文句なく正しい)
(追記:○。もちろん)
7.詰めが甘いですね
わざわざ、win, looselose(次項を参照) ...なんていうフィールドを作っていますが不要ですね。Resultのフィールドとしてint countを置いて、実装継承しているのだから、Result#executeでカウントアップすれば済みますね。
(追記:○。最後の結果表示でwin.getCount(), lose.getCount()...とすれば良い)
8.誤った綴りを使っていますね
looseじゃなくてloseですよ。素直にKati, Make, Aikoとすれば、こういう間違いは防げますね。っていうか、どおりでなんでlooseがlostになるんだ? と思ったはずだ(で、辞書見て、「単語が存在する」のを確認してそこで終ったところがバカですね)。
ご指摘感謝。
(追記:○。心より恥じるってやつですね。)
#追記:ネタ的(微妙)なものに×、正しいものに○を付けた
9(追加).メソッド名がいい加減すぎです。
なんでもexecuteはいかがなものでしょうか? せめて、Resultについてはjudgeなどにすべきですね。
(○。そうだな)
10(追加).ところで、根本的に間違えていますね
comさんが0を出すことってありえるか考えてみたらどうですか?
(○。確かに、その通り……
11(追加).「面倒な部分は再利用」とか言っていますが、「再利用」ってそんなにいいですかね?
つまりコピペは悪ということですね。
(int)(Math.random() * 3)。「1.0より小さい正の符号付doubleを返す」
(○。うむ、心より恥じる。っていうか、ちゃんと添削しといてくれよ。)

_ この時、何が起きている?

i686 Win32 J2se1.4.2では、
public class K {
    public static void main(String[] args) {
        double k = 0.9999999999999999;
        System.out.println("result=" + ((int)(k * 3))); // -> 2
        double j = 0.99999999999999999;
        System.out.println("result=" + ((int)(j * 3))); // -> 3
    }
}
となるけど、代入時点で既にjは1.0になっているのか。
本日のツッコミ(全19件) [ツッコミを入れる]

Before...

_ るいも [(int)(Math.random() * 2 + 1); わははチョキさえ出してれば負けないぞ!]

_ るいも [あ、10に書いてありましたね。すんません。]

_ arton [違いますよ。るいもさんの書き込みを見て書き足したんです。「確かにその通り」の部分がリンクになってます。]


2004-04-16

_ テストファースト

頭の中でインターフェイスを考えるってのは、まさにTDDの効果の1つだったな、と再確認。

確かに、再利用不要なインターフェイスであれば、最初からクラスとして設計するけど、その場合であっても考えるのはインターフェイスでした。

_ もうちょっと考えてみた。

特徴:

Saisseさんのモデルは、グーチョキパーがコード上で可視化されるから確かに読みやすそう。

tpircsさんのモデルは、Saisseさんのモデルに加えて、Playerがあるからコンピュータの手の選択方法の変更に強そうだし、またJudgementの導入効果は大きそう。

僕のは、(現実的には4次元=34が限度だろうけど)プレイヤー(や手――この場合チャートは相当でかくなるが)の追加に強いはず――このへんは通信制御プログラミングからの影響が強いから、相当コンサバなアプローチではないかな。って言うか、vtbl経由で呼べるかってんだい、みたいなもので、おそらくSaisseさんの言っていることが一般的には正しいと思います(が、自分の好みを優先しているから「x. 勝敗判定がわかりにくい」という添削結果は作らない)。

同じプログラムでも、どうモデル化するかで違うものになるところがおもしろい。

おもしろいんだが、これをもし問題だと考えるのであれば、将来を見越したユースケース分析ってのを重視するか(分析重視)、後からいかようにでも組み合わせを変更できるようにクラスを小さく分けていくか(モデル重視と言ってもTDD的な実装時の分離のような)のどっちかになるんだろうか。すると、最初の時点でtpircsさんのかな。

_ アンテナ

っていうか、書いて、コミット、読んで修正、コミットというスタイルだと書きかけのを読まれるんで、あまり嬉しくないが、これもTDDならではということだな。というか、公開サーバーでそれをやるのが間違い(というか、赤や黄色をコミットしてはいかんだろう)。が、ここは「おいらの家」だからあまり気にしない。家はハウスで家庭はホーム、すると「おいらの家庭」ですか?

_ さらに追加(勝敗判定の箇所)

昨日のを読むと、添削結果の実装継承のところで、Resultからの継承でexecuteメソッドの意味を2重化しているのがわかる(かたほうはどの手が入力されたかの状態表示で、もう一方が勝敗の結果表示とか)。

ここを、ResultをJudgementとして、この中で元のResuslt#executeの表示と、勝敗表の検索(元のGcp#execucteで実行しているやつ)を行うのが役割分担としては正しいのかなと思います。そうすると、win, fair, loseの各カウンターはJudgementのインスタンス変数となり、元のWinとかloseとかは結果表示とカウンター設定用のJudgementのインナークラスとなる。

そんな感じですかね。

本日のツッコミ(全2件) [ツッコミを入れる]

_ Saisse [自分で書いていてTeのファクトリがいるかな?と思ってましたが、tpircsさんのはPlayerにファクトリ機能を持た..]

_ tpircs [私のモデルは結城さんの「デザパタ本」の記憶が混じってるので、私の手柄じゃなかったり(汗。いろんなモデルの考え方を見さ..]


2004-04-17

_ 今日は映画の日

とは言え、コナンだが。

_ やっぱMSだな

VB.NETでDataGridをいじっていてはまった。

メモリンク

なんで、FormのKeyPreviewで全部解決させないんだ、ぷんぷん。

_ メモ

Matz on Craftsmanship

このサイトはなんなんだ? むちゃくちゃ濃いのだが。知らぬはおいらばかりなり?


2004-04-18

_ ふーん

ケントンプソンの悪戯なんてのがあったのは知らなかった。

しかし、「オープンソースプロセスのまさにその本質」ということは、この頃からBugTrackとかの賞金稼ぎの戦果報告場とかがあったり、eeeyeのような企業もその頃からあったのかなぁ。勝負の土俵が違う頃の例を持ってこられてもしょうがないような。

Reflections on Trusting Trust――これか。1984年(これを読むと仕込み方の解説であって、実際に仕込んだかどうかはわからないが読み飛ばしてるかも)。

まだ、インターネットワームよりも前だし、誰も気にしてなかったんじゃないか?

それより、Unixにはこういう研究からさらに20年の蓄積もあるということなのではないかなぁ。結論は不可知論みたいに読めるけど。

それに、コンパイラに仕掛けてあるという手法に則して言えば、現在、バイナリーを吐くのってgccとgas(リンカはどうだっけ?)に絞られていて、それこそ1番、監視されてるような(新しいCPU、新しいOSが出るたびにいじくられてるわけだし)。

っていうか、これだけ集積度が上がるとマイクロコードの中にバックドアを仕掛けるという

MS Watch(2002/12/01)の読みもありそうだな。

というか、この論評自体は、MSの共有ソースプログラムに関連したものだったのか。

追記:JVMに埋め込めば、ServletエンジンやJMSとかで好き勝手ができる可能性がある。

追記:っていうか、『Linuxカーネル開発プロセスが破壊工作を阻止』は読んだ記憶があるが(内容は全く覚えてなかったが)、良き警告としてナレッジベースに組み込まれているようだが。しかし、この記事を読むだけでは、Linus達がモラリストだということと、BitKeeperへの侵入を許していないことがすべてのようにも見えるが。あまり役に立たない記事だ。

追記:なんだ、ケントンプソンのオリジナルは自分で探さなくても、セキュリティメモにちゃんとリンクが貼られてるじゃん。


2004-04-19

_ 九つ、けんかは逃げる脚対空飛ぶ轟天号

けんかえれじい [DVD](高橋英樹)

けんかえれじいの主題歌が急に気になって調べたら、世界のけんかえれじいというのが引っ掛かった。

いきなり「その疾きこと風の如く」とか書いてあるんで、笑わせてもらったが、それにしてもわけわからんおもしろさ。

帝国捨てぜりふ研究所。なんか、相当嗜好が被っているようでもあり、微妙なところだがつい読みふける。

しかし、なんだな、これだけ検索に引っ掛かりそうな言葉並べて、かつ日記にあれだけ書くってことは、相当、周囲の人間から孤立してんじゃなかろうかとか大きなお世話だな。

しかしだな、2001年2月5日にああいうことを書くわけだから、どうしたって大きなお世話だろうが、気になるってもんじゃないか、とか。

しかしなんだな、永久封印ってのは何かと思ったら、本当にこいつの「芸」なんだな。ちょっとびっくりした。確かに世の中は広いや。

_ アクション復刊

しかしメニューがマウスの動きを妨げる最低のフラッシュだな。

というのはどうでも良くて、軍鶏が見あたらないのが気になる(っていうか、それ以外は気にならないというか)。


2004-04-20

_ 調べ残したが寝よう

VB.NETで、デリゲート(というよりイベントハンドラの入れ物の)配列をどう記述するか。
Private Event foo() As EventHandlerのような記述をするとエラーになる。って、言うか、VB.NETでジャンプテーブルを作る方法って別にあるのかなぁ。
非スタティックインナークラスが無いからそっち側のジャンプテーブルってのも使えないし。デリゲートがあるから非スタティックインナークラス不要とか言うんだから、どうにかして欲しいところ。
「VB.NET ジャンプテーブル」で検索すると、なぜか自分の書いたGSのやつがトップに出てくるしなぁ。
メソッドの引数にMeを突っ込む形でオブジェクトの配列にするしかないかな、こんなやつ。
Friend Interface FnKeyHandler
    Friend Sub handleEvent(ByVal frm As MyForm)
End Class
 
Private fnCommands() As FnKeyHandler = New FnKeyHandler() {
    New F1Handler(),
    New F2Hanlder(),
    ...
}
 
Private Sub Form_KeyDown(...) Handles MyForm.OnKeyDown
    If KeyData >= Keys.F1 && KeyData <= Keys.F12 Then
        fnCommands(KeyData - Keys.F1).handleEvent(Me) 'Meを指定するのすごくイヤざんす
    End If
End Sub
メソッド内で3行で済むものをわざわざSelect使って24行もだらだら書くのはイヤだし。
#急に思ったが、非スタティックインナークラスでSunが特許を取ってたりして。それで、デリゲートを「発明」したのかな? 実は言語デザインの問題でもオブジェクト指向の問題でもなく単純にそういう問題だったり。

_ 喩えとは何か

結局、何でもそうだと思うが、少し賢い奴は、行き詰まったときは、比較対象を求めて、相対的にものを考えるということをする。まず、それになんか似たものはないかなと考える。その似たもののありようとの比較において、自らの問題対象のありようを考えるのである。

――石童丸史

これは今まで見た喩えとは何かについて書かれたものの中で、もっとも腑に落ちた。

確かに、相対化して分析するためのツールだというのは納得だ。

相対化する能力に乏しいとパターン(むしろアンチパターン)の発見も難しいだろうな。

とは言え、金は価値を作らないかも知れないが、流通量を操作可能だというところが(あ、これも言葉と同じか)ちょっと違和感を持ったところなのだが、寡黙と饒舌の間で操作可能だという面じゃ同じか。

#喩えというのは概念を心象として形成させるための手段だというのが僕の考えなわけだが、それでは心象とはどうやって形成されるのかと言えば、それは身近に引き付けるしかないだろうという考えが根底にある。理屈は後からつけりゃ済むが、納得(AHA)は瞬間的に生まれると思う。

_ iBook update

自分用に欲しい。

こっちもいいな


2004-04-21

_ NET Architect Seminar 2004

出社したら昨日(追記:20日の出来事なのでここでの昨日というのは19日のこと)の夕方に届いていたお誘いメールを発見。席が余ったのかなぁ、とか考えながらも、ありがたくプリントアウトして、午後、ドームホテルへ。

Doom Hotelだとちょっとおどろおどろしいが、そんな気が利いたホテルではなかった。ちなみに、zooはツォーだったりゾオだったりするわけだからDoomでドオムってのもありだろう。

とか、どうでもいいことを考えながら地下へ降りてNさんに挨拶。復調したのなら良いのだが。今日は午前と午後があってとか言うので、まさか重複コードをリファクタリングしたりはしてないですよね? と訊くと、そりゃないだろうとか。

司会のマイクを取ろうして、演壇はあっちと教えられると、照れてるんだかなんだか、妙な足取りで右へ進む。ああいう時には、さりげなくムーンウォークとかすると良いだろう。(追記:以降、ほとんど同時通訳を利用。通訳が追いついていない部分では英語のほうも参照しているが相当怪しい)

で、いきなり「午後の部では」とか言い出すので、このオッサンちゃんとわかってるのかいな? と思ったが、そつなく始まる。2時間(3時間かな?)分のパワポだが90分だから途中を素っ飛ばすと言明。多分、MSとしては、ページコントローラを素っ飛ばされるのは嬉しくないんじゃないかな。それはそれとして、あまりにそつが無いので退屈する。PoEAAのプロモーションに来たのかなぁ。途中、うまく通訳で伝わるかなとか言いながらギャグを飛ばしたようだが印象には残っていない。そこで「やっぱり通訳付きじゃ通じないか」とかブツブツ言ったのには受けたが。

ロウデータゲイトウェイのところで、スタティックメソッドによるファインダメソッドが必要となり、それによって、モック(ファウラーの用語ではスタブ)の使用ができなくなるから、ファクトリを別途使用することを提案(なのかな)。っていうか、そのまんまCMPエンティティビーンとホームインターフェイスですがな。

データマッパーは実装がすごく大変だから、おれたちソートワークスみたいに優れたデータマッパーの実装を持ってなければやめときな、というようなことを言い出す。リレーションがあると確かに単純には実装できそうにもないかな、とちょっと実装戦略を考えているうちに分散パターンへ突入。

コモンシナリオを見せる。これはカスです、と言明。いくらアメリカ人でも、顧客にはそうは言えないけどねと注。全く正しい。

コーバーピープルって何かと思ったが、CORBAピープルのことか。痛い目にあったのかなぁ。そりゃ合うだろう。分散オブジェクトっておもしろいんだけど、インプロセスとは違うからな。

透過、透過って、おまいら速度を意識したことは無いんでつか、と怒ってみせる。まったく正しい。しかし速度よりも、障害だよ、真の問題は。(と、速度をクリアしていたもので実践投入――DCOMだけど――したことのある僕は呟くのであった)

リモートファサード。粗粒度インターフェイスの利用。だからDTO。

でも、インプロセスなら、こんなもんいらんもんね。

そうかな? それこそ透過APIで済むのではないか?

アドレスデータをレコードセットと考える。これはDTOだ。ただし、コントローラ(アドレスファサード)のインナークラスとして(コントローラへのバックポインタを持つと)考える。

DTOではあるが、insertのようなメソッドについては、内部でコントローラへthis(これはDTOだ)をデリゲートすることで済ませることが可能だ。

ロウデータゲイトウェイには、ファインダクラスを設けることにするのがベストプラクティスなのだから、それをファサードとして利用可能では無いか、と考える。

で、質疑応答。

ドメインモデルのインスタンス生成コスト問題。そんなものよりDBを気にしろ。うーん、そうなのか? そうなのかも。というか、その通りなのだが、まあ、考えどころではある。

現実問題としては、正しい。無意味な文字列生成のように短期間に爆発的に生成されるわけではないので(特に更新処理)ほとんどのインスタンスはトランザクション境界と同程度の寿命を持つ。レコードをグルグル読みまくるようなものにドメインモデルを利用してはいけないというのは当然で、ファストレーンがそのためにあるわけだし。

SOA。なんか、最初の解釈ってのは、箱モノが外部にサービス提供するのは良いアイディアだと言い出す。それはOfficeアプリケーションが外部にサービスを提供するのは良いアイディアだのOLE1、2、フィニッシュみたいだ。同じことだが、サービスの粒度が異なるってことかいな。

非同期重要。正しい。

でも、Webサービスは重たいから、エンドとエンドを自分で決定できるのなら、(ミドルウェア)ネイティブなプロトコル、つまりリモーティングやRMIを使え、そのほうが効率的だ。と言い出す。

それは違う。速度はドメインでのDB処理の見直しによって考えるべきだ(と早速、流用)。やはりプロトコルがどこまで透明かが重要となる(インターフェイス透過のことでは無い)。リモーティングやRMIを利用するのであれば、独自にUDP上にアプリケーションプロトコルを作成すべきだ。と僕は考えるが、まあ、いいか。一般論としては間違いではないし、障害の発生頻度は環境にも依存するからだ。それでも、僕は(ほとんどの局面で)HTTPを使うけどね。

追記:WRさんのレポートを読んでいて思い出したが、XML Webサービスを使ったらXMLシリアライゼーションにバカな時間を食ったと言っていたのを思い出した。そりゃそうだ。まだ、XMLシリアライゼーションはH/Wに追いついていない分野だと考えたほうが良い。バイナリシリアライゼーションのPOST(るいもさんの案)か、SAX(または独自シリアライザー/デシリアライザー)とXSLT(言語としてのXSLではなく、独自に要素のマッピングをする変形ツール)を利用(まあ、ソートワークスのデータマッパじゃないが僕はインフラがあるし)しなければならないのはHTTPを利用する上での現時点での良識(オブジェクトがでかい場合については。少なければSOAPで十分)。

テスティングフレームワークについて。UIドライバって作るの大変だよね、とか。まったくだ。そこでプレゼンテーションレイヤはとにかく薄く作ってテスティングフレームワークが適用可能なドメインとは分離すべきだ、と最初の3層の話につなげたのかな、ちょっと記憶が曖昧。

あと、IoCの質問とか。角谷さんの翻訳について触れる。.NETでも役に立つんじゃない、と軽く流す。

もし役に立つなら、次期VS.NETじゃなくて(.NET Frameworkだろうな)に組み込まれるだろうし、そうじゃなければしょぼしょぼだろう。役に立つかどうかは.NET開発者にどれだけTDDが受け入れられるかどうかだな。

案)

System.Testingネームスペース

TestCaseクラス

System.Containerネームスペース

MicroContainerクラス(ナノピコよりでかいところがMSだ)

というわけで、なかなかおもしろかった。

で、終了後神保町へ行って、書泉グランデ。あ、洋書が無くなっている。で帰る。

追記:僕の考えと、ファウラーが喋ったことの分離度を低く抑えて書いている(俗流意識の流れってやつでね)ので、dotNETArchitectSemi2004と照合したほうが良い。

追記:なんか、結構違うな。UIドライバと両エンドを自分で管理可能な場合。前者はこっちの記憶が曖昧だからあっちが正しいかも。後者はこっちが正しいと思うが確証はない。

追記:DBのモック(スタブ)が重要なのは、テストの速度。例)実際にDBと接続するユニットテストは40分(かな?)、モックを使うのは数10秒。ソートワークスでの話。時間については誇張があるような気もするが、正しい。

_ XML Webサービス問題点(追加)

さっそくWRさんのコメントを参照してリンクをたどる。わ、大容量文書だ。それで「きちんと読んでません」になるんですね。僕もきちんとはまだ読んでません(へたすると読まないかも)(追記:これは読む価値があるから、やはりちゃんと読む)。

2種類のシナリオがあって、

1.インターネットシナリオ(みんなが望むXML Webサービス(B2Bとか))

2.イントラネットシナリオ

1.の場合は、スキーマによる検証が必須となると思います。そのためには、ネームスペースなどフルオプションで付ける必要があるでしょう。が、2.の場合は検証済み(受け入れテストをしてるはずです)システム間の通信となるため、厳密な検証は不要です(バグは別。でもバグはXMLを使うかどうかとは関係ない)。

検証をしなくても良いとなれば、デシリアライゼーションは相当、速度が向上します。また、現在、イントラネットの通信は(除く障害)速度についてはH/W進化の恩恵を非常に受けている分野です。一昨年の100Kバイトデータは、今年の1Mバイトデータ並かそれより大きい(可能性がある)。

とか、書き始めたが、ちょっと割り込みが入ったので多分、ここまで。

本日のツッコミ(全5件) [ツッコミを入れる]

Before...

_ WR [補足させてください。枯れた技術、ツール類云々はASN.1にかかります。]

_  [ああ、なにかヒトコトいいたいかもかも。]

_ arton [お願い、言って。]


2004-04-22

_ VB.NET

interfaceのメソッドの記述はどうにかならないもんかな。あまりに見苦しいのだが。
不満点:
C#と違って、ソースにデフォルトのNamespaceが付かない。後から入れるので面倒。
start:
クラスFoo1.classをプロジェクトに追加。
1:ソースが開く
Public Class Foo1
 
End Class
2:Namespaceを入れる
Namespace Bar
Public Class Foo1
 
End Class
3:Enterキーを打つ
Namespace Bar
 
End Namespace
Public Class Foo1
 
End Class
4:不快になりながら(インテリセンスだかスマートインデントだかなんだから、文脈読んでソースの最後にEnd Namespace入れろよな、ってことだ)、End Namespaceをカット&ペースト
Namespace Bar
 
Public Class Foo1
 
    End Class
 
End Namespace
5:なぜ、End Classが移動するんだ? と不思議に思いながらバックスペース攻撃(Delete攻撃でも可)――ネームスペースでインデントされるのは嫌いなのだ。
Namespace Bar
 
Public Class Foo1
 
End Class
 
End Namespace
6:カーソルを移動
Namespace Bar
 
Public Class Foo1
 
    End Class
 
End Namespace
7:Wordですか?
で、しばらく5と6をイテレーションし、うんざりして他のことをするためにコードビューを切り替えたりしてから、戻って見ると
Namespace Bar
 
    Public Class Foo1
 
    End Class
 
End Namespace
いつの間にかインデントが揃っている。.NET時代を迎えても、人を不快にさせるVBマジックは健在なり。

2004-04-23

_ 開心果仁

殻が閉じきっているやつがいるが、浅蜊じゃないんだから食えるだろうといろいろトライしてもどうにもならない。爪を剥がすってのは拷問のはずだから、すさまじく痛いに間違いない。だから、あまり素手でムキになるのは下策というものだ。

そこで上策を考えてみれば、専用の器具の利用となるが、あいにくそんなものは無い。そこで中策を取る事にして引き出しからラジオペンチを取り出した。

手加減しながら挟む。スルッと飛び出す。というようなのを繰り返すこと数度、ついに短気を起こして短期決戦を挑む。つまり挟んだ瞬間に握り締めた。

その途端、イヤな感触とバキッという音がして、粉末があたりに飛び散った。ラジオペンチの溝には詰まって取れないわ、椅子の布の隙間に挟まって取れないわ、床は殻の破片が散乱しているし、どうやらとんでもないことをしてしまったようだ。

それでも半分ひしゃげた中身を発見し、食べてみる。

眠狂四郎殺法帖 [DVD](市川雷蔵)

こんなもののために……

( 狂四郎、崖の上に独り立ち、まじまじと手の中の碧玉の仏像――バルバランを見る。)

――眠狂四郎殺法帖

彼はゆっくりとした足どりで岸壁に近づくと、大きなモーションでバルバランを海中に投げ捨てた……ずいぶん遠くに飛んでいった……波の間にポチャンと陽気な音を立てて消えてしまった……

――アンダンの騒乱

ボリス・ヴィアン全集〈1〉アンダンの騒乱(ボリス・ヴィアン)

語録

_ なんか、みんな同じところにいるな

仕様書で喧喧諤諤

こういう場にしゃしゃり出てくる組み込み野郎は、どうして自分の狭い了見で物事を語るんだろう?

組み込みは、対機械のプログラムだから、仕様は確定可能。エンタープライズアプリケーションは対人間のプログラムだから、仕様は流動的。対機械でシグナルがハイと言ったらそれはハイ。2.5msec以内にACKを返すといったら2.5msec以内にACKを返す。しかし対人間で、OKを選択と言ったら、一体どれだけの可能性があることか。

あと、最初の部分を見ると、機能仕様と実装仕様/外部仕様と内部仕様で議論が噛みあっていないように読めるのだが。で、それを指摘する人間もいるのだが、どうもそういうまっとうな声は小さいようだ。

こういう、人の話も読めない連中が、仕様のような高度に抽象的なものについて語るっていうのは端から見ても滑稽だな。で、人の話も読めないのに、仕様書を読めるってんだから不思議なものだ。(追記:わかった。組み込みと同じことだ。人間じゃなくて機械なんだ)

_ 今日のお言葉

他人が作ったコードは、コメントを頼りに読むしかありません。
なるほど、勉強になりました。
注釈:他人を信用するなという意味に取れば正しい。
 int comp = (int)(Math.random() * 2 + 1);
と書くのではなく、
 // コンピュータの手(グー(0)、チョキ(1)、パー(2))を求める
 // Math.random()はー0.5以上から1.0未満の間のdoubleの乱数を返すメソッド
 int comp = (int)(Math.random() * 2 + 1);
と書きなさいということだ。
こう書けば(何しろコメントを頼りに読むのだから)、るいもさんに笑われることもなかろう。
というか、どうしてこういう事をいえるんだ?
drawメソッドのコメントが「// メソッドの定義」というようにJava言語の構文の説明になっています。 このままでも学習段階では構いませんが、 実用的なプログラムでは「// 描画を行う」のように、メソッドの機能をコメントするようにしてください。
2つのことを言っている。最初のは良い。構文の説明はやめようね、と教えているのは実に正しい。
次のだよ。なんの意味だ? ルビをふれという意味なのか? 対訳をつけろということなのか?
これならまだ理解できる。
// 描画を行う
public void X0E_EYY_00100() {
 ....
}
頼むからコメントを付けてくれ。
こういうのも良いかも。
// 描画を行う
public void a() {
 ...
}
こりゃ楽だね。でもコメント書くのが手間だな? いや、さっさとJavadocの記述方法を教えるべきだろう。
/**
 * 描画を行う
 */
public void a() {
 ...
}
違うな。
/**
 * {@link #x}を幅、{@link #y}を高さに持つ四角を書く。この時、
 * 左上の角は左から{@link #radius}(なぜradiusなのかは謎)、上から10とする。
 */
public void draw() {
 ...
}
とかかな。
考えてみれば、紙上なんで「描画する」としているが、このあたりは現実にはちゃんと説明している可能性はあるな。
具体的な汎化例については出ていないからわからないが、このプログラムのままなら、汎化はインターフェイスによるべきだろう(drawと面積計算しか共通項目が無い)。しかし、描画の開始位置として座標を与えるのであれば、実装継承のほうが良さそうだ(共通の属性として位置が出てくる)。
追記:だからそうじゃないのよ。 という言及しているページを発見。
確かに、最初の部分が無茶苦茶だ。っていうか、コンストラクタも無意味過ぎ(明示的な0初期化は無意味だと思うし)。最低でもコンストラクタに移動すべきだろう(仮に現在の人間が座標を決める方法だとしても)。っていうか、長さ情報がpublicな時点でだめぽだろうな。というよりも、xとかyって なんなんだ? Sankaku s;よりもint xじゃなくてint base、int yじゃなくてint altitudeを指摘して欲しいところ。あと、四角のradius。

_ 層分けの間違い

WRさんのところに書いたコメントは異なる層(分析と実装)をごっちゃにしてるから、だめだめですね。

_ ゲルマン

ア*・ゲルマンという名前を見て、思わず、そこにあったAmazonへのリンクをクリックして、そして少し悲しくなる。

今、わたしが映画をつくることもほとんど不可能に近い。以前は映画をダメにするのはイデオロギーだったが、今では経済状況が映画をダメにしている。

寡作の人に佳作は多いが家作ができた試しがない(なんだっけな?)。

ゲルマンやカネフスキーはどうなったんだろう? 来るのはボドロフばかりなり(嫌いじゃないが)。

本日のツッコミ(全2件) [ツッコミを入れる]

_ xyz [コメントより、正しい変数名!]

_ arton [確かに、それが1番の問題だと思います。xとyだったら描画の開始位置を示すとかだったらまだわかるんだけど。あと、フィー..]


2004-04-24

_ VB.NET(Windows Form)必勝パターン

1.データセットの追加を選び、スキーマを定義。

2.DataSetコンポーネントをドロップ。1.を型指定されたデータセットとして組み込む。

3.フォーム上のコントロールを2.のDataSetを経由して1.のスキーマ上の要素とバインド

4.フォームのロード時に、dataSet.ReadXmlで初期値を読むかさもなければ、dataSet.Table(0).Rows.Add(new xxxDataRow())で、初期化する。

5.各コントロールのValidatingに対応するイベントハンドラで検証コードを記述する。

6.入力の最終時点でDataSetのTables(0).Rows(0)を利用する。

_ ASRを自前コンパイル

雪見酒さんの日記4/24

はなからタコツボGPL(GPLがタコツボなんじゃなくて、ソースがタコツボに落ち込んでいるため自由であっても特定環境でしかビルドできない――したがって厳密にはGPL違反ではないか)だということはわかっていることなので、今更書くのもなんですが、ATLが存在しない限りビルドできません。

ATLも例のToolkitやSDKに付属しているのであれば(ATL1.0は別配布だったし、WTLもPSDK付属だったのであり得ないわけでは無いのかな?)、Makefileを外出しする(IDEのExportが利用できる)のは良いのですが、VCのプロジェクトにINCLUDEやLIBが絶対パスで書かれてしまっているため、手作業は必要となります。具体的には"d:\ruby\.."というパスが散りばめられているので、それを変更してください。

ASR(ruby1.8版)のnmake用Makefile

_ ロボット

Everybody wants to be a robot

etoさんのとこから。バグルズじゃんというような気もしないでもないが、好きだわ、これ。もう100回以上聞いているぜ。

しかし、I want to be a machineとはエライ違いだ。

ウルトラヴォックス!(ウルトラボックス)


2004-04-25

_ 妙な言葉は納得は早くても忘却も早い。

WRさんのとこにごにょごにょ書いている最中に、ある言葉がそれを意味していると気付いたのだが、その「ある言葉」を思い出せない。

あそこで、僕がイメージしている疎結合システムを意味する用語ってなんだっけなぁ?(誰もお前のイメージなんかわかるかってというツッコミは置いておいて)。

エコシステムか、サプライチェーンだと思うんだが、サプライチェーンだと対象領域が限定された使用例しか思いつかないし、エコシステムというと余りに怪しげだし、何か用語があったはずなんだが…(検索中)…やっぱりエコシステムかなぁ。

……どうもそうらしい。それにしてもこんな使用例もあるが、やはり怪しい言葉だな。

_ VB.NET必勝パターン(続)―IoCコンテナは.NETでも有効か?

有効。理由は以下のとおり。

VB.NET必勝パターンを誰でも知ってるStrutsに対応させると、ここでのDataSetはActionFormに相当する。IDEのプロパティエディタで設定できるという意味ではDynaActionForm以上の利便性を持つ。かつ、スキーマ定義はドラッグアンドドロップ可能なビジュアルエディターで編集できるから楽チン至極。

Validationイベントハンドラは自分で記述しなければならないとは言え、VB.NETのインテリセンス付き構文エディタ(であってるか? プリティプリントするだけでも構文エディタと呼ぶような記憶があるからその意味じゃあってるはずだし、コンパイルエラーも記述時点で判明するから―すげぇな良く考えてみると―あってるだろう)でちゃかちゃか記述できるのだからこれも良い。

と考えてみると、VB.NETのWindows Formアプリケーションは、Enterキーによる「実行」処理のイベントハンドラの記述をActionと見立てて、MVCのCとVの混在だということがわかる。ただしVのうちTextBoxだのCheckBoxだのは、自動的に処理がされるわけだし、DataSetと束縛させておけばLabelなどへの自動表示もサポートされているわけだから、非常に手数は少なくて済む。

ここで、DataSetをそのままデータベースとのインターフェイスデータとして利用すれば、それはテーブルモジュールパターンとなり、DataSetはそのままモデルとなる。

しかし、DataSetをユーザー入力の単なる入れ物(まさにActionForm)として扱う場合には、Actionに相当する実行ボタンハンドラから、モデルへの委譲を記述することになる。この場合、モデルは普通にクラスを作成していくのでも良い(ドメインモデルパターン)。ドメインモデルの呼び出しがWebサービスの呼び出しとなるのであれば、その場合、Windows Formはプレゼンテーション層に相当するのだが、Webサービスから見れば、入力のバリデーションは完了しているため、イントラネットシナリオに限定すればドメイン層のうち、ユーザーファサード(という呼び方があるかは知らないが、意味的にはユーザーインプットに対するファイアウォールということになる)までを担当していることになる。Webサービスではなく、Remotingを利用するのであれば、ドメイン層のうちファサードまでを担当していると見なすことも可能。(インターネットシナリオでのRemotingはあり得ず、Webサービスであれば入力の検証は必須――XSS脆弱性はともかくとして)。

ここで重要なのは、ティアの分割が2層のクライアント―サーバであっても――これは、DataSetを直接テーブルモジュールとして操作する場合、およびモデルに相当するクラスから直接DataAdapterなどを利用する場合のいずれであっても、モデルは、Windows Formとは分離したクラスとして実現できることである。

このように構成されたアプリケーションは16ビットWindows時代のベタなクライアント―サーバとは同一視できない。たまたま、物理的な配置が2層になっているというだけで、論理的にもオブジェクトモデルにおいても、3層以上の構成となっているからだ。

なぜならば、ローカルに配備されたモデル相当のクラスは、実際にはリモートに配備することも可能だからだ。

さて、ここで1998年に戻ってみる。Windows DNAだ。同じ構成は実際にはVB6でも可能であった。モデルをCOMのコンポーネントとしてアプリケーションからは分離可能であったからだ。ここで、COMのコンポーネントをリモートのMTS内に配備すれば、同様の多層構造となる。

ここでの問題は、やはり、DCOMの信頼性に尽きる。初期設定であり、かつ変更が不可能なPING(6分だったっけな?)も当然、問題だ。DCOMに比較すれば、OLEDB(またはODBC)のほうが遥かに安定した通信を提供する。したがって、現実的なアプリケーションは仮にCOMのコンポーネントとしてモデルを実装してもクライアント上に配備することになる。この結果だけを考えれば、あえてCOMのコンポーネントとするよりも直接アプリケーション上にデータベースへのアクセスコードを記述する2層クライアント―サーバシステムとしてしまうというのも現実的な解だ。

ただし、VB6の時代では、COMのコンポーネントが重量コンポーネントだったという事実を割引く必要がある。レジストリへの登録が必要であり、OLE2のようなDLLを必要とするからだ(1度ロードした後はvtblバインディングが行われるため実行上のペナルティは型システムの制限以外は無い)。

.NETにおいては、すべてが.NET Framework内での実行となるため、COMのコンポーネントのように重量が……というような考慮は基本的には不要である。(追記:もちろんRemotingの信頼性はDCOMの実績を加味すべきだし、Webサービスが重量級なのは事実。したがって物理配置は2層が望ましいと判断したーしなくても良い―と仮定した上で、)したがって、論理構造(およびオブジェクトモデル)としては、多層で実装したとしても実行上のペナルティは課せられない。である以上、仮に物理配置においては2層クライアント―サーバであっても多層構造によって実装すべきであることは自明である。

シナリオ:

・社内のPCからのアクセス(モデルはPCへ配備し、データベースへはPCからアクセス)

・出先のノートパソコンからのアクセス(モデルはWebサービスとしてWebサーバへ配備し、データベースへはWebサーバからアクセス)

の両者に同一Windows Formアプリケーションが利用できるということは、それだけで十分なメリットである。もし、1アプリケーション内にデータベースアクセスを記述してしまえば、後者のケースには対応できない。

また、このシナリオを有効にするには、モデルに対するビジネスデリゲートが必須となるのも当然である。

ここで、ビジネスデリゲートの実態は、サービスロケータ+ファサードだという点を考えてみるとIoCコンテナの有効性がわかる。サービスロケータが有効なシナリオではIoCコンテナもまた有効だからだ。

したがって、IoCコンテナの出番は、第1にはWindows Formアプリケーションのためということになる。


2004-04-26

_ 買った読んだ

ピグマリオン岡田史子作品集(岡田 史子)

うが、episode3ってのは無いのか? これでおしまい?

だとすれば、単に60年代終焉から70年代初頭に作品としての記録を残した新宿フーテン族のイカレタ女の子のヘンなマンガってだけのことになってしまうんですが、そういう意図なのか?

というか、その時期(セデスをのんでラリラリ――インタビューには出てくるが)さえも収録されてないのだが。

とすれば、まるで扱いはランボーだ。

こういうのは、典型がある。

ベルリオーズを考えてみれば、幻想交響曲はいつでも入手可能だが、トロイとかロメオとジュリエットなんてのはいつでも手に入れられるわけではない(今は違うかも)。

マーラーだって、ついこないだ(バーンスタインの全集まで。全然こないだじゃないな)までは、巨人と復活以外は無かった(に等しい。そりゃ、9番だけはバルビローリとベルリン、ヴァルターとウィーンがあるから他はいらないとは言え。追記:大地の唄もヴァルターとウィーンの凄惨なのがあった。考えてみれば戦前にヴァルターとウィーンは9番と大地の唄をちゃんと記録したのだ。なんて恵まれた作家なんだろう)。

プッチーニの西部の女やジャンニスキッキが聞きたいと思えども、あるのはボエムとトスカだけなり、とか。トスカは中期と言っても良いかも。だめか。

ベートーヴェンだって29-30-31こそ全てだろうと思ったって、しょせん月光と熱情、悲愴にくらべりゃ無いに等しい。

ブルックナーと言えばヴァグナーとロマンティシュ。でも8番は? 9番だって。(追記:今はマーラーと同じく完全に人気モノみたいなんで不自由は無さそうだな)

スクリアビンは3番と遠い星への飛行。黒ミサ、白ミサは?

リストといえば超絶技巧とハンガリアン前置曲。だが僕は、凶星やヌアジュグリや葬送のゴンドラが好きなのだ。

そんなのばかりじゃないか。

映画だってそうだ。

ラングと言えばジャガーの眼だろう(違うかも。ベンガルの虎かも。忘れちゃった。インドの冒険のやつ)? せめて暗黒街の弾痕。でも、Mやメトロポリスの監督らしい。

トリュフォーと言えば大人はわかってくれない。おい、大人のトリュフォーをわかってやれって。日曜日は待ち遠しいぞ。

ロッセリーニと言えばドイツ零年。でも、インドのドキュメンタリー(嘘つけ)のおもしろっぷりだってとても映画なんですが。

ブニュエルと言えば昇天峠だろ(運転手さん、そのバスに僕も乗っけてくれないか)、いやグランカジノか。でも歴史はアンダルシアの犬と呼ぶ。

エイゼンシュテインだってメキシコじゃないか。でも歴史はポチョムキンと言う。

黒澤といえば7人の侍で、どですかでんとはこれいかに、とか。

ピストルオペラ [DVD](江角マキコ)

鈴木清順は殺しの烙印とけんかえれじいで、カポネ大いに泣くはどうですかとか。あ、今、Amazonで見たが本当に無いや。カポネ大いに泣くは、すげぇ映画なんだがなぁ。あれだけ長くて、あれだけ大げさなくせに、シカゴは千葉だし、どうすりゃあれだけ薄っぺらで風が吹かなくても倒れてしまうような、まさに映画そのもののような映画が見られるんだろうか、っていうような映画の中の映画なのに。とすればピストルオペラ、今のうちに買っておくしか……ぐは、在庫切れだ。

みんな中期以降が本当にダメダメなのか? そんなこたない。

(あ、ゲイリーニューマンか)

100年後を想像してみる。

ボウイと言えばジギーだけが残って、どんなにリアリティとかが聞きたくなってもそりゃ無理でしょうとか、ルーリードと言えばベルリンだけが残って、どんなにサリーキャントダンスが聞きたいといってもそりゃ無理でしょうとか、既にストーンズと言えば、ジャンピンジャックフラッシュで、ミスユー以降があるんですか? とか、ストラングラーズはノーモアヒーローズで、ラフォリはどこですか? とか。ブルーハーツはリンダリンダとトレイントレイン(共通点があるなあるな)。でもおいらが好きなのはヒマラヤのミサイルや桜のトンネルだ。

ま、そういうのが時代の寵児ってやつの宿命なのかも。だとしたらもって瞑すべし。

_ ムーンフリート

別枠で記憶の確認。

音楽は亡命ハンガリアン。この曲から、Amiga用のシンバッドはインスパイアされたのではないかと勝手に想像している。

孤児が故郷へ戻る。怪しげな悪党ジェレミーフォックス。旧家の娘。排他的な村人。お金が好きな総督。

父親探し。

ジプシーの娘。

フォックスとの冒険。

フォックスは傷つき、独り、ドーバー海峡をフランスへ小船で乗り出す。

良くわからんが、1番好きな映画はムーンフリートなのかも知れない。

本日のツッコミ(全1件) [ツッコミを入れる]

_ るいも [ベートーベン、32はダメですか? 30、31で、あぁ、もう頭の中は神様でいっぱいなのですね、と思ったら、32の一楽章..]


2004-04-27

_ 無茶苦茶でした

だから、数字は……というか、確認せずに書くのはだめですね。

ここで想定していたのは、ポリーニのやつだから、

"ベートーヴェン : ピアノ・ソナタ第30番,第31番,第32番"(ポリーニ(マウリチオ))

30,31,32でした。

でも、僕が本当に好きなのは、軽やかに轟く1楽章、どっかへ逝ってしまうかのように始まり、どんどんスウィングしながら、やっぱり昇天する2楽章、ポゴレリチの ベートーベン:ピアノ・ソナタ第32番ハ短調(ポゴレリチ(イーボ))です。何がそんなに有頂天。

ほーら、全部、在庫切れだ。

スイング・タイム(有頂天時代) [DVD](フレッド・アステア)

で思い出したのが、有頂天かつスウィングの、アステア。

でこの中で引用として出てくるボージャングルが実際にエデュケイテッドな足を見せようとするのがストーミィウェザー。そこで暴れまわるのがキャブキャロウェイ。で、グラモフォンのジャケットの黄色い帯へと連環する。

#ストーミィウェザーまでは黒人が主役というのはできなかったそうだ。

#すると、ボージャングルを見たければどうすれば良いのか?

#で、アステアが替わりに靴墨塗ることになるのかなぁ、とか映画からアメリカが見えたり。

_ 111

そうか。111の1が妙に印象的なのだが、脳内で作品番号の1ではなくソナタの1と入れ替えしまったから、最後が31で-2までを含めるから31,30,29と考えてしまったらしい。

_ 21

実は聞いたことは無いかも知れません。なんかでアナリーゼを読んだ覚えがあるだけです。今度、見てみます。

_ ボソッ

すごく固いし、安全策を取ってるし、しかも長いし。デンパでつか、とか言われそうな気がするし。

なんか火中の栗のような。

でも、目立たないかも知れないからいいや。でもそれじゃ良くないんだけど。

追記:やっぱ、長いと言われてるし……

_ ITPro

TDDをウォーターフォールにインジェクションしようという提案

続き

どうも、あそこは足元をすくわれないようにという意識が先立つので、もって回った言い回しが多くなってますね。かくして読みにくくなり、気軽に攻撃してもらえなくなるという罠(それはそれで攻撃されるのにも興味あるし)。

しかし、例の仕様書論議を見ていると、外部と内部(機能と実装)という分割はそんなに一般的じゃないのかなぁ、という疑念も。だとすれば、まず、そこからやらなきゃだめでしょう。

_ シベリウス

交響曲といえば2番しかないのですか? というのも忘れちゃいけない。そして豊かなピアノ小曲群も。

本日のツッコミ(全8件) [ツッコミを入れる]

Before...

_ arton [しかしピアノになるとこ、やっぱり、バグルズだよなぁ。そしてボボボーといってダダダダと入るとこ。だけどパチモンって感じ..]

_ るいも [そうですね。ポリーニとかアシュケナージは安心して聴けるというのはあります。グールドの32買ってみます。]

_ arton [しかし聴けば聴くほどアレンジはバグルズ。パチモンかどうかは関係なく、メロディーと歌詞が良いのだ。というわけでやはりJ..]


2004-04-28

_ 契約によるプログラミング

コンポーネント間の結合は契約が守られていることを前提とする。そのため、外部入力を扱うコンポーネントに関してはファイアウォールが必要になる。すべてのコンポーネントがファイアウォールを持たなければならないとしたら、その状態が既に不正。あんまりうまい要約じゃないな。

というようなことをakonさんという方が思い出させてくれたのだが、それについて言及されているのを発見してなんか妙な感じ。

UMLを使い始めた頃に購入したUML表記法ガイド(版が違うのかAmazonには見当たらない)の著者の方だったのか。

_ !似てる

通りかかったd(タイポしてた、ごめんなさい)taediumさんの日記から。

分析・設計工程ではOOより在来手法に軍配

ふーむ、何だか似ているな。

3人のアミーゴって、何か勘違いしているだろうという突っ込みは別として、そんなに悪くはない。用語が異なるだけでストラテジパターンのことを言っているわけだし、実際にトップレベルではそのように作ることになるだろう。後は、ここからどういう実装が出てくるかだな。

機能に落ち着くのも妥当だろう(*)。属人性に対する指摘に対してここまできれいに開き直っているのは初めて見たが、この考えは好きだ。

で、最初のところから巨大クラスなのかと思うと、言語を問わず小さく分割すれば楽勝ということで、機能分割していく。それを「機能」と言わずに「責務」と呼べば、それはそれで正しい設計の出来上がりではある。

ただ、なんか本質的にオブジェクトという言葉の意味するものが違う感じがする。なんか妙に粗くて、それはオブジェクトじゃないだろう、という印象を受ける。多分、抽象化されていないからだな。具象クラスが5個くらいという感じだ。また、インスタンスが見えない点が違和感の正体かな。そういう意味では途中で設計が終了してしまっているようだ。

(*)機能はfunctionだが、procedureと対になるfunction(関数)とごっちゃにしているのかなと感じるものを時々見る。

追記:なんでこっちに書かずにコメントのほうに長々と書くのかな。

これは僕の経験値なので、もっと異なるうまいものがあるかも知れないけど、OLTPを前提とすると(この前提が共通点)、1トランザクション境界で「何をやるか」は在来分析だろうが、プロセス分析だろうが、DOAだろうが、同じ結論になるはず。ならなければ、そのトランザクション(ACID特性を満たす)はトランザクションでは無い。データの持ち方から変えてしまう場合は別だけど。後はどの方法が1番要求を吸い上げて正確に定義できるか、の問題だと思う。で、あの文書は在来手法でも平気ですよ、と言っているわけでそれは正しいのではないか、と思う。

そこから先の実装設計が、あちらはトップダウン、こちらはOOだから異なってくるのは当然だけど、そこに至るまでの上流工程については手法が流用できるという点に関しては同意できるというのが大きいかな。

もっとも図6をクラスダイアグラムとして渡されたら怒るとは思うけど、以前COBOLプログラマにJavaを覚えさせるにはどうすれば良いかを考えた時に、クラス=機能の固まりとして、ストラテジで組ませるのが1番良さそうだと思ったのと大体同じような結論になっていたので、それもそんなもんだろうと納得してしまったし。

OOで実装設計ができる人は後編を読んでも、そういうアプローチもあるんですなぁという感想の他に得るものは無いでしょう。

さらに追記:うむ、見てもしょうが無いところは読み飛ばしていたようだ。前編の大半はクソ(=妙な誤解を刷り込む)ですな。むしろ、後編のほうが良いのか。後編は具体性が出てくるからヘンなところに落ち込んでいないからだろう。たとえば、アプリケーション層を1つの巨大なトランザクションスクリプトとして記述すれば、この著者の考えとフィットするだろうし。

ただ、実装が全然わかっていないってのは間違いない。平気でOOでのメッセージパッシングと実装レベルでのメソッド呼び出しを混同しているような記述もあるし。その一方で画面については何か勘違いしている(ASP.NETのサーバーコントロールをイメージしているのだと思う)が、Taglib作ったりすれば実際にはこの人の言っていることもあながち的外れではないかも。

_ 属人性ってのはやっぱり妙だよね。

さて上の従来技法でGOの人は、OOAから見れば属人性があるかも知れないが、それの何が悪い。属人性大いに結構、まさにデザイナー冥利に尽きると放言している。

うにゃ?

DOAの人は、OOAの人を属人性があるからだめだめですなぁ、と書いているのだが……

だからといってDOA>>>>>OOA>>>>>従来=属人性 なんていう矢印が書けるわけはないだろう。というか上に書いたように、(あくまでもOLTPに限定すれば)最終的なトランザクション境界に属人性もへったくれもあるわけがない。あったら、トランザクションじゃないんだから。アトミシティが分析手法に依存して変化するわけないじゃないか。で、今、問題にされているのは業務システムへの適用であり、そこにトランザクション抜きで何か言ってもしょうがなかろう……かなぁ? 実装寄りの見方過ぎるかも。そのキライはあるだろうな。しかし、そりゃしょうがないな。実装寄りで見ることが持ち味なんだから。別の見方は別の人が提供すれば良い。

#Transaction Oriented Approach = TOAというのを思いついた。

というわけで、そんなもん気にしてもしょうがなかろう。という意味では、開き直っている従来技法の勝ちでは無いかと思った次第。

_ F

……なるほど、そういう手もありましたね。

本日のツッコミ(全2件) [ツッコミを入れる]

_ taedium [はじめまして。おおむね好意的な意見なのですね。artonさんのような方から見たら結構突っ込みどころ満載なのかなぁと思..]

_ arton [うーん、あの文書はネガティブな方向から突っ込んでも余り得るものが無さそうなんですよね。とりあえず後編の図6は間違って..]


2004-04-29

_ tDiary風のWiki

Hikiかなぁ。

テーマは共通で使えるはずだし(使ってるし)、プラグインも共通に使えるようです。

でもWikiじゃないと書いてあるし……

Amazonプラグインも使えるのか……知らなかった。

_ 本当の生産性

論点をずらして個人の功績ということで日頃の感謝を。

おっしゃるとおり、たださん(追記:とtDiaryプロジェクト参加者の方々)と近藤さんのインターネット上での功績はただごとじゃないと思います。明らかに僕は恩恵を受けてると思う。感謝してます。

大げさに言えば、パピルスが起源かも知れない紙というメディアがあったとして、それを巻物と言う形で見せた人や(これは竹簡起源かも知れないかな)、書物として折り曲げて背中を糊付けすることを考えた人、に近いのかなと想像します。紙を発明した人(達?)やグーテンベルグも偉大かも知れませんが、それだけではだめで、こうすればこの技術をもっと使いやすくできるよ、と応用した人ということでしょうか。

同様に、時々は思い出すべきこととして、掲示板についてもこうもりさん、しばさん、あめぞうさん、という2chへ連なることになる方々の功績(およびその影の流れのように防御技術を研究されていた、mmさんや工場長さん達)もありますね。

_ ちょっとだけブルックナー

taediumさんってテ・デウムなのかなぁ、と思ったけどテ・デウムの綴りを知らないのでAmazonでブルックナーで検索したら(宗教曲のジャンル=レクイエムなんかと同じ=だからブルックナーに限定する必要はないんだけど、ブルックナーが作曲したのは知ってるから)、まあ、あるわあるわ、ちょっとびっくり。ブーレーズまで振ってるのか。思わずクリックしそうになったけど昨日ガバガバ買ったばかりなので自粛。

生まれて最初に買ったクラシックって、ケンペがミュンヘンを振ったブルックナーの5番(テイチクがBASFと契約してたころ。新聞広告が魅力的だったのだがジャケットもきれいだった。黒地に夜明けの画じゃなかったかなぁ。2枚組みで2ヶ月分の小遣い相当だった)で、何度も聴いているうちに、本来は霧は無いはずなのに(たしか、ボンボンボンボンじゃなかったかな?)針音の霧が生まれてしまって玄妙な5番になってしまった。

その頃の友人がブルックナー/マーラー(全然脈絡ないだろうと今は思うが、音楽の友社が作曲家の伝記をそう組み合わせていた)が好きで、そいつのコレクション(クーベリックのマーラーとか)を聞かせてもらったりしたのを思い出した。

で、所期の目的はカタカナ表記のしか見つからなかったから果たせなかったのだが、コダーイも作曲してたのを思い出して調べたらTe Diumなのか。でもこっちはハンガリー語(マジャール語?)だしな。

_ 血液型プログラミング

生まれて初めて、血液型……で、おっ言えてそう、と思った。おいらO型だしなぁ。

_ キター

やっと真に妙なspamが来た。

<a href="http://citibank-validate.info/">http://web.da-us.citibank.com&BVP=/cgi-bin/citifi/scripts/&M=S&US&_u=visitor</a>

うーcitibank-validate.infoにアクセスしてみたい……

本日のツッコミ(全2件) [ツッコミを入れる]

_ るいもママ [いつもるいもがお世話になっております。娘時代に歌ったブルックナーのテ・デウムはラテン語で、綴りは Te Deum で..]

_ arton [はじめまして。それでは、早速。]


2004-04-30

_ 43

21=3 * 7

0=(3 + 7) % 10

_ 記帳をしようと

町まで出かけたが、長蛇の列見てびびってご帰宅。

みんなが怒ってた、イライラしまくってた。

ルールルルッルー

今日は良い天気。

_ 語呂合わせによる変形(縦読みでは無い)

ヤッチマイナー

チョッチマイナー

トッチマイナー

イッチマイナー

クッチマイナー

ケッチマイナー

グッチマイナー

モッチマイナー

ウッチマイナー

シッチマイナー

ヘッチマイナー

リッチマイナー

スッチマイナー

この中で1番マイナーなのはどれか?

本日のツッコミ(全2件) [ツッコミを入れる]

_ るいも [とりあえず、片っ端からググってみたのは、わたしだけ?]

_ arton [あんまマジメに考えてたわけじゃないけど、基本は「XXって」+「しまいな」です。最初のは「殺って」+「しまいな」。 し..]


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

ジェズイットを見習え