[Anthy-dev 2697] コードの抽象化 (was: to 太田さん)

アーカイブの一覧に戻る

YamaKen yamak****@bp*****
2005年 12月 13日 (火) 10:26:56 JST


ヤマケンです。

sigschemetype-compact.hについては色々と思うところがあったんです
が、まずは動くようになるのが先だと思って黙ってました。太田さんの
努力のおかげでだいぶ完全動作が近くなってきたようなんで、この機に
口出しさせてもらいます。

おこがましいですが若者の成長に資するつもりで色々書いてみたんで、
考察の種にしてください。

At Mon, 12 Dec 2005 12:51:25 -0800,
jun.l****@gmail***** wrote:
> > 昔Yamakenさんのコードが有ったんですが、あれはさらに抽象度高すぎ & 名前長す
> > ぎで僕の頭が完全にオーバーヒートして捨ててしまった経緯が有ります。
> 
> …ちょっと見てみたい気も(^^;

いやそんなに長くないですよ? ホントに。省略名を使わないという傾向
は同じですが、必要な情報を捨ててないからS->Y系の名前が長くなって
るだけです。

詳しくはr1857時点のコードを見てください。

http://lists.freedesktop.org/archives/uim-commit/2005-October/001724.html
http://lists.freedesktop.org/archives/uim-commit/2005-October/001729.html

> > SCM_TAG_OTHERS_VALUE_OFFSET_STRINGは確かに分かりづらい。TAGも冗長
> > で、SCM_STRING_VALUE_OFFSETが一番わかり易いですね。変更しておきます。
> 
> うーん、わかりやすくない。私が言いたいのは
> 
> ・一塊として捉えられるぐらい短く
> ・用語はちゃんと定義しておく
> 
> ということです。抽象化の階層を減らすのは前者の一環。ただしより重要なの
> は後者。
> 
> その名前だと例えば offset が何を指すのか、value が何の値なのかがわかり
> ません。見たところ cdr の 32 bit のうち、型情報で無い部分を value と呼
> んでいて、value の最下位 bit の位置を LSB からの index で指定したもの
> を offset としているようですが、これらの情報はどれ一つとして source に
> 出てきません。これらの情報を名前に含めるのは無理そうなので comment に
> 書いては? という事が言いたい。まあ offset は value の意味がはっきりす
> ればわかりそうですが。

私の案ではそれらの構成をコードと最小限のコメントで表現していたつ
もりです。半ドキュメント的コードなのでそこが嫌われたんだと思いま
すが。

この件に関しては私は以下の順に問題だと思ってます。

1. 名前に論理構造がない
2. tag, primary, directといった用語の概念が不明確
3. 視認性が悪い (icon性の消失)

上のマクロを例に取ります。

kzk:       SCM_TAG_OTHERS_VALUE_OFFSET_STRING
kzk改:     SCM_STRING_VALUE_OFFSET
yamaken:   SCM_OTHERS_CDR_VALUE_OFFSET_STRING
yamaken改: SCM_OCDR_VAL_OFFSET_STRING

私の命名では「others objectのcdr部のvalueフィールドのoffset、
stringの場合」という階層構造を持たせてあり、各層毎に意味を憶えれ
ば後はそれらの組み合わせで解釈できるようにしてあります。ファイル
中でも以下のように対照的に階層構造が理解できるような並べ方をして
あります。

#define SCM_OTHERS_CDR_TAG_WIDTH_STRING     SCM_OTHERS_CDR_TAG_WIDTH
#define SCM_OTHERS_CDR_TAG_OFFSET_STRING    SCM_OTHERS_CDR_TAG_OFFSET
#define SCM_OTHERS_CDR_TAG_MASK_STRING      SCM_OTHERS_CDR_TAG_MASK
#define SCM_OTHERS_CDR_VALUE_WIDTH_STRING   SCM_OTHERS_CDR_VALUE_WIDTH
#define SCM_OTHERS_CDR_VALUE_OFFSET_STRING  SCM_OTHERS_CDR_VALUE_OFFSET
#define SCM_OTHERS_CDR_VALUE_MASK_STRING    SCM_OTHERS_CDR_VALUE_MASK

名前が長くicon性が失なわれているのは太田さんのコードと同じですが、
階層構造さえ保持されていれば各階層毎のIDを短縮する事には何も問題
はありません(例: OTHERS_CDR→OCDR)。これらの作業は直交に行う事が
できます。ただ、私の好みとしては設計が確立するまでは普通に意味の
取れる名前を使っておきたいです。

これに対して現状のSCM_TAG_OTHERS_VALUE_OFFSET_STRINGという名前で
は、

・ポインタ越しにcdr部にアクセスするという情報の欠落
・tagの値にはアクセスしないのにTAGという名前が含まれ誤解

という問題があるので「others cellを指すobjectのtagの値?」とか幾
通りもの解釈を生んでしまいます。なので名前の短縮より先に一貫性の
ある構造と命名規則を確立しないと問題は解決しません。

2.の用語の概念が不明確なのもこのobject representationをどのよう
に抽象化するかという構造がしっかりしていないからです。抽象化とは
対象物の本質を抽出して単純な物事で代表させるという作業なので、本
来は進めれば進めるほどに全体の概念は単純化されてゆくはずです。こ
れが複雑に感じるという事は、抽象化が行きすぎているのではなく抽象
化に失敗しているという事です。ここしっかり認識しといてください。

何を抽象したのかが明確になっていれば、自ずとそれにふさわしい名前
も限定されます。逆に言うと不明瞭な名前が付いているという事は対象
の本質が掴めてないという事です。

現状のコードを見ると、「なんでそこに(余計な)インタフェイス作るか
な」「なんでこれを抽象化しないで複雑な操作するかな」と思う箇所が
多々あります。問題は抽象化の行きすぎではなく失敗だと思います。あ
れからだいぶcompactの実装にも馴染んだと思うので、もう一度r1857の
私のコードを眺めてみてください。

> 他にも SCM_PRIMARY_GET_VALUE_AS_INT の primary (tag) とか value とか、
> DIRECT_CAR の direct とか、よく調べないと意味がわかりません。Value は
> 特に S に入ってる値なのか X なのか Y なのかという曖昧さがあります。
> AS_INT とか AS_OBJ も普通に cast した方がわかりやすいように思います。

primary tag, subtag, extended tagの概念は私がr1857に入れましたが、
これが変質したものと思います。これもprimary (tag)という言葉が何
を抽象化していたのかという理解が不十分なために起こったものと思い
ます。まあ私の命名も万全とは言えませんが。

AS_HOGEもそうですが、全般的に概念を集約させるよりも一見綺麗に見
える不要な概念を新たに作ってかぶせる傾向が伺えます。これはカバー
かけ中毒とか分類症候群とか丁寧病に近いもののように思います。私も
昔からそういう傾向はあったんですが、意識して減らしつつあります。
一度思い切って丁寧なものを排除するコーディングしてみてはどうしょ
う。そうすれば丁寧と明瞭の違いも見えるかもしれません。

> 繰り返しになりますが、外に見えない中間物に対して verbose な名前をつけ
> るのは code clutter を助長して邪魔になるだけです。暗号みたいでもいいか
> ら、一旦覚えれば一目見てそれと認識できる名前の方が望ましいでしょう。

私はこれについては上記のように優先度は3番目ですね。大事だとは思
いますが。

このファイルの中でも抽象化の階層が複数段あるので、その格段でうま
く下層の抽象化を行えば上層に長い名前が溢れるという事態は防げるは
ずです。


さて、ここまで蘊蓄垂れる暇あるなら手を動かしてコード書けよという
感じですが、前にも言ったようにこれは教育のつもりでやってるので、
今はこのへんの技能に興味がないという事であればここまでにして直接
コード書く事にしますがどうしましょう? >太田さん

-------------------------------
ヤマケン yamak****@bp*****



Anthy-dev メーリングリストの案内
アーカイブの一覧に戻る