Architectural Decision Records を知った

※ 正確には「知った」のは恐らく半年以上前なんだけど、ちょっと触ったりドキュメントを読んだりした。

"life is a succession of choices, what is yours?" by https://unsplash.com/@ivalex

設計の基準を明確にして残しておきたい

自分の問題意識としては「設計の決定のための検討、比較などの記録が issue や pull-req に埋れがち」というものがある。またこれらは実はそれほど検索しやすくないし、記録を遡ることもやりやすくない。

この問題は実はかなり長いこと意識としては持っていて、何かみんな困っているはずなんだけどなーと思いつつ、全然情報が見つからずに思い出しては放置、思い出しては放置していたのだが、今回の直接のきっかけは以下のツイート。

このもとは以下の記事で、

時間を区切って設計を打ち切るのはおすすめできない - hitode909の日記

この記事を読んでまさにちょっと前に自分たちのやったことを思い出していて1 、何回めかのトライでようやく ADRs という言葉にはたどり着いていたんだけど、時間がなくてちゃんと掘り下げられずにまた放置していた。

今回やっと時間が確保できたので、ちょっと調べてみてメモを起こしておく。

Technology Radar ではすでに 2017年末から Adopt

Lightweight という言い方がなされており、いわゆるライトウェイトプロセスの中で XP に寄せすぎると欠落しやすくなる「なぜその設計を採用したのか」を、ライトに残すためのドキュメンテーション テクニック のようだ。

Technology Radar では Wiki や Web サイトではなくコードそのものと同期させることができるので Source Control に store することを recommend してる。

※ example を漁ってみると分かるが、比較的仔細なレベルの設計の意思決定を記録しようとしているので、同じリポジトリに入っているのが扱いやすく、また技術的には「収集して再利用」しようと思うと Wiki ではなくファイルとして存在している方がよいので、Technology Radar の言う通りにするのがよさそう。手っ取り早く始めるには Wiki の方がよさそうに見えるけど。

基本のツールは MADR っぽい

おそらくドキュメントの読み書きが低コストで行えればなんでもよいが、昨今の流れだと大半のドキュメントは Markdown を基本に作成されているはずなので、Markdown で書く ADR ( Architectural Decision Records ) ということで MADR という呼び方があるようだ。

おそらく reST でも Asciidoc でも同じように考えられるはずだし、Word や Google Docs でも構わないように感じる。ただ、コードからの距離は遠くない方がよさそう。少なくとも詳細な実装に紐づく部分は。

Templates

ここまでの情報だと、意図していることはなんとなく分かるが、実際に何を書けばよいかがよく分からない。そこでまずは本家で紹介されている Template を漁ってみる。

RFC っぽい重厚さを持つ流派と、よりライトな流派があり、ライトな流派は以下のように似たような内容を扱っているようだ。

Nygard (2011)Y-StatementsMADRAlexandrian Pattern
   prologue
contextcontextcontextdiscussion ( context )
status   
 facingdecision drivers 
  consider options 
decisionwe decideddecision outcome ( consequences posi / nega )solution ( decision )
concequensesalternatives not chosen results ( consequences )
 to achieve  
 acceptingpros and cons of options 

だいたいどれも

  • context
  • options
  • decision
  • pros / cons of options

みたいな感じになっている。

adr.github.io がおよそ 3, 4 年前にリリースされており、この頃からこうしたドキュメンテーションの話は一部で盛り上がっているっぽい。しかし Nygard の post は 2011 年であり、もう10年前の話になっている。

XP やライトウェイトプロセス、アジャイルなどの盛り上がりが一段落し、そうは言っても実践的に役に立つドキュメントの手法についても意見が出始めたのがこの頃なんだろうか。

examples

こうして見るとけっこう細かいレベルの記述になっていることが分かる。

処理系

書くには

とりあえず sh script の以下のものが手頃で扱いやすい。これは Markdown を基本にしている。

いろいろな言語に移植されているが、けっきょくのところ決まったテンプレートに従って Markdown を書けばよいだけなので、あまり凝った道具は要らないと思う。

読むには

Markdown で書くと決めたら Markdown なのでそのまま読めなくもないが、

なんかでもよさそう。また多くの人が手軽に読めるようにするという意味では

などを使って Web サイトを起こすのもよいのではないかという気がしている。Wiki と違ってファイルなので、どこかでまとめたり、統一的な UI をもたせたりということもそれほど難しくないはず。

template の種類と組織の回し方と記録の残し方

ということで Lightweight Architecture Decision Records | Technology Radar | ThoughtworksArchitectural Decision Records | adr.github.io をベースにあれこれ触ってみたけど、恐らく template の決め方はいくつかパターンがあって、その判断基準には

  • ドキュメントベースでの意思決定に慣れているかどうか
  • 記録の運用が長期間に渡るかどうか

があると思う。

上に挙げた template はあまり status を項目に持っていないんだけど、これがドキュメントベースでレビューして合議で決定するようなスタイルだと status を持っているのは非常に重要になるだろう。また長期間運用されて設計が更新されていくような場合にも status : obsolete などが欲しくなるように思う。

また、

Getting Started with Architecture Decision Records | Blog

では

  • 社内の既存のルールに従っているだけの場合には ADR は書かなくてよい
  • メール、電話、ミーティングなどを挟んで合意にいたった場合、それを書き起こすことには価値がある
  • ほとんどの場合、ADR は他のドキュメントと同じように Wiki やドキュメントシステムに書く

としている。

恐らくドキュメントベースの議論はそれほど重視しておらず、あくまで結果を写し止めておくような印象を受ける。こっちの方がふつうの組織にはよりマッチしそうに見える。少なくとも「始めやすく、残しやすい」のは間違いなさそう。

ただこういうドキュメントは基本的にエンジニア以外は興味を持たないので、共有のドキュメントシステムにあると、メンテナンスや検索、オンボーディングの視点ではイマイチかもしれない。(プロジェクトをまたいで ADR だけを収集するような方法にも向いていない。)

参考

Architecture Decision Record Template: Y-Statements | ZIO’s Blog: Architectural Decisions, (Micro-)Services and More

から辿っていける話がとても面白い。この Y-Statements も original は medium の post である 2020 年ではなく、SATURN という Software Architecture Community の 2012 年の際に発表されたものらしい。

こうして見てみると ADRs だけではなく AD ( Architectual Decisions ) や AKM ( Architectural Knowledge Management ) という言葉も多く登場してくるのが分かる。ADR という言葉だけでなく、その辺も掘っていけるといいのかな。

(1) SATURN: A Software Architecture Community - YouTube

もう少し全体感がまとまったものは

Documenting Software Architecture – @hgraca

からたどっていける話も面白い。

あと日本語の事例は少ないけど、以下のような感じ。

割と MADR そのままが多いのかな。


  1. いくつかの仕組みが連携する際に、1) 連携元のアウトプット、2) 連携先のインプット、3) 連携先の振る舞いが関係するんだけど、完全な動作を前提にすると 1, 2, 3 の順に実装するしかない。しかし、実際には 3 が決まっていないと 1 が決まらない、なんてことはよくある。そこで 1 の設計を仮置きしておいて、2 はインプットできたものとして適当な値を fixture よろしく置いておいて 3 の実装に取り掛かって、そこから 1 を決定して 1, 2 を実装する、なんてことはよくある。この際、1 の仮置きをちゃんと参照しやすい形で残しておきたい、みたいな話。 

RRはRSpec 3には対応していない。でも…。

最近はそうでもないんだけど、以前は RSpec の test double の記法がどうしても納得いかなくて RR というライブラリを一部のテストに採用している。今回この RR を採用しているプロジェクトの RSpec を 2 から 3 に上げて動かなくなったのでその対処について。

結論から言うと RR 自体は RSpec 3 には対応していない。

rr/rr: RR is a test double framework that features a rich selection of double techniques and a terse syntax.

as well as the following test frameworks:

Support for Rspec 3 · Issue #65 · rr/rr

There is no plan to support RSpec 3.
If we support RSpec 3, we\'ll create rspec-rr gem instead of implementing RSpec 3 support into rr itself.

アッハイ。

でも実際には

stub(Klass).method {}

RR.stub(Klass).method {}

に書き換えれば動く。

本来 RSpec 3 は stub, mock を double の alias に使わないとかグローバル汚染させないモードもあるらしいので、共存することもできるんじゃないかという気がしたんだけど、なんか割と小さい変更で動くようになってしまったのでどうでもよくなってしまった。

少なくとも RR で書いていたものをすべて RSpec や Minitest の double の書き方に合わせ直す方がはるかに面倒だし、この程度で済めば御の字だろう。

[2016-07-27 追記]

after { RR.reset }

がないとあちこち変な動きをするみたい。

RSpec 3に移行するのそんなに大変じゃないかも

以前作った Rails アプリの一部を分離したアプリに Pact を利用して API を実装しようとしたんだけど、昨日 RSpec 2 では動かないということが発覚したので RSpec 3 への移行作業。

ひじょーに気が重くて避けられるなら避けたかったので無駄に Pact の内部のコードを追いかけてしまったが、結論から言うと自分の使い方では RSpec 3 への移行コストは割と杞憂だったようだ。

以下、やったことをざざっとメモ。なお、アップグレード対象バージョンは 2.99 → 3.5.1

  • spec_helper.rb を退避して rails g から spec_helper.rb, rails_helper.rb を上書きインストール
  • rspec-rails は spec_helper ではなく rails_helper を呼べということでエディタの力でエイヤ
    • rails_helper.rb の中だけ手で書き戻す
  • subject, should の部分は特に直す必要がなかった(たぶん事前の情報で最小限で済むように準備しておいたのだろう)
  • be_true, be_false はエディタの力でエイヤ。
  • 時間が掛かったのは RR

今さらながら Hpricot は便利

Hpricot, a fast and delightful HTML parser

なんと言っても

HTML でも XHTML でもそれなりに同じように動く

っていうさじ加減が絶妙すぎる。

XML を対象にした便利なツールは実は結構たくさんある。でも世界の Web 上になんとかソースは存在しているが欲しい形にはなってなくて不便、という類いの情報って実は圧倒的に XHTML でないことが多い。だから XML を対象にした便利ツールの大半は使いものにならない。

ブラウザ上では早くから HTML でも XHTML でも DOM 操作は可能だったし、今は XPath も CSS セレクタも使える、といった具合でどんどん便利になっている。でもサーバ側というか非ブラウザ環境ではゴリゴリ正規表現書いたり、なんだか不便な状況が続いていたように思う。特に PHP は C の wrapper なので XML 関数は充実しているんだけど全然使えないという悲しい状況だった。1

これがあーた。何この Hpricot の楽さ。これに open-uri を組み合わせればまるで remote include 可能な PHP のように作業を始められる。

require 'open-uri'
require 'kconv'
require 'rubygems'
require 'hpricot'

Hpricot( open( URL ).read.toutf8 )

また Hpricot::Elem オブジェクトは inspect を書き換えているので、単に p しただけでどのような要素が取得できているのかチェックできて楽ちん。

気が利くなぁ。気が利くよ。さすが why だよ。抜けるところは手を抜くところもさすがだよ。Syck の to_yaml() も個人的にはすげー困るけど、しょうがないかなぁという気もしてきちゃうよ。

  1. だから個人的には Pear の XML_HTMLSax3 を wrap して stack を用意することで階層構造のチェックが可能なものを使っている。結果を serialize して cache しちゃえばそれなりの速度で動いてくれる。 

javascript.el は googlecode にあった

mewde - Google Code

あちこちで紹介されている割に本家が存在しなくなっていたような感じの javascript.el は googlecode にありました。

これで一安心だなー。いつまでもリンク先が 404 や 410 を返してたものはさすがに使いたくないもの。

カントリーサイン10コげと。

先週末に3泊4日で北海道をドライブした。すっかりどうでしょうバカの称号を得るレベルに達した私は当然のようにカントリーサインの撮影を行った。とは言えカントリーサインを見つけたら停車するってなことはしてないので撮れたものは見つけたものの一部に過ぎない。撮影に成功したのは以下のカントリーサイン。

あえてすべてノートリミングでどうぞ。全部自分で撮影したわけじゃないけど。

中富良野町中富良野町カントリーサイン
芽室町芽室町カントリーサイン
帯広市帯広市カントリーサイン
池田町池田町カントリーサイン
本別町本別町カントリーサイン
足寄町足寄町カントリーサイン
阿寒町阿寒町カントリーサイン
美幌町美幌町カントリーサイン
標茶町標茶町カントリーサイン
釧路町釧路町カントリーサイン

トトロで泣いた

@金曜ロードショー

カンタのばあちゃんがドーラの声に似ているような感じがして調べたら全然違った。

しかし、トトロで泣けるとは。年を取るのも悪くないかもしんない。

安眠はどこにある

うるささと暑さを両方いっぺんに解決する方法として耳栓をして窓を開けて寝るという方法を昨日試し、「うまくいった」と喜んでいたのだが、昨日うまくいったのは偶然だったようだ。今日はやはり午前3時に轟音で目が覚めた。なぜなら、

耳栓が取れていたから。

昨日はたまたま寝返り方で耳栓が取れなかったが、朝まで耳栓をしているとは限らないのが現実のようだ。こりゃ安眠ソリューションとして失格か。

About

例によって個人のなんちゃらです