読者です 読者をやめる 読者になる 読者になる

無限のメモリ空間と絶対に落ちないプロセスを仮定して「ビジネスロジック」をあぶり出す

先日、前職の上司から「そろそろプロフィールに"詩人"を追加するべきだ」と言われました a-suenami です。今日も今日とて詩人業を行なっていきますよ!

ビジネスロジック」とは何か

最近、業務で、比較的中長期的なアーキテクチャの見直しだったり、新機能の設計だったりをさせてもらう機会が増えた。

コンポーネントをどういう風に分割するかとか、それぞれのコンポーネントを主にどのチームでメンテナンスしていくかとか、そういうのを考えるのは楽しい反面、かなり熟慮に熟慮を重ねないといけないものでもあるのでかなり責任を感じるというのもある。

まあ、そんなこんなでいろいろうーんうーんって悩んでいると昔(たぶん DDD コミュニティだと思うけど)誰かに言われた「無限のメモリ空間と絶対に落ちないプロセスがあったとして、それでもそのコードを書かないといけないのならそれがあなたのドメインだ」という言葉だ。

モデリングをしているとドメインロジックとかビジネスロジックとかって言葉はよく出てくるんだけど、これは結構なかなか人によって解釈が違っていたり、明確な定義がなくて難しい。エリックエヴァンスの DDD 本ではユビキタス言語というパターンがあって、それがちゃんと構築できてる前提であればドメインか非ドメインかわかりやすいんだけど、あれをちゃんと実践するのはすごく大変だ。僕も何年か前にあの本を読んで以来、チーム内でいろいろ試みてみたけどいまだに手応えのある成功体験はないし、プロダクトオーナーを含むチーム全体を巻き込んでいかないとかなり厳しい。

で、もうちょっと簡単にそれがビジネスロジックなのか or not を判別したいことがあって、それをもとにその振る舞いをどこに実装していくべきかって考える感じのことがある。まあイメージとしては軽量 DDD というか、少なくともエンジニア同士では認識が揃っていて、何かを実装しないといけないときにそれをどこに定義すればいいかを迷わなくてもいい仕組みくらいだと思ってもらえるとよいと思う。もしそれを修正しないといけないことになったとしたときに、それがビジネス都合なのか、アーキテクチャ都合なのかをちゃんと区別して、決してそれが混じらないということが実現されるだけでもかなりシステムのメンテナンスは楽になる。逆に、どっち側の変化によっても同じオブジェクトやメソッドが修正されるという状態は明らかにオブジェクト指向設計の単一責務原則に反しているし、障害が発生したときの問題切り分けが著しく難しくもなるので基本的に避けたい。

もちろんそうやって分割されたオブジェクトやメソッドのうち、ビジネス都合で定義される側のクラスやメソッドがユビキタス言語になってるほうがなおよいけど、まあそこは一旦エンジニア同士で伝わればいいよねっていう妥協もアリだと最近は思い始めた。*1

そして、その判別方法が「無限のメモリ空間」と「絶対に落ちないプロセス」を仮定することによる思考実験である。たぶん厳密には「断線・遅延しないネットワーク」も必要なのかもしれないけど、まあ要するに永続化やキャッシングから解放されたときにそれでもそのコードは必要なのかっていうことで、これはなかなか結構おもしろい思考実験である。

僕たちがどれだけ永続化に関するコードを書いているか

これ、実際にやってみるとわかるんだけど、実際に考えてみるとほとんどのコードは必要なくなるってことに気づく。僕らが一体どれだけ永続化とキャッシュに振り回されてるのかってことだ。

逆に言うと、そのレイヤーの心配ごとが軽減すれば僕たちはもっと自分たちのビジネスに集中できるし、ちゃんとしかるべきクラスだかオブジェクトだかに隠蔽してあげてビジネスロジック層からは意識しなくて済むようにしてあげるべきなんだよ。設計ってそういうことだと思うんだ。僕が ActiveRecord を Dis るのは(おっと誰か来たようだ

システムは何故バグるのか

これは完全に僕の経験則だけど、システム障害において、ビジネスロジックにバグが混入していたというケースは実はそんなに多くない。エンタープライジーな開発現場を経験してないので、そもそもこのレイヤーのロジックが薄いプロジェクトしか知らないというのはあるのかもしれないけど、それにしたって永続化やキャッシュに関するバグ、ミドルウェアや連携システムの冗長化不備がほとんどである。

その中でも本当に多いのは

  • キャッシュに関する何か
    • リフレッシュされてなくて古いキャッシュを参照する、等
  • 失敗可能性(要するに NULL 参照)の考慮漏れ
  • 永続化したデータの取得遅延
    • まあ、平たく言うとスロークエリ

で、僕は勝手にこれを三大バグ発生要因と呼んでいる。(あくまで勝手に)

永続化もキャッシュもなくてよくて、NULL もない、そんな理想郷がもしあるならその世界で実装されるシステムの障害は激減するはずだ。

ビジネスロジックは意外と薄い(かもしれない)からこその創造性

これは仮説だし、僕自身まったく検証できてないんだけど、それを念頭に読んで欲しい。

思考実験として仮定した無限のメモリと落ちないプロセスは実際には実現不可能だけど、コンポーネント分割を工夫して永続化に関する関心事をあるレイヤーで隠蔽することはできるし、そうするべきでもある。それによって、少なくともビジネスロジック層から見れば永続化を意識しなくてよくなるので、先に述べた理想郷が仮想的には実現できる。

で、このときに気づくんだけど、実際にはビジネスロジックなんて予想外に少ない。もちろんドメインによると思うけど、Web アプリケーションにおける参照系の機能(つまり Web ページの閲覧)なんてだいたい DB に入ってるデータをそのまま画面に表示するだけだったりするし、あるとしたら表示整形くらいでそれはビジネスロジックというよりはプレゼンテーションのロジックだ。僕は今メディアの会社にいるのでなおさらだけど、ビジネス = プレゼンテーションみたいなもんである。

そういう状況にエンジニアが放り込まれたらどうなる?

エンジニアは本質的にコードを書きたい人種が多いんじゃないかと僕は思っている。そんな人たちが永続化の関心事が隠蔽されていて「コードを書く必要がない」環境に置かれたら、どうやったら自分たちはもっとコードが書けるか、こういう機能が実現できたらいいんじゃないかっていう創造性が発揮されるんじゃないかなと。これは予想というよりも自分と一緒に仕事をしてくれる人たちにそれを期待したいっていう意味も込もってるんだけど。

もちろん一定数のエンジニアには低レイヤーへの憧れみたいなものもあると思うし、僕も若い頃には Linux コマンドを使いこなして、呪文のようなバイナリを見たり、まるで MySQL と会話しているかのような先輩エンジニアに尊敬の念をよく抱いたものである。ビジネスロジックが意外と薄いということは、逆に言えばシステムの根幹をなすのは永続化部分のコードだとも言えるのでそこに興味を持つのは自然なことだし、その場合は隠蔽された先の、永続化に関するコンポーネントの実装に携わればよい。

重要なのは、今自分が何のコードを書いているのかちゃんと意識すること。

ビジネスを加速していくために新しい機能を実装するか、その人たちを支えるために適切に永続化を隠蔽するか、趣味・嗜好も得手・不得手あるだろうし、会社やチームの都合でどっちがより重要なフェーズかってのもあると思うけど、少なくともそこが適切に分離されていて、どちらかをやっているときはもう一方を意識しなくていい状況は最低限実現していきたよねと思った週末なのであった。(いい感じにまとまった。たぶん。)

追記 2016/09/25 16:01

きょんさんからコメントいただいたので追記。

このエントリで「ビジネスロジック」という言葉を使ったのは単にわかりやすいと思っただけなのと、代替できるわかりやすい他のワードが思いつかなかっただけである。今となっては反省している。

僕自身も普段の業務において「ビジネスロジック」という言葉はあまり使わないので、とりあえず Twitter ではしれっと弁明しておいた。

ただ何て言うんだろうな… まさにきょんさんが言っている「適切に分割して、適切な注意を払え」っていうのがこのエントリで一番伝えたかったことで、それはどんなシステムでも必要なことだろうし、ましてオブジェクト指向パラダイムを持つプログラミング言語を使っていれば息を吸って吐くようにできないといけないことではあるんだけど、実際にはそれができてない人やチームがあって、そのときにわりとわかりやすい分割の方法論としてのこの思考実験を提案したかったっていうのがたぶん正しい。

このエントリで言っている「ビジネスロジック」というのは適切な命名が難しいので長ったらしい文章で説明するしかないけど「非機能要件を隠蔽して機能要件のみを抽出したもの」のことで、これは技術的バックグラウンドのない人のメンタルモデルに近いはずだし、ユースケースはここで抽出された語彙を使って記述されるべきだよねって僕は思っているので、そのためにはまずそこを分割して語彙を手に入れないといけないというのが主な主張。

ちなみに「ユーザーストーリになればより非機能的な部分がふえてくる」というのはきょんさんのコメントで初めて気づいた。確かにそうだ。

さらに追記 2016/09/25 16:16

もしかして機能的・非機能的という分類自体がもう必要なくて、やはり時代は ActiveRecord なんだガハハみたいな意見があったり、そういうデザインパターンや組織パターンがあるのだとするとそれはそれで興味深い気もする。

システムというのは必ず何らかの要求にもとづいて構築されるもののはずで、従来(汎用機〜クライアント・サーバ時代まで?)はその要求の内容として機能的なものが支配的で非機能的なものはエンジニアが何とかすればよかったけど、今はそうじゃなくてむしろ非機能的な部分こそがビジネスの中心を担うことがある(実際、僕の今いる会社とかはその可能性がある)のだとすると、その非機能要求が一体どういう言葉で誰の手によって作られて、どういう伝達をされて、どのようにして実際のチームの開発プロセスに取り込まれていくべきなのかという議論は大変興味深い。

十分な性能、十分なセキュリティ、安定稼働、こういったものは今までは UX のなんとか品質モデルでいうと「当たり前品質」とかって呼ばれるものだったと思うんだけど、むしろこれが「動機付け品質」になりうるのだとすると、そのときの組織のあり方やアーキテクチャのあり方はどうあるべきなんだろうな〜とちょっと思ったりする。

*1:DDD界隈の方々、すいません。マサカリは甘んじて受ける覚悟です。

知っていてこだわらない、それがいいソフトウェアエンジニアの条件なんだと僕は思うんだ

週末の午前中、カフェでアイスコーヒーを飲みながらふとポエムでも書いてみようかと思い立ってしまったので、ちょっと前からよく考えていることを書く。本当に思いつきで書くので乱文になる可能性が高いけどご容赦いただきたい。そもそもブログを書くこと自体が相当久しぶりだ。

僕ももう 30 をすぎて、プログラマの世界ではさすがにもう若手とは呼べなくなり、教育っていうのはおこがましいけど、まあ自分より若い人たちの指導みたいなことをやらないといけない立場になってきたからこそ、「いいプログラマとはどういう人なんだろう。この人たちはどういうことを学べたら幸せだろう。」ということをよく考えるようになった。そういう話をする。

プログラマは手段のスペシャリストである

世の中には目的・手段論みたいな論調が存在する。 「それは手段だよね。目的をはき違えたらダメだよ。」という話はいたるところでよく耳にするんだけど、僕はこれを結構ナンセンスな話だなと思っている。目的と手段というのはスコープによって異なってくるし、そういう意味ではかなり強く文脈に依存していると思うからだ。

例えば「大学受験に合格する」という誰かの想いがあるとする。これは高校 3 年生や予備校生にとっては目的になりうる。そのために彼らは一生懸命勉強しているんだから。でも長い人生の中においては大学に入学するということ自体が別の何かに対する手段だ。 ビジネスの現場においてある人が目的だと思っている KPI の達成だって究極的には利益を上げるための手段だし、その会社の存在そのものが営利とは別の何かを成し遂げるための手段かもしれない。事業の数字をきちんと作るというのはプロジェクト内では目的だけど、株主総会では完全に手段だ。目的・手段論なんてそんなもんだと僕は思う。

目的と手段なんて今その状況において対象としているスコープに依存する。だからそれが目的なのか手段なのかなんて気にしなくていい。まして我々が生業としているプログラミングなんて多くの場合において手段だ。プログラミングが目的のケースなんて計算機科学の研究者くらいじゃないだろうか。(そしてそれも別の応用研究から見れば手段だ。)

昔、誰かが「プログラマは手段のスペシャリストだ」と言ってたんだけど、これはその通りだと僕も思っていて、だから僕らは、偉い人に「それは手段だよね」って言われても堂々と「ええ、だってそれが僕らの専門性ですから」って言い返せばいい。手段のスペシャリストだからこそ、目的が何であれ、僕らはそれを達成することに注力すればいい。それが僕らの仕事なんだよ。

手段へのこだわりがエンジニアをスペシャリストにする

ただ、プログラマに関して言うと、いやプログラミングに限らずソフトウェアエンジニアリング全般がそうだと思うけど、ある分野に精通してそれを手段として使いこなせるようになるためにはそれなりの時間と経験を要するし、それは結構狂気に似た没頭が必要だと思う。それこそ「目的なんか知るか。俺はこの技術が使いたいんだ!」っていう態度が結果的にその人をその技術のスペシャリストに導くことも多いし、自分が置かれている状況を理解していわゆる"大人な選択"をするようでは没頭しているとは言えないことも多い。

そういった手段へのこだわりや情熱を持たず、その時点での目的に対して必要最小限の技術の使い方しか学ばず、早い段階でバランスのとれたエンジニアに成熟してしまった人は、平時には高いパフォーマンスを発揮するんだけど、目指すべき方向性が変わってしまったときや緊急の対応が必要な時に頼りにならない。

僕はそういう「大人で、聞き分けのいい」ソフトウェアエンジニアになりたいと思わないし、自分の後輩や同僚にもそうなって欲しくないと思う。

知っていてこだわらない、それがいいソフトウェアエンジニア

例えば、初めて自転車に乗れたときの感動を今でも覚えている人はいるだろうか。かっこいい乗り方、速くこげる乗り方、疲れない乗り方、子どものころにはそんないろいろな方法を練習した人も今では単に移動の手段で使っている人が多いのではないかと思う。

目的だったものが手段になるということはそういうことだと思う。かっこいい自転車の乗り方も知ってる、疲れないこぎ方も速くこげるこぎ方も知ってる、だってかつてはそれに強いこだわりをもって必死に練習したんだから。でも今は単にある場所まで移動したいだけだからそのために必要最低限の使い方をするんだ、と。

エンジニアリングもそうなんだよ。あるプログラミング言語の得意とすること・苦手とすること、データストアとして RDB が得意なこと・NoSQL が得意なこと、各アプリケーションフレームワークの設計思想、そういうのは熱狂的なまでのこだわりとそれなりの量の経験の先にしか身につかない気がするんだけど、さらにその先にそれを手段として使いこなせるようになるんだと思っていて、そのときにこそ熱狂的な情熱からちょっと冷めて物事を俯瞰的に見れるようになるんだと思う。

もちろん情熱を失ったほうがいいと言いたいわけではないし、必ずしも俯瞰的な見方をしたほうがいいというわけでもない。ある領域へのこだわりや情熱は個人の嗜好性の範囲ではずっと持ち続けていいと思う。 ただ多くの開発現場がチームでプロジェクトを進めていく以上、チームで目的とすることとそれを実現する手段の整合性は重要で、そのためには目的と手段のスコープの切り替えが大事になってくると思っている。 そういう意味で、熱狂的な情熱と周辺領域まで含めた俯瞰的な視点の切り替えを繰り返していくことは大事で、その結果だんだん目的と手段のスコープの切り替えが上手になっていって、手段としての専門性の深さと目的との整合性をうまくとれるような、そんな理想のエンジニアになれるんじゃないかなと思うんだ。

僕が理想とする「知っていてこだわらない」エンジニアというのはそういう人で、僕自身も今後もそれを目指していくし、僕が若者に伝えていきたいこともそういうことなんだよなぁ。

TDDBC 仙台 5 に行ってきた #tddbc

2015/11/14(土) に TDDBC 仙台 5 に行ってきたので忘れないうちに書いておきます。

きっかけ

TDDBC 仙台には 2 年前に TA として参加したんですが昨年は参加してなくて仙台の皆さんにはすっかりご無沙汰してしまっているなと思っていたところで今年もやりますというアナウンスが TL に流れてきた感じでした。

そこでサポート言語の中に Go があることを確認して参加を決めた感じです。 今仕事で Go を使ってるのでもっと慣れておきたかったのと、Go のテスト文化は特殊すぎるので一度 TDDBC で議論してみたかった感じです。

前日と当日朝の様子

前日こんな感じだった僕です。すごく無計画ですね。

しかもちゃっかり花金も満喫してます。

結果がこれです。

というわけで、運営のみなさんや僕とペアを組む予定になっていた方*1には本当にご迷惑をおかけしました。すいません。

慌てて東京駅に向かい新幹線に乗り込んで、何とか午後のコンテンツから参加させてもらいました。

お題

TDDBC 仙台といえば毎回 takehiro_i さんが作成してくれているお題がひとつの楽しみだったりするわけですが、ご多分に漏れず今年もとてもおもしろい課題でした。格子点を扱う課題だったのですが、すでに全文公開されているので詳細は以下を参照してください。

TDD Boot Camp(TDDBC) - TDDBC仙台05/課題

僕も参加者として課題を解いたのですが個人的におもしろいなーと思ったのは以下のあたりでした。

  • 課題が段階的に公開される
    • これは以前の仙台開催のときもそうでしたね。
    • 実装するべきものの全体像がはじめはわからないので TDD のフィードバックループをまわしやすいお題提供のしかただと思います。
  • 早すぎる最適化 v.s. 拡張可能な設計 ファイッ
    • 上記のお題提供のされかたと関係しますけど、全体像がわからないから現状書かれたテストをグリーンにしたあとにどこまでリファクタリングするかというのがペアによって個性が出てたと思います。
    • ある程度抽象化してその抽象化したものに名前をつけて別の型や別のメソッドとしていたり、次の課題以降でどういう拡張があると予想して設計判断をしていたり、逆にグリーンにした後にほとんどリファクタリングせずにほぼベタ書きのままのコードが残っていたり。
    • いろいろな設計判断があっておもしろかったと思いました。
  • 型設計や責務設計の重要性がフィーチャーされやすいテーマ
    • 格子点とその集合をどういう型として設計するかとかそれぞれの責務をどういう風に考えるかというところが重要になる課題だったかと思います。
    • そういう意味で言語の文化や個性がよく出てた気がします。
    • 今回はなかったですが関数型のパラダイムが色濃い言語だったらどうなったのかちょっと興味があります。

で、お前は結局何やってたの

盛大な寝坊 & 遅刻のために本来やろうとしてた Go でのペアに入れなかったのですが、スタッフさんとペアだった JS 組があったのでそこでペアチェンジして ES6 でお題を解いてました。 僕の ES 力が低すぎて若者に迷惑をかけたところもあると思いますけど、TDD 的な視点でいろいろ教えることはできたんじゃないかなーと思います。

とてもモダンな JS 環境で TDD できてテンションあがったのでこの流れでフロントエンドエンジニアを目指すのもいい気がしますね。

懇親会 & LT

終わったあとは会場であるメンバーズさんのオフィスでそのまま懇親会兼LT大会が執り行われました。 和室っぽいスペースがありゆったりとした雰囲気でLT聞いたりディスカッションをしたりできました。

僕も LT しました。思ったより好評でよかったです。

www.slideshare.net

お礼

TDDBC はもう何度も参加してますがそれでも本当に毎回新しい学びがあり、今回も参加してよかったと思います。 スタッフの皆さん、会場を提供していただいたメンバーズさん、本当にありがとうございました。

一応 Go でやってみました

元々は Go で参加するつもりだったので、ペアプロはできませんでしたがソロで自分なりにやってみました。意見募集です。

*1:Goで普通にペアができる予定だったらしい

株式会社はてなに入社しました

株式会社はてなに入社しました

株式会社はてなに入社しました - hitode909の日記

そろそろドメイン駆動設計はもうちょっとだけ細分化されるべき

昨日飲みながらドメイン駆動設計(以下、DDD)についてしゃべっていて思ったことを書く。

ドメイン駆動設計(DDD)って?

DDD とは何かという説明についてはぐぐったらたくさん出てくると思うので割愛。

Wikipedia の引用だけしておきます。(雑)

ドメイン駆動設計 - Wikipedia

ドメイン駆動設計(英: Domain-driven design, DDD)とはソフトウェアの設計手法であり、'複雑なドメインの設計はモデルベースで行うべきであり'、'また大半のソフトウェアプロジェクトではシステムを実装するための特定の技術ではなくドメインそのものとドメインのロジックに焦点を置くべき'とする。この名称は Eric Evans が同名の著作で用いた。

興味がある人はこちらを読んでください。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計 (Object Oriented Selection)

ソフトウェア設計手法としての DDD

僕は DDD を最初ソフトウェアの設計手法として学んだ。ソフトウェア設計というと表現が大袈裟かもしれないけど、要は今自分の目の前にあるコードベースがもっと綺麗でメンテしやすい形であって欲しいという願いが第一義的だった。

当時僕はとある業務システムをやっていたのだけどそのプロジェクトでは「このボタンを押したときにサーバとの通信が発生して性能的に(以下略」とか「データベースにはこういうデータを保存しているのでその要件を満たすためには(以下略」とか「ブラウザのクッキーに(以下略」とか到底ユビキタス言語のユの字も出てこないようなコミュニケーションをやっていて、エンジニアと非エンジニアのコミュニケーションコストがすごく高かった(ように感じた)。

ただ当時の僕はこのチームのコミュニケーションをもっと円滑したいなんていう高尚なことを考えていたわけではない。ただ目の前にあるコードがどんどん自分の理想から離れていくのが我慢できなかっただけだ。円滑ではないコミュニケーションに引っ張られて要求はどんどん複雑化し、仕様は変わり、それにアドホックに対応した形跡がコード中に散見されるという状態で、僕はこれではこのプロジェクトを嫌いになってしまいそうだなと思ってしまったことが DDD を学ぶきっかけだった。

だから僕はかなり実装に近い立場でエリック・エヴァンスの DDD 本を読んだ。

エンティティとバリューオブジェクトは何が違うのか、サービスとは何か、仕様パターンは何が嬉しいのか、ファクトリーとかポリシーとかもあるのか、そういうところが僕が最初に DDD 本を読んだときの興味だったし、その流れでそもそも自分はオブジェクト指向をちゃんと理解してなかったような気がして別の書籍をあたったりもした。

まあ、ただそれだけだったら DDD 本はただのデザインパターン本ということになってしまうしそれだったら GoF でも読んでろよという話で、それはそうだと今なら本当に思うんだけど、当時の僕はこんな感じだったんだというお話。

組織論としての DDD

これは最近思っていることだけど、ドメインの分析の成果として適切な大きさのチームへの分割があると思う。DDD 本にあるパターンでいうと「境界づけられたコンテキスト」とか「コンテキストマップ」とかがそうだ。

ある程度システムが複雑になってくるとそこに複数のコンテキストが存在することが多くなる。その場合、無理にドメインモデルを統合するのでなく、コンテキストに明確な境界を設定しコンテキストごとに別々のモデルを構築したり、異なるドメインモデルの接点を明確にしたりすることで、全体が大規模かつハイコンテキストになってもメンテナンスしやすい大きさのチームやプロセスやアーキテクチャを保つことができる。これは DDD の大きな価値である。

これについては昨年末くらいからよく言葉を聞くようになったマイクロサービス(microservices)と似てる。システムが大規模になった場合、それは小さいサービスに分割したほうが個々のシステムはシンプルに保つことができるがサービス間のインターフェースが増えるとそこで問題が起こりやすくなるし、それを防ぐためのコミュニケーションが必要になってしまう。なので、マイクロサービスはどういう単位で分割するかというのが非常に大事であり、個々のサービスのアーキテクチャ以上にサービス間のインターフェースやそこで生じるコミュニケーションの設計に気を遣わないといけない。

それらの方法論を「境界づけられたコンテキスト」「コンテキストマップ」というパターンで提供しているのが DDD であり、つまり DDD とは組織パターンであると捉えることができる。

DDD の話は DDD だけにとどまらない

DDD の話をしているともっと広く話が盛り上がってしまうことが多い。

DDD 自体が設計手法や分析手法でもあり、組織論でもあり、どういう立場でそれを捉えるかによって本質が異なってくるようなものなので当然かもしれない。

最近、 DDD はとても流行っているように思う。Twitter や誰かのブログで毎日のように DDD の話題を目にするし、現場に導入してるという話もそれなりに聞く。コミュニティとしては十分に盛り上がってきたのではないかと思う。

そんな今だからこそ、もう少し掘り下げた議論をし始めるべきではないか。エリック・エヴァンスの DDD から僕らはたくさんのことを学んだけど、もっと実践的に、もっと他の知識と組み合わせてその効果を最大化する余地が DDD にはあると思う。

個人的には

あたりは結構盛り上がりそうだな、と思っている。

ソフトウェアプロセスは人に依存するようになった

これを読んでなんとなく思ったことを書く。

僕は「ソフトウェアプロセスが盛り上がってこれから普及するぞ(でも下火になった)って時期」を知らないので、元記事で使われてる言葉をかいつまみながら想像を膨らませて書くことになります。なので、紹介されてる書籍を読んでから書けよという話ではある*1のですが、とりいそぎ忘れないうちにポエム程度に書いておこうかと思います。

ただ、明らかな事実誤認等があればどなたかご指摘ください。

プロセスは人に依存するようになった

「ソフトウェアプロセス技術」というものがそもそもどういうものなのか僕はイメージがわいていなくて、なのでそれが流行りかけて下火になったことに対しても何も言えないというか僕として意見はないのだけど、それらが技術として体系化されたものでなくもっと人に依存するものになった可能性はあると思っている。

ソフトウェアの開発プロセスが技術的に体系化されて管理されるのではなく、そこに集まった人たちでどうやって開発を進めるかということに比重が置かれてきた感じ。

「あらかじめ決めることを決めてからソフトウェアを開発すること」は依然大事

「ソフトウェアプロセス技術」がいわゆるプロジェクトマネジメントの話なのか、もう少しアーキテクチャに寄った話なのかわからないんだけど*2、いずれにしてもビジネス全体のあり方を整理して決めることを決めてから開発を進めることの重要性は低下していないと思う。

決めることをちゃんと決めて開発を進めることでプロジェクト資源的にもアーキテクチャ的にも無駄を極力なくして開発をすることは大事なんだけどそれが難しすぎて意思決定を遅らせたくなったという状況があって、そのときに救世主的に登場したのがアジャイルに代表されるようなインクリメンタル型開発なのではないかと思う。

ただインクリメンタルに開発をすることで意思決定を遅らせるというのは実際にやってみるとわかると思うけどすごく大変である。もしかしたらそれをノーコストでできると思っている人がいて「アジャイルは画期的だ!すごい手法だ!」と言われて広まってしまった*3のがプロセス技術が下火になった原因なのかもしれないとは思う。

僕はアジャイルウォーターフォールをあたかも対立する概念のように扱うのは好きじゃなくて、それはこんな風に、アジャイルというか柔軟なプロセスと高度に自己組織化されたチームが決めなければいけないことから目をそらしがちになるからである*4。平たくいうとどっちが言っていることも絶対大事で、これらをどう組み合わせていくかという話でしかないということだ。

良いチームと良いプロセス

僕は良いチームと良いプロセスはかなり深い関係にあると思っているけど、これは分けて考えたほうがいいのかもしれないと最近は思っていたりもする。

僕は今回プロセス技術というのがかつて流行ったことを始めて知ってとても得るものがあったと思ってるけど、それ以前にも例えばプロジェクトマネジメント理論とかモデリングとかアーキテクチャ設計とかには興味があってわりと勉強をしていた。アカデミックな世界でこういう風に体系化可能なものは体系化されていたほうがありがたいし、それは積極的に活用するべきだと思う。

なかには開発現場までダイレクトに適用可能なほど体系化できていないものもあるはずで、それらは最近だとパターンランゲージを用いて記述されることが多いのかなという印象がある。デザインパターンとか組織パターンはもちろん、例えばリファレンスモデルなんかもひとつのパターンと言っていいと思っていて、こういうのはツールとして出来上がっているものや標準仕様として広まっているものよりは各現場での工夫が必要になるけど、フルスクラッチで設計していくよりははるかに楽であり先人の知恵を利用させてもらうことができる。

そして、それでも解決できない問題が残るのであればそれこそがそのプロジェクトが立ち向かう本質的な問題な気がするし、属人的で再現不可能であっても手探りで解決していかないといけないもので、それこそが良いチームなのかなと思う。

うーん

結局何が言いたかったんだっけ…

*1:一応、Amazon で購入はしました。

*2:元記事で紹介されている書籍の目次を見た感じだとわりと両方ともそうっぽい?

*3:もうさすがに一巡したと思うけど…

*4:もちろん柔軟なプロセスと自己組織化されたチームはすばらしい成果であり、それ自体を否定するつもりはない。ただアーキテクチャ的に無駄が生じる可能性はある。

そろそろ「テスト」という言葉を使うのをやめたほうがいいのかもしれない

週末になごやのこわい人*1が東京に来てたのでいろいろ話したんだけど、そのときにちょろっと出た話について忘れないうちにまとめておく。

タイトルの件だけど、結局僕らはテストをやりたいというよりはいいプロダクトやいいサービスを作りたいのであって「テスト」という言葉を使っちゃうといろいろ誤解されることもあるなーと思った。

ソフトウェアの世界で「テスト」と言うといわゆる単体テストとか結合テストとかシステムテストとかのことを暗黙的に示してしまうわけで、それは仕様通りにソフトウェアが実装されているかどうかを確かめる行為であると認識されることが多い。実際にはさらにその先にそのソフトウェアがどの程度の価値を生み出したかという重要な指標があるんだけど、それは「マーケティング」と呼ばれたり最近だと「UXデザイン」と呼ばれたりしてソフトウェアテストとは別のものとして扱われたりする。

でも、機能上のバグだろうと、性能上のボトルネックだろうと、UI の酷さだろうと、それが結果的にユーザ体験を損ねているんだったらそれはソフトウェアとして十分な価値をデリバリーできてないわけであって、僕たちはそれらをテストしたいんだ。

ちょうど先日以下のような記事があった。

「ユーザーをちゃんと丁寧に扱うこと。これはソフトウェアの1つの機能ですよ。多くのソフトウェアは、この機能を実装していない。なんか特定の機能がないとか、ある機能が期待したように動かないとか、そういう話じゃないです。ぼくはユーザーを見放したりしない。人間というのは、ちゃんと自分に向き合ってくれる人の元を去らないもの。ソフトウェアも同じで、機能、機能、機能、技術、技術、技術……、そんな話じゃない。ソフトウェアも人の話なんです。使いやすさとか、きちんとユーザーに向かうことの大切さが過小評価されてると思います」

この記事では Amazon がロジスティックスを最適化しているという事例や Basecamp のユーザサポートの事例があげられているが、この事例のようにユーザ体験に大きな影響を与える要因がソフトウェアそのものではなくそれより外の世界であることは決して少なくない。

こういった現実世界の副作用をソフトウェアテスティングの知見を活かして測定することも可能なはずだし、副作用のない世界ででしか価値を発揮しないソフトウェアにはあまり意味がない*2

例えば自分たちが作っているプロダクトの KPI が一体何なのかというのを常に考えて、それが達成されてるか未達なのかを監視し続ける仕組みとか、未達だった場合にその原因と考えられる要素を分析して通知する仕組みとか、それをプロダクトの設計や実装にフィードバックするチームやプロセスの設計とか、きっと僕たちがやりたいことはそういうことなんだよ。

おまけ

ただ、ちょっと難しいなと思うのは(これは個人的な嗜好性なんだけど)僕はそれが再現可能なプロセスじゃないとあまり満足感を得られない人で、例えば自分が超がんばって成果を出したとか極めて特殊なチームの強みがあったからうまくいったという感じでなく、同じようなスキルを持った人たちが同じようなことに取り組めば同じことができるということのほうが興味がある。そうなるとパターンランゲージっぽい方向になると思っていたりする。

*1:https://twitter.com/kyon_mm

*2:もちろんそれすらちゃんとできてない場合もあるのでこれ自体は重要なことではある。