My Favorite Life

Go there and write simply with golang. Such a person I want to be.

【本メモ】『スーパーエンジニアへの道〜技術リーダーシップの人間学〜』

『スーパーエンジニアへの道〜技術リーダーシップの人間学〜』を読んだので、本メモを公開。

スーパーエンジニアへの道―技術リーダーシップの人間学


  • まず「変化」そのものについて理解をしよう
  • 自分を通して変化を体験しよう
  • そして自分自身に対しても理解を深めよう
  • セルフイメージによって、自分の反応は変わる
  • イデアが醸成される場をサポートしよう
  • 人間としていつも誠実に向き合おう
  • リーダーシップを各人が問題解決できる環境づくりに用いよう
  • 自分の強みを使って実践を通して取り組みながら学ぼう
  • 「自分で自分の教育に責任を持つ」という考えの元、ブレストから計画作りを始めよう

リーダーシップのMOIモデル

変化が起こるためには、環境に次の三つの成分が含まれていなければならない。 自分をより有能な問題解決型リーダーに変容させることに成功するために、三つのことが必要。

M-動機づけ(Motivation)

トロフィーであるかトラブルであるか、またひと押しであるかひと引きであるかは問わず、 関係する人を突き動かす何ものか

O-組織化(Organization)

アイディアを実際に実現することを可能にする、既存の構造

I-アイディア(Idea)ないし技術革新(Inovation)

タネ、すなわち実現されるもののイメージ

リーダーシップとは、人々が力を付与されるような環境を作り出すプロセスである。

問題解決型リーダーたちはつねに使えるアイディアはないか、
とほかの文脈を探し歩いているもの。
自分または他人によってすでにうまくやられたことを、もう一度やりなおすことには、興味を示さない。

どんなアイディアも、出てきたばかりときから完璧だということはない。
コピーしてきたアイディアでさえ、新しい環境に合うように調整しなければならない。

自分が単に我を張っているだけである場合には引っ込め、
グループの自分以外のメンバーが致命的な誤りに向かってつんのめっているにときには頑張る必要がある。

すべてのアイディアが有用だとは限らない
すべての人は有用である
言葉の選択には注意を払い、アイディアのみを批判し、決して人を批判しない。

真の問題解決型リーダーとして認知されるためには、
少なくとも何ほどかの動機づけ、および組織化の能力が必要である。
逆に、動機づけまたは組織化によって指導する力は、
技術革新によるリーダーシップの能力が少量でもあれば、ずっと増す。
これこそ、自分がそういうタイプだと思うか思わないかにかかわらず、
問題解決型リーダーになるための道を調べることによって、
万人が学びとることのできる教訓である。

変化はわれわれが朝食に何を選ぶか、
というところからはじまるものだ。
この、問題解決型リーダーシップという、より静かな様式を、
人生とか自由とか幸福の追求とかいった日常的な問題に適用してみれば、
それが力の源になることに気づくかもしれない。

技術革新への障害

自己に対する盲目 -  障害第一番

人がわれわれを見るように自分を見る、ということの不可能性こそ、
自己改善への最大の障害である。
このたった一つの障害に、問題解決型リーダー志願者の大多数が引っ掛かる。

自分自身への気づきを高める法

自己盲目性という、他の障害を克服する上でじゃまになる障害を克服する助けをしてくれる。

動機づけに関しては、読者が本当に変わりたいと思ってないなら、無力。

三箇月間、個人的な日誌をつけるのに毎日五分間使うこと。

記録をとる、という行為に対して忠実であるためには、
あらゆる補助手段と刺激が必要。

個人的日誌
一日のうちいつそれを書くかは重要ではない。
それどころか、毎日決まった時間に書くことすら重要でない。
重要なのは、毎日確実に五分間は書くように保証するための、
何らかの方法を見つけ出すことである。

本能がそれを要求したときに書くことは重要だが、
本能が要求しないときにも書く、ということはいっそう重要なのだ。

もし自己観察のための時間を一定のパターンにしたがって確保できないようなら、
読者のリーダーシップ養成計画は重大なトラブルを抱えている、ということになる。

何について書くか
日誌をつけることによって、仮にほかには何の情報も得られなかったとしても、
自分の行動を変えようと思ったとき、
自分がどう反応するかを知ることはできるのだ、ということを示している。

ほかの人々に何か簡単な変化を要求したとき、彼らがどう感じるか理解できるようになる方向に、
第一歩を踏み出すことができる。

『自分について書きなさい』

- 何が起こったか
- 自分がそれにどう反応したか
- 何か学んだことがあれば、それについて

たいていの場合、何も学びません。
学ぶのはずっと後になって、その項目を読みなおしたときです。

日誌をつけるのは、自分自身について学ぶため。

日誌を、技術リーダーになるための第一歩としてお勧めしたのは、
それがごく小さな約束ごとであって、それをしないための筋のとおったいいわけがほとんど見当たらない、
という理由によってであった。

三大アイディア生産法と技術革新に対する三大障害の間の関係
・自分自身に対する気づきが欠けていると、人は自分の誤りに気づかず、したがってそれをとらえてすばらしいものに変換する、ということができない。
・自分は最高の知性を持っている、と信じ込んでいる人は、他人の仕事を引き写そうという気を起こすことがないから、創造的な盗みの恩恵にあずかることができない。
・またすべての問題には一つただ一つの正解があると「知って」いる人は、アイディアを組み合わせることなんかばかばかしいと考えるので、結合を利用することができない。
アイディア生成の三大戦略
- 誤り
- 盗み
- 結合

人に動機づけを与えることについての大障害

なぜコミュニケーションはこうもねじ曲がるのか
自己評価
私自身について私が持つ感じ方は、私が応答するしかたに強力な影響を及ぼす。

コミュニケーションの道をつける法
「彼らに自分が何を知覚しているか、知覚しているものに対してどう感じているか、
そしてもし可能なら、その感じについて自分がどう感じているかを告げなさい」

「私には弱味があります。ただし私は、自分の弱味をさらけ出せるに十分なだけ、
自分とみなさんについて自信を持っています」
自分の弱味を示すことによって、自分自身について知る必要のある情報をもたらすかもしれないチャンネルを、
開くことになる。

問題解決型リーダーとして成功するためには、
人々が人間であることをつねに前面に出しておかなければならない。

もしあなたがリーダーなら、人々こそあなたの仕事の対象である。
それ以外にする値打ちのある仕事はない。

## 人を助けることの難しさ
もし人々がこちらの助力を欲していないのなら、
いくらこちらが頭のいい、すばらしい人間だったとしても、
われわれは決して彼らを助けることには成功しない

彼らがこちらの助力を望んでいるかどうか、いつも確認しよう。
確認のためのもっとも簡単な方法は、
助力を望んでいるかどうか聞いてみることである。

気遣っている、ということを納得させる必要がある。
ただ一つの確実な方法は、本当に気遣うことである。
自分をだましてはいけない。
もしリードさる人々について真に気遣うということをしないなら、
リーダーとして成功することはありえない。

他人を愛する能力、そしてひいては他人を助け、他人をリードする能力は、
自分を愛する能力から出発する。

他人を助けようという試みは、つねに成功するとは限らない。
助力者として困難にぶつかった場合、どう反応するかは、
自分自身に対する感じ方によって決まる。

もし自分を軽視していたとしたら、
そのことは人々に動機づけを与えようとする試みの一切に対して、
じゃまを入れることになろう。
人を助けようと乗り出す前に、まず自分について検討してみた方がよい。

組織化

力の使いかた
リーダーに必要な資質はほかにもある。
利己的でないことがそうだ。
リーダーの役割:全員が力を付与されるような環境を作り出す
そういう環境を作ることに使うのでなかったら、
彼らは自分たちの力を高尚な目標に、きちんと向けていることにはならない。

大切なのは、最良の方法を知ることではなく、
現在の状況下において最良の方法を知ること。
状況が変われば、組織も変わらなければならない。
もっとも有能なリーダーとは、
状況が変化したときにチームがそのことに気づき、適切な新組織を見つけ出すための手助けをする人にほかならない。

有効な組織作りへの障害-人を機械扱いにする

自分の意志決定と命令を、ますます厳格かつ厳密にしようとし、
人を機械であるかのように扱うというのは、有効な組織作りにとってもう一つの大障害である。
それをやりすぎると組織を基礎づけるための標準と手順の山がどんどんふくれ上がる、ということになる。
そういったものは、精密になればなるほど有効性を失う。
誰も読もうとしなくなる。
ましてや従おうなどと思わなくなる。
手順書やメモをを書くことによって組織しようと忙しくしているリーダーは、
じきそれらに従うはずの人々との接触を失うことになる。

有効な組織作りへの障害-自分でやってしまう

通常リーダーの仕事は、単一の問題を解くことではなく、
多くの問題が、しかも現在のみならず将来にまでまたがって解かれてゆく環境を作り出すこと。
もちろん目前の問題が解けなければ、将来はない、という場合もある。
その場合は介入して解いてしまうことも必要かもしれない。

その問題は、本当に生死に関わるのか。
これはリーダーによって、もっとも困難な判断になる可能性がある。

組織作りの主題は、問題を解くことではなく問題を回避すること。
一度問題と取っ組み合いをはじめてしまったら、
本当に有効な組織作りをするにはもう遅すぎる。
恐らく有効な組織作りのための最大の障害は、
われわれが有効でない組織作りに報償を与えたがる、その熱心さにある。

リーダーの基本姿勢は、
個々人が問題を解き、決定をくだし、それらの決定を実施に移すのではなく、
むしろ全員が問題を解き、決定をくだし、それらの決定を実施に移すことができるような環境を作り出すことに向けられる。
このモデルでは、組織作りとは厳格な規則を作り上げることではない。
組織作りとは命令することでも命令を受けることでもない。
仕事を片付けることである。

組織作りの学び方

人々の生活に影響を与える場面で間違いを犯すことを恐れ、
まず理論をマスターしたいと思うのだろう。
理論は重要だが、それで間違いが全部予防できるわけではない。
人々をどう組織化するかについては、
互いに矛盾した理論がたくさんあり、それらは実体験を道案内としない限り理解することすらできない。
組織に影響を与えるような仕事に手を出せるだけの実体験なしに、
どうして実体験を得ることができるものだろうか。

要するに、どんな活動でもいいから、さまざまな組織形態の中で、
さまざまな役割を担ってみて、それがどんな感じがするものなのか経験するのである。

「彼らはみな、この状況の中で彼らにできる最良のことをしている。
もし私が、彼らはなし得るベストを尽くしてないと感じるのだとすれば、
それは私が状況を理解してないせいだ。」
「状況」とは、組織とすべき仕事の間の不整合であることがふつう。
問題解決型リーダーシップの三つの主要機能のどれかについておかしいことが起こっている、
と仮定してものごとをよく見る、というようにしている。
・問題を定義する
・アイディアの流れを助長する
・品質を管理する
目前の問題にふさわしくない種類の組織の中では機能障害を起こす可能性がある。

リーダーがものごとに対処するやりかたには、大きくわけて二種類ある。
それは動機づけに重点を置くか、組織化に重点を置くかの違いである。
状況を誰かほかの人のスタイルで処理しようとする、という誤りを犯さないために、
自分の強みがどこにあるかを知っておくのはよいこと。
「自分の場合にもっともうまく行きそうで、しかも自分がそれでいやな感じにならないようなことをおやりなさい」

変容

変わるための計画を立てる

個人的業績に向けて計画を立てる
第一段階
個人的業績についての目標を立てる。
ただしそれは何か安全で、新しくて、自分一人でできるようなものとする。
その業績は、どの程度の成績が得られたかがその場でわかる、という意味で即時性をもっていなければならない。
第二段階
第一日には成績の最低水準がどれだけであるかをはっきりさせる。
次に少なくとも毎日一回、練習を進めるにつれてどれだけの進歩が見られたかを自分の日誌に記録する。
第三段階
最終日には、どれだけできるようになったかを人に示し、
その業績を求めて努力するうちに何が起こったかを人と議論するようにする。

業績に向けて計画を立てるのは、ものごとをどうやって達成したらいいか学ぶための方法になっている。
固有の変化のスタイルがどのようなものであるかを知るためには、
その手はじめとして自分なりの業績計画を立ててみるとよい。

学ぶであろう最初のことは、何かを学ぼうとしたとき提言に抵抗するしかたは、
どういうスタイルを持っているかである。

変化というものの性質を理解している人なら、
それと同様の理由によって、
ありふれた小さな変化が積み重なってゆけば、
あるとき突然何か大きくて異常なものの瀬戸際に立たされることになる、ということを予測できる。
自分自身と自分の変化に対する反応を理解している人なら、
その瀬戸際まで行って思い切ったことをする勇気が持てる。

何千という学習の機会に取り囲まれている。
ただし計画を持って対応しないと、その大部分をのがすことになる。
計画作りは、ブレインストーミングによってなにほどかの項目を追加する、
というところからはじめるといい。

ブレインストーミングでどんなリストを作るにせよ、
またほかの人からどんなアドバイスを受けるにせよ、
作る変化のための個人的計画は、本質的には自分自身を理解する、というのが目的。
それはほかの誰にもできないこと。
計画の第一段階は「自分で自分の教育に責任を持つ」というものであるべき。

黄金律は、人にしてほしいと思うことを人にもせよ、と教えている。
「何でもあなたが本当にしたいと思っていることをなさい」というのは、
私がいってもらいたいと思うことである。
このアドバイスは、最良の支援者からのアドバイスである。
そういう人を私は、ずばり、「親友」と呼ぶ。

なぜ私はこれを書いたのだろう。
私は自分が、私のリーダーであった人々に対する感謝の気持ちからこれを書いたのだと思う。
彼らが教えてくれた幸福を私が読者に伝え、
読者がこの幸福をほかの人々に伝えて下さるなら、それが彼らが施してくれた恩恵にもっともよく報いる道なのだと思う。
それ以外に、どんな理由があろうか。

【本メモ】『スーパーエンジニアへの道〜技術リーダーシップの人間学〜』

『スーパーエンジニアへの道〜技術リーダーシップの人間学〜』を読んだので、本メモを公開。

スーパーエンジニアへの道―技術リーダーシップの人間学


  • まず「変化」そのものについて理解をしよう
  • 自分を通して変化を体験しよう
  • そして自分自身に対しても理解を深めよう
  • セルフイメージによって、自分の反応は変わる
  • イデアが醸成される場をサポートしよう
  • 人間としていつも誠実に向き合おう
  • リーダーシップを各人が問題解決できる環境づくりに用いよう
  • 自分の強みを使って実践を通して取り組みながら学ぼう
  • 「自分で自分の教育に責任を持つ」という考えの元、ブレストから計画作りを始めよう

リーダーシップのMOIモデル

変化が起こるためには、環境に次の三つの成分が含まれていなければならない。 自分をより有能な問題解決型リーダーに変容させることに成功するために、三つのことが必要。

M-動機づけ(Motivation)

トロフィーであるかトラブルであるか、またひと押しであるかひと引きであるかは問わず、 関係する人を突き動かす何ものか

O-組織化(Organization)

アイディアを実際に実現することを可能にする、既存の構造

I-アイディア(Idea)ないし技術革新(Inovation)

タネ、すなわち実現されるもののイメージ

リーダーシップとは、人々が力を付与されるような環境を作り出すプロセスである。

問題解決型リーダーたちはつねに使えるアイディアはないか、
とほかの文脈を探し歩いているもの。
自分または他人によってすでにうまくやられたことを、もう一度やりなおすことには、興味を示さない。

どんなアイディアも、出てきたばかりときから完璧だということはない。
コピーしてきたアイディアでさえ、新しい環境に合うように調整しなければならない。

自分が単に我を張っているだけである場合には引っ込め、
グループの自分以外のメンバーが致命的な誤りに向かってつんのめっているにときには頑張る必要がある。

すべてのアイディアが有用だとは限らない
すべての人は有用である
言葉の選択には注意を払い、アイディアのみを批判し、決して人を批判しない。

真の問題解決型リーダーとして認知されるためには、
少なくとも何ほどかの動機づけ、および組織化の能力が必要である。
逆に、動機づけまたは組織化によって指導する力は、
技術革新によるリーダーシップの能力が少量でもあれば、ずっと増す。
これこそ、自分がそういうタイプだと思うか思わないかにかかわらず、
問題解決型リーダーになるための道を調べることによって、
万人が学びとることのできる教訓である。

変化はわれわれが朝食に何を選ぶか、
というところからはじまるものだ。
この、問題解決型リーダーシップという、より静かな様式を、
人生とか自由とか幸福の追求とかいった日常的な問題に適用してみれば、
それが力の源になることに気づくかもしれない。

技術革新への障害

自己に対する盲目 -  障害第一番

人がわれわれを見るように自分を見る、ということの不可能性こそ、
自己改善への最大の障害である。
このたった一つの障害に、問題解決型リーダー志願者の大多数が引っ掛かる。

自分自身への気づきを高める法

自己盲目性という、他の障害を克服する上でじゃまになる障害を克服する助けをしてくれる。

動機づけに関しては、読者が本当に変わりたいと思ってないなら、無力。

三箇月間、個人的な日誌をつけるのに毎日五分間使うこと。

記録をとる、という行為に対して忠実であるためには、
あらゆる補助手段と刺激が必要。

個人的日誌
一日のうちいつそれを書くかは重要ではない。
それどころか、毎日決まった時間に書くことすら重要でない。
重要なのは、毎日確実に五分間は書くように保証するための、
何らかの方法を見つけ出すことである。

本能がそれを要求したときに書くことは重要だが、
本能が要求しないときにも書く、ということはいっそう重要なのだ。

もし自己観察のための時間を一定のパターンにしたがって確保できないようなら、
読者のリーダーシップ養成計画は重大なトラブルを抱えている、ということになる。

何について書くか
日誌をつけることによって、仮にほかには何の情報も得られなかったとしても、
自分の行動を変えようと思ったとき、
自分がどう反応するかを知ることはできるのだ、ということを示している。

ほかの人々に何か簡単な変化を要求したとき、彼らがどう感じるか理解できるようになる方向に、
第一歩を踏み出すことができる。

『自分について書きなさい』

- 何が起こったか
- 自分がそれにどう反応したか
- 何か学んだことがあれば、それについて

たいていの場合、何も学びません。
学ぶのはずっと後になって、その項目を読みなおしたときです。

日誌をつけるのは、自分自身について学ぶため。

日誌を、技術リーダーになるための第一歩としてお勧めしたのは、
それがごく小さな約束ごとであって、それをしないための筋のとおったいいわけがほとんど見当たらない、
という理由によってであった。

三大アイディア生産法と技術革新に対する三大障害の間の関係
・自分自身に対する気づきが欠けていると、人は自分の誤りに気づかず、したがってそれをとらえてすばらしいものに変換する、ということができない。
・自分は最高の知性を持っている、と信じ込んでいる人は、他人の仕事を引き写そうという気を起こすことがないから、創造的な盗みの恩恵にあずかることができない。
・またすべての問題には一つただ一つの正解があると「知って」いる人は、アイディアを組み合わせることなんかばかばかしいと考えるので、結合を利用することができない。
アイディア生成の三大戦略
- 誤り
- 盗み
- 結合

人に動機づけを与えることについての大障害

なぜコミュニケーションはこうもねじ曲がるのか
自己評価
私自身について私が持つ感じ方は、私が応答するしかたに強力な影響を及ぼす。

コミュニケーションの道をつける法
「彼らに自分が何を知覚しているか、知覚しているものに対してどう感じているか、
そしてもし可能なら、その感じについて自分がどう感じているかを告げなさい」

「私には弱味があります。ただし私は、自分の弱味をさらけ出せるに十分なだけ、
自分とみなさんについて自信を持っています」
自分の弱味を示すことによって、自分自身について知る必要のある情報をもたらすかもしれないチャンネルを、
開くことになる。

問題解決型リーダーとして成功するためには、
人々が人間であることをつねに前面に出しておかなければならない。

もしあなたがリーダーなら、人々こそあなたの仕事の対象である。
それ以外にする値打ちのある仕事はない。

## 人を助けることの難しさ
もし人々がこちらの助力を欲していないのなら、
いくらこちらが頭のいい、すばらしい人間だったとしても、
われわれは決して彼らを助けることには成功しない

彼らがこちらの助力を望んでいるかどうか、いつも確認しよう。
確認のためのもっとも簡単な方法は、
助力を望んでいるかどうか聞いてみることである。

気遣っている、ということを納得させる必要がある。
ただ一つの確実な方法は、本当に気遣うことである。
自分をだましてはいけない。
もしリードさる人々について真に気遣うということをしないなら、
リーダーとして成功することはありえない。

他人を愛する能力、そしてひいては他人を助け、他人をリードする能力は、
自分を愛する能力から出発する。

他人を助けようという試みは、つねに成功するとは限らない。
助力者として困難にぶつかった場合、どう反応するかは、
自分自身に対する感じ方によって決まる。

もし自分を軽視していたとしたら、
そのことは人々に動機づけを与えようとする試みの一切に対して、
じゃまを入れることになろう。
人を助けようと乗り出す前に、まず自分について検討してみた方がよい。

組織化

力の使いかた
リーダーに必要な資質はほかにもある。
利己的でないことがそうだ。
リーダーの役割:全員が力を付与されるような環境を作り出す
そういう環境を作ることに使うのでなかったら、
彼らは自分たちの力を高尚な目標に、きちんと向けていることにはならない。

大切なのは、最良の方法を知ることではなく、
現在の状況下において最良の方法を知ること。
状況が変われば、組織も変わらなければならない。
もっとも有能なリーダーとは、
状況が変化したときにチームがそのことに気づき、適切な新組織を見つけ出すための手助けをする人にほかならない。

有効な組織作りへの障害-人を機械扱いにする

自分の意志決定と命令を、ますます厳格かつ厳密にしようとし、
人を機械であるかのように扱うというのは、有効な組織作りにとってもう一つの大障害である。
それをやりすぎると組織を基礎づけるための標準と手順の山がどんどんふくれ上がる、ということになる。
そういったものは、精密になればなるほど有効性を失う。
誰も読もうとしなくなる。
ましてや従おうなどと思わなくなる。
手順書やメモをを書くことによって組織しようと忙しくしているリーダーは、
じきそれらに従うはずの人々との接触を失うことになる。

有効な組織作りへの障害-自分でやってしまう

通常リーダーの仕事は、単一の問題を解くことではなく、
多くの問題が、しかも現在のみならず将来にまでまたがって解かれてゆく環境を作り出すこと。
もちろん目前の問題が解けなければ、将来はない、という場合もある。
その場合は介入して解いてしまうことも必要かもしれない。

その問題は、本当に生死に関わるのか。
これはリーダーによって、もっとも困難な判断になる可能性がある。

組織作りの主題は、問題を解くことではなく問題を回避すること。
一度問題と取っ組み合いをはじめてしまったら、
本当に有効な組織作りをするにはもう遅すぎる。
恐らく有効な組織作りのための最大の障害は、
われわれが有効でない組織作りに報償を与えたがる、その熱心さにある。

リーダーの基本姿勢は、
個々人が問題を解き、決定をくだし、それらの決定を実施に移すのではなく、
むしろ全員が問題を解き、決定をくだし、それらの決定を実施に移すことができるような環境を作り出すことに向けられる。
このモデルでは、組織作りとは厳格な規則を作り上げることではない。
組織作りとは命令することでも命令を受けることでもない。
仕事を片付けることである。

組織作りの学び方

人々の生活に影響を与える場面で間違いを犯すことを恐れ、
まず理論をマスターしたいと思うのだろう。
理論は重要だが、それで間違いが全部予防できるわけではない。
人々をどう組織化するかについては、
互いに矛盾した理論がたくさんあり、それらは実体験を道案内としない限り理解することすらできない。
組織に影響を与えるような仕事に手を出せるだけの実体験なしに、
どうして実体験を得ることができるものだろうか。

要するに、どんな活動でもいいから、さまざまな組織形態の中で、
さまざまな役割を担ってみて、それがどんな感じがするものなのか経験するのである。

「彼らはみな、この状況の中で彼らにできる最良のことをしている。
もし私が、彼らはなし得るベストを尽くしてないと感じるのだとすれば、
それは私が状況を理解してないせいだ。」
「状況」とは、組織とすべき仕事の間の不整合であることがふつう。
問題解決型リーダーシップの三つの主要機能のどれかについておかしいことが起こっている、
と仮定してものごとをよく見る、というようにしている。
・問題を定義する
・アイディアの流れを助長する
・品質を管理する
目前の問題にふさわしくない種類の組織の中では機能障害を起こす可能性がある。

リーダーがものごとに対処するやりかたには、大きくわけて二種類ある。
それは動機づけに重点を置くか、組織化に重点を置くかの違いである。
状況を誰かほかの人のスタイルで処理しようとする、という誤りを犯さないために、
自分の強みがどこにあるかを知っておくのはよいこと。
「自分の場合にもっともうまく行きそうで、しかも自分がそれでいやな感じにならないようなことをおやりなさい」

変容

変わるための計画を立てる

個人的業績に向けて計画を立てる
第一段階
個人的業績についての目標を立てる。
ただしそれは何か安全で、新しくて、自分一人でできるようなものとする。
その業績は、どの程度の成績が得られたかがその場でわかる、という意味で即時性をもっていなければならない。
第二段階
第一日には成績の最低水準がどれだけであるかをはっきりさせる。
次に少なくとも毎日一回、練習を進めるにつれてどれだけの進歩が見られたかを自分の日誌に記録する。
第三段階
最終日には、どれだけできるようになったかを人に示し、
その業績を求めて努力するうちに何が起こったかを人と議論するようにする。

業績に向けて計画を立てるのは、ものごとをどうやって達成したらいいか学ぶための方法になっている。
固有の変化のスタイルがどのようなものであるかを知るためには、
その手はじめとして自分なりの業績計画を立ててみるとよい。

学ぶであろう最初のことは、何かを学ぼうとしたとき提言に抵抗するしかたは、
どういうスタイルを持っているかである。

変化というものの性質を理解している人なら、
それと同様の理由によって、
ありふれた小さな変化が積み重なってゆけば、
あるとき突然何か大きくて異常なものの瀬戸際に立たされることになる、ということを予測できる。
自分自身と自分の変化に対する反応を理解している人なら、
その瀬戸際まで行って思い切ったことをする勇気が持てる。

何千という学習の機会に取り囲まれている。
ただし計画を持って対応しないと、その大部分をのがすことになる。
計画作りは、ブレインストーミングによってなにほどかの項目を追加する、
というところからはじめるといい。

ブレインストーミングでどんなリストを作るにせよ、
またほかの人からどんなアドバイスを受けるにせよ、
作る変化のための個人的計画は、本質的には自分自身を理解する、というのが目的。
それはほかの誰にもできないこと。
計画の第一段階は「自分で自分の教育に責任を持つ」というものであるべき。

黄金律は、人にしてほしいと思うことを人にもせよ、と教えている。
「何でもあなたが本当にしたいと思っていることをなさい」というのは、
私がいってもらいたいと思うことである。
このアドバイスは、最良の支援者からのアドバイスである。
そういう人を私は、ずばり、「親友」と呼ぶ。

なぜ私はこれを書いたのだろう。
私は自分が、私のリーダーであった人々に対する感謝の気持ちからこれを書いたのだと思う。
彼らが教えてくれた幸福を私が読者に伝え、
読者がこの幸福をほかの人々に伝えて下さるなら、それが彼らが施してくれた恩恵にもっともよく報いる道なのだと思う。
それ以外に、どんな理由があろうか。

【本メモ】『進化的アーキテクチャ』

『進化的アーキテクチャ』を読んだので、本メモを公開。

進化的アーキテクチャ

業界やコミュニティは絶え間ない変化を期待
変化がいつ起こるのか、変化が持続するのかを予測できない。
しかし、変化も避けられない
→技術的な景観が変わるであろうことをふまえてシステムを設計しなくてはならない

重要なアーキテクチャ特性を定義した後、どうすればそれらの特性が腐敗しないように保護できるか。
アーキテクチャ特性の進化可能性は、システムが進化していく中で他の特性を保護するということを意味する
進化可能性とは、他のすべてのアーキテクチャ特性を保護するアーキテクチャのラッパー

進化的アーキテクチャとは、複数の次元にわたる漸進的で誘導的な変更を支援するもの

もし進化可能なアーキテクチャを作りたいのなら、変更が影響を与える全ての部分を考慮しなくてはならない

現代のソフトウェアアーキテクチャにおいて進化可能性に影響を及ぼすいくつかのよくある次元

・技術
アーキテクチャの実装部分。フレームワーク、依存するライブラリ、実装言語など。
・データ
データベーススキーマ、テーブルレイアウト、最適化計画など。
この種のアーキテクチャは通常はデータベース管理者が扱う。
・セキュリティ
セキュリティポリシーの定義、ガイドライン、不具合を発見するツールの指定など。
・運用系
アーキテクチャを既存の物理インフラまたは仮想インフラ(サーバー、クラスタ構成、スイッチ、クラウドリソースなど)に
どのようにマッピングするかといった関心事。

次元とは、ある特定の観点を支持する部分を意図的に分割したもの

「システムを設計するあらゆる組織は、必ずその組織のコミュニケーション構造に倣った構造を持つ設計を生み出す」
Melvin Conway

Conway は論文において、ソフトウェアアーキテクトはアーキテクチャやソフトウェア設計だけでなく、
チーム間の作業の移譲、割り当て、調整にも注意を払う必要があると警告。

「逆コンウェイの法則」
マイクロサービスなどのアーキテクチャを構築する多くの企業は、サイロ化した技術アーキテクチャによる分割ではなく、サービス境界を中心にチームを組織する。
チームの編成をこうしたやり方で行うのは理想的
なぜなら、チーム構造はソフトウェア開発の無数の次元に影響を与えるもので、問題の規模や範囲を反映すべき。
例えば、マイクロサービスアーキテクチャを構築する場合には、
企業は一般的に、機能的なサイロを横断し、アーキテクチャのビジネス的側面と技術的側面全ての方向を満たすメンバーをチームに含めることで、チームをアーキテクチャに似せて組織する。
「対象のアーキテクチャに似せてチームを組織すること。そうすれば、アーキテクチャの実現はより容易になる。」

進化的アーキテクチャ、2つの重要な特徴

  • 漸進的
  • 誘導的
順応という言葉よりも進化という言葉を好むのは、継ぎはぎして理解しがたい偶発的な複雑さに適用していくアーキテクチャではなく、
基本的な進化的変化を経るアーキテクチャに興味があるから

真に進化するアーキテクチャを構築するためには、
アーキテクトは応急処置的な解決策ではなく、本物の変化をサポートしなくてはならない。
生物学のメタファーに戻ると、進化とは、目的に沿った、絶え間なく変化する環境で生き残ることができるシステムを持つこと。

進化的アーキテクチャ3つの基本的な側面

  • 漸進的な変更
  • 適応度関数
  • 適切な結合
あるアーキテクチャ特性がどの程度満たされているかを評価する客観的な指標

スケーラビリティ、パフォーマンス、セキュリティ、データスキーマなどの重要な次元を定義することは、
いかなるシステムにおいても、初期のアーキテクチャにおける重要な決定事項

従来のテストや監視をはじめとする各種ツールを含む適応度関数を構築するために、既存の多くの仕組みを活用
テストがアーキテクチャ上の関心事の完全性を証明するのに役立つ場合には、それを適応度関数とみなす。

アーキテクトは、アーキテクチャの重要な部分全てを最初から知ることは決してできない。
→システムが進化する中で適応度関数を明らかにしていく必要がある。

適応度関数を特定しなければ、チームは以下に示すリスクに直面する
・間違った設計を選択し、最終的には環境に適合しないソフトウェアを構築してしまう
・不必要な設計を、時間やお金をかけて選択してしまう
・将来環境が変化したときに、システムをたやすく変化させることができなくなってしまう

適応度関数を早い段階で特定しなければ、チームは最終的にこれらの責務をコードベース全体へ分散
→変更を理解するには幅広い影響分析が必要となり、全体的な変更コストを跳ね上げる

適応度関数3つのカテゴリ

・主要なもの
技術や設計を選択する上で重要
これらの要素を中心とした変更を容易に行えるようにする設計上の選択を探ることにより多くの労力を割かなくてはならない。
例:銀行アプリケーション
パフォーマンスと回復力

・関連性のあるもの
機能レベルで考慮する必要だが、アーキテクチャ上の選択を誘導することはない。
例:コードベースの品質に関するコードメトリクス
重要だが、主要な次元ではない

・関連性のないもの
設計と技術の選択は、この種の次元に影響を受けない。
例:サイクルタイムなどのプロセスメトリクス
重要なものではあるかもしれないが、アーキテクチャとは無関係。
そのため、適応度関数は必要ない。

「適応度関数と実行した結果を共有スペースなどで可視化することで、主要な適応度関数と関連性のある適応度関数の知識を保ち続けよう。
そうすることで、開発者は忘れずに日々の開発作業の中でそれらを考慮することができるようになる。」

適応度関数の定義とメンテナンスは、
アーキテクトと開発者、アーキテクチャの整合性を維持することにかかわる全ての役割による共同責任となる。

コンポーネント粒度

量子とは相互作用に関与する物理的実体の最小量。
アーキテクチャ量子とは、高度な機能的凝集を持つ、独立してデプロイ可能なコンポーネント。
アーキテクチャ量子は、システムが適切に機能するために必要な構造的要素全てを含む。
モノリシックアーキテクチャでは、量子はアプリケーション全体。
モノリシックアーキテクチャは全てが高度に結びつく。
→全てまとめてデプロイする必要がある
対照的に、マイクロサービスアーキテクチャは、
変更可能性のある部分を全てカプセル化したアーキテクチャ要素間の、物理的な境界づけられたコンテキストを定義する。
→漸進的な変更を許容するように設計されている。
マイクロサービスアーキテクチャでは、境界づけられたコンテキストは量子的な境界として機能する。

DDDは、複雑な問題領域の組織的分解を可能にするモデリング手法。
境界づけられたコンテキスト
→内部へはドメインに関する全てのことを公開し、外部へはそれを明かさないように境界が引かれた領域
DDD以前
→開発者は組織内の共通エンティティを全体にわたって再利用可能にしようと尽力していた。
しかし、共通の共有成果物を作成
→結合やより難しい調整、複雑性の増加といった、多くの問題を引き起こす。
境界づけられたコンテキストの考え方
→局部的なコンテキスト内で最もうまく機能する各エンティティを識別
したがって、組織全体で統一されたクラスを作成する代わりに、
各問題領域がそれぞれのクラスを作成し、統合点においてその相違を調整

小さな量子
→小さなスコープを意味し、よって、それはより速い変化を意味する。
一般に、小さな部品は大きい部品よりも扱いが容易。

進化的アーキテクチャを構築することのキーの1つ
→ソフトウェアアーキテクチャによって支えたい性能に合うように、コンポーネント粒度を決定し、コンポーネント間を結合すること
進化的アーキテクチャでは、アーキテクトはアーキテクチャ量子を扱う。
アーキテクチャ量子は、壊れがたい力でまとまったシステムの一部。
例:トランザクションは強い核力として振る舞い、無関係な部分を共に結び付ける。
トランザクションコンテキスト分割は可能
→それは複雑なプロセスであり、しばしば分散トランザクションのような偶発的な複雑さを招く。

モノリスアーキテクチャ
→データベースサーバーなどの依存コンポーネントを含むアプリケーションそのものが量子となる。
大きな量子サイズのシステムを進化させることは難しい。

漸進的な変更
変更が既存のレイヤ内に分離されている場合
→アーキテクチャに何らかの変更を加えることを容易だと感じる。

境界づけられたコンテキストが顧客に関する情報を共有する必要がある場合
→1つの表現へと統一しようとはせずに、メッセージングを介して情報の共有を実現する。

各サービスはDDDのドメイン概念を中心に定義
技術アーキテクチャと他の全ての従属コンポーネント(DBなど)
→境界づけられたコンテキスト内にカプセル化
 高度に疎結合されたアーキテクチャを形成
 各サービスは境界づけられたコンテキストの全ての部分を「所有」
 他の境界づけられたコンテキストとメッセージング(RESTなど)を介して通信。
→したがって、他のサービスの実装詳細(DBスキーマなど)を知るサービスは存在せず、不適切な結合が防止される。

問題領域によってはデータを細分化できない
重いトランザクションを処理するシステムは、マイクロサービスにはあまり適していない。
→トランザクションの動作は、サービス間の調整を要するため、コストが高くつきすぎる
複雑なトランザクション要件を持つシステム
→DB要件がそこまで難しくないサービスベースアーキテクチャの方がうまく対応

量子の大きさをコントロール
アーキテクチャの量子サイズ
→開発者が進化的な変更をいかに簡単に行えるかに大きく作用
モノリスやESB駆動SOAのような量子サイズの大きなアーキテクチャは進化が難しい。
→変更ごとに調整が必要になるから。
Broker型EDAやマイクロサービスのような、より疎結合化されたアーキテクチャ
→進化を容易にするためのより多くの手段を提供する。
アーキテクチャを進化させる上での構造上の制約は、開発者がどううまく結合や機能的凝集を扱うかにかかっている。
もし開発者が十分に定義されたモジュール式のコンポーネントシステムを構築するなら、進化はより容易に。
コンポーネントの分離に熱心に取り組む→疎結合によってアーキテクチャ量子の大きさが小さくなる
→モノリスでも、アーキテクチャの進化可能性は増える

「アーキテクチャ量子が小さければ小さいほど、アーキテクチャはますます進化しやすくなる」

多くのDBリファクタリング手法
→リファクタリングに移行フェーズを設けることで、タイミング問題を回避
このパターンでは、開発者は移行開始時と終了時の2つの状態を持ち、移行中はその古い状態と新しい状態の両方を維持。
移行状態→後方互換性の維持を可能に
→企業内の他のシステムが変更に追いつくのに十分な時間も与える。

アーキテクトは時にビジネスにとって自然なレベルよりも細かい粒度でアーキテクチャを構築しようとして間違う。
例:マイクロサービスアーキテクチャは重厚なトランザクションシステムにはあまり適していない。
→サービス粒子の目標がとても小さいから
サービスベースアーキテクチャは量子サイズの要件が厳密でないため、うまく機能する傾向あり
アプリケーションの全ての結合特性を考慮する必要がある
・クラス
・パッケージ
・名前空間
・ライブラリ
・フレームワーク
・データスキーマ
・トランザクションコンテキストなど、

これらの次元(またはそれらの相互作用)を無視
→アーキテクチャを進化させようとする際に問題を作り出す。

「DBトランザクションは強力な核力として振る舞い、量子を結びつける」

モノリシックアーキテクチャをより粒度のか細かいアーキテクチャに移行
→まず少数の大きなサービスにするところから始める。
白紙の状態からマイクロサービスアーキテクチャを構築
→開発者はサービスとデータのコンテキストの大きさを制限することについて必死にならなければならない。

進化的アーキテクチャを構築しようとする前
→スキーマと品質の両方の観点で開発者がデータをうまく進化できるようにしてほしい。
・不十分な構造はリファクタリング
・データの品質を基礎とするために必要な行動を何でもやっていくべき。
これらの問題を永久に処理する複雑で継続的な仕組みを構築するのではなく、これらの問題を早期に解決すること。
レガシーなスキーマとデータには価値がある
→進化する能力への重しにもなる。
アーキテクト、DBA、ビジネス担当者は、何が組織における価値を表しているかについて率直な会話をする必要がある。
組織における価値
→レガシーデータを永久に保持し続けることだろうか。
 それとも、進化的な変更を作る能力だろうか。
本当の価値があるデータを見定めて、それを保持しよう。
古いデータ
→参照用には利用可能にしつつも、進化的な開発の主流からは外すようにしよう。

「スキーマのリファクタリングや古いデータの削除を拒むことは、
アーキテクチャを過去を結びつけ、それはリファクタリングを難しくする」

進化するシステムを構築するには、開発者とDBAは現代の開発プラクティスと並行してデータに関する効果的なプラクティスの実践を促進する必要がある。

進化的アーキテクチャの3つの基本的な要素

  • 「適応度関数」
  • 「漸進的な変更」
  • 「適切な結合」

進化的アーキテクチャ構築3つの手順

1. 進化の影響を受ける次元を特定する
どの次元をアーキテクチャの進化とともに保護したいのか特定

2. それぞれの次元に対して適応度関数を定義する
アーキテクトは、どの次元を継続的に注視するかを決定し、
それをWikiなどの軽量フォーマットで文書化

3. デプロイメントパイプラインを使って適応度関数を自動化する
プロジェクトで進化的アーキテクチャを支える開発者の責務の1つ
→サイクルタイムを良い状態に維持する
他の多くのメトリクスがそこから派生するため、サイクルタイムは漸進的な変更において重要な意味を持つ
プロジェクトのサイクルタイムが長くなれば、新しい機能を送り出せる速度は遅くなり、それは進化に影響する
開発者はあらかじめ全てを予期することはできないため、ソフトウェアの「未知の未知」問題に悩まされる。
アーキテクチャの一部が厄介な兆候
→適応度関数を構築することで、アーキテクトはこの不全が育つのを阻止可能
非機能要件が壊れる状況を警戒
将来の問題を防ぐために適応度関数とともにアーキテクチャを改良していかなければならない

既存のアーキテクチャに進化可能性を加えられるか3つの要因

・コンポーネント結合
技術アーキテクチャの進化可能性に大きく左右
きれいに疎結合化されたシステムは進化を容易に
生い茂った結合の巣窟はそれを痛めつける
真に進化可能なシステム構築
→影響を受けるアーキテクチャ上の全ての次元を考慮する必要
 結合の技術的な側面を超えて、システムのコンポーネントの機能的凝集についても考慮し守る必要
あるアーキテクチャから別のアーキテクチャへ移行
→再構築されたコンポーネントの最終的な粒度は、機能的凝集によって決定される

コンポーネントを不合理なレベルには分解できないという意味ではなく、
→コンポーネントは問題のコンテキストに基づいた適切な大きさを持つ
例:重厚なトランザクションシステム
→ビジネス上のいくつかの問題は他よりもより結びついている。
この問題に抵抗して究極に疎結合化されたシステムを構築しようとすることは、非生産的。

・開発プラクティス
継続的デリバリープラクティスは
→必ずしも進化的アーキテクチャを保証しない
しかし、それがなければ進化的アーキテクチャを実現することはほとんど不可能。
進化的アーキテクチャを構築することにおける最大にして唯一の障害
→扱いにくい運用
もし開発者が変更を容易にデプロイできなければ、フィードバックサイクルの全ての部分が妨害される

モノリシックアプリケーションの分解
→正しいサービスの粒度を見つけることが重要。
大きなサービスを作成
→トランザクションコンテキストやオーケストレーションのような問題は生じにくい
 モノリスを小さな部品へと分解することにはならない。
コンポーネントを細かくしすぎる
→過剰なオーケストレーション、コミュニケーションのオーバーヘッド、コンポーネント間の相互依存といった問題が生じることになる。

決定を可逆にする

積極的に進化するシステム
→予期しない失敗に陥る
将来の予防として新しい適応度関数を作成する必要がある。
しかし、失敗から回復するには
ブルーグリーンデプロイメント
カナリアリリース
変更を機能トグルの下にデプロイ
→ユーザーの小さなサブセットに対してリリースを行い変更を確認できる。
機能が予期しない動作
→トグルを元の状態に戻し、もう一度試す前に失敗を修正可
要求コンテキストに基づいた特定のサービスへルーティングするサービスルーティング
→マイクロサービスエコシステムにおけるカナリアリリースのもう1つのよく見られる方法。

予測可能ではなく進化可能を選ぶ

未知の未知
→予期せずに生じる、誰もそれが登場することがわかっていなかったもの。
アーキテクトは未知の未知を設計できない。

「全てのアーキテクチャは未知の未知のためにイテレーティブになる。
アジャイルはこれを認識し、すぐにそれを行う」

未知のものを何とかできるアーキテクチャ
→ない。動的平衡はソフトウェアの予測可能性を無駄にする。
代わりに、進化可能性をソフトウェアに組み入れる
アーキテクチャは、最初に作ってしまえばそれで終わりというような代物ではない。
プロジェクトはその生涯を通じて、常に変化し続ける。明白に、しかも予期しないような形で。

アーキテクトは将来の利用量を予測しない
→このライブラリをAPIの後ろに置くことで比較的容易に置き換えられるようにした。
最終責任時点で答えるべき質問
「今この判断をしなければならないだろうか」
「仕事を遅らせることなく、この判断を安全に延期する方法はあるだろうか」
「今ここに置くのに十分足りるものは何で、必要に応じて後で変更が容易だろうか」

インターフェースの適切な位置に腐敗防止層を設置
→機能の置き換えを機械的な作業にできる
腐敗防止層を構築
→特定のAPIの構文を考えることではなく、ライブラリから彼らが必要とするものは何かという意味を考えることを促す。

アーキテクチャレベルでは、開発者は根本的に変化する要件と特性に苦労して取り組む。
正しいアーキテクチャを選択できるくらい十分に学ぶ方法の1つ
→考えの証明を構築
「犠牲的アーキテクチャ」Martin Fowler
考えがうまくいくことがわかったら投げ捨てるよう設計されたアーキテクチャ
例:eBay
1995 年に Perl スクリプトの集合としてスタート
1997年に C++ に移行
2002年には Javaへと移行
→ eBay システムを何回も再構築しているにもかかわらず、うまくいっていることは明らか。

ライブラリの使用
→アプリケーションへの結合が 技術アーキテクチャの進化が必要なときに置き換えが容易
ライブラリとフレームワークを異なるものとして扱う1つの理由
→開発プラクティスに行き着く。
アプリケーションコードの全ては、フレームワークの変更による影響を受ける。
フレームワークのメジャーバージョンが2つ以上時代遅れになる
→最終的に更新するための労力(と痛み)はひどいものになる。
 アプリケーションの基礎部分であるため、チームは積極的に更新を行わなければならない。
ライブラリは一般的にフレームワークよりも弱い結合点を形成する
→更新についてチームはよりカジュアルに行うことが可能

早期に時間費やす場合のコストは、チームが更新を果てなく先延ばしにした場合に比べたら、 ごくわずかで済む。

「フレームワークの依存関係は積極的に更新し、ライブラリの依存関係は受動的に更新すること。」

2種類の悪いプラクティス

多くの開発者はアンチパターンという言葉を「悪い」の俗語と して使用
→実際の意味はもう少し微妙。
ソフトウェアにおけるアンチパ ターン2つの要素
・アンチパターンは当初は良い考えのように 見えるものの、結果的に誤りであることが判明する
・ほとんどのアンチパターンにはより良い選択肢が存在する。
多くのアンチパターンは後になってから気づく。
→避けることは困難。
落とし穴は表面的にはよい考えのように見えるが、すぐに筋の悪さが明らかになる。

ベンダーキングアンチパターン
アーキテクチャが全体的にベンダー製品を中心に構築され、組織がツールに病的に結合されてしまう
十分に時間をかけても、開発者は必要なものを完全に実装するのに十分なカスタマイズを ERPツールに対して行えず、
ツールの限界や彼らがツールを中心としたアーキテクチャ領域を中心に置いてしまったという事実による無力さを理解する。

「ラスト 10%の罠」
ビジネスプロセスの視点か最適なワークフローをサポートできない。
フレームワークの元で精を出し終えると、ツールのカスタマイズではなく、プロセスを変更する。
→企業間の差別化要因は少なくなる。

「Let’s Stop working and Call It A Success(作業するのをやめて、それを成功と呼ぼう」原則
何百万ドルも無駄にしていることを認めたいCTO はいない
ツールベンダーも長年にわたる悪い実装を認めたくはない。
→両方の思惑から、作業することをやめ、それを成功と呼ぶことに同意
けれども、約束されたはずの多くの機能は未実装となる。

「アーキテクチャをベンダーキングと結合しないこと」

ベンダー製品を単なる統合点として扱おう。
統合点の間に腐敗防止層を設置
→ベンダーツールの変更がそのアーキテクチャに影響を与えるのを防ぐことができる。 

現代のソフトウェアにおける勝利の鍵の1つ
→どれくらいうまくいく効果的な抽象を作れるかどうか。 
しかし、抽象化はコストにもなる。
→抽象でないものこそが完全
もし、それが存在し、抽象でないのなら、それは本物。 
「自明でない抽象化は全て、程度の差こそあれ、漏れがある」Joel Spolsky

当時流行っていた Accessやそれ以外の 4GL言語
→クライアントが望むことの80%は迅速かつ簡単に構築できる
しかし、顧客が望む次の10% は、可能だったが、かなり難しかった。

マイクロサービス
→コードの再利用を避け、結合より重複を選ぶという考え方を採用。
再利用は結合を意味
そして、マイクロサービスアーキテクチャは極度 に分離される。
しかし、マイクロサービスの目標は重複を促すことではない。
マイク ロサービスの目標
→ドメイン間のエンティティを分離
共通クラス を共有するサービスは、もはや独立していない。
例:Checkout と Shipping は互いにそれぞれの Customer の内部表現を持つ。
顧客に関 する情報を協調させる必要がある場合
→サービスは互いに関連する情報をやり取 りしあう。
アーキテクトは異なるバージョンの Customer をアーキテクチャ内で一致 させたり統一したりしようとはしない。
再利用の利益は錯覚であり、再利用による結合は全ての不利益を導入
→重複の欠点を理解しつつも、より多く結合することになるアーキテクチャ上のダメージをより局所的に抑える。

コードの再利用
→資産になるだけでなく、潜在的な負債も生む。

「結合点が進化化やその他の重要なアーキテクチャ特性を妨げる場合には、分岐や複製によって結合を壊すこと」

チームが共有コードの所有権を持つことによって結合を壊した。
負担は増えるものの、新しい機能を届ける彼らの能力の足を引っ張ってきたものから彼らを解放した。
他のケース:おそらくより大きな部分 から何らかの共有コードを取り除く
→より選択的な結合と段階的な疎結合化が可能に

「アーキテクトは、アーキテクチャの「~性」の適応度を継続的に評価し、アーキ テクチャがまだ価値を持ち、アンチパターンに陥っていないことを保証しなくてはならない」

アーキテクトは何度もその時点で正しい判断だとする判断を行う
→動的平衡 のような条件の変化によって、その判断は時間経過とともに悪い判断になってしまう。

ゴルディロックスガバナンス (Goldilocks Governance)モデル

標準化のために、単純、中間、複雑という3つの技術スタックを選定
→個々のサービス要件によってスタック要件が導かれる
チームは適切な技術スタックを柔軟に選択しながら、 企業に標準化の利点も提供することができる
例:何年もの間、PenultimateWidgets のアーキテクトは全ての開発をJava と Oracle に標準化しようとしてきた。
より細分化されたサービスを作るにつれて、彼らはこのスタックは小規模なサービスに大きな複雑さを課すということに気が付いた。
→けれど彼らは依然としてプロジェクト間での知識とスキルの移植性を望んでいた
マイクロサービスの「全てのプロジェクトが独自に技術スタックを選択する」 というアプローチ
→完全には受け入れたくなかった。
しかし、最終的に彼らはゴルディロックスガバナンスの方法をとり、以下の3つの技術スタックを選択
小
スケーラビリティやパフォーマンスの要件が厳しくないとても単純なプロジェク トには、Ruby on Rails と MySQL
中
バックエンド:中規模のプロジェクトには、Go言語と、データ要件に応じて Cassandra か MongoDB、MySQLのいずれかの1つ
大
大規模なプロジェクトには、可変アーキテクチャの問題にうまく対応するため、引き続きJavaとOracle

サイクルタイムが速い
→アーキテクチャが速く進化できる
プロジェクトのサイクルタイム
→アーキテクチャの進化速度を決定
進化速度は サイクルタイムに比例

開発者はプロジェクトのサイクルタイムより速くシステムを進化させることはできない。
→ チームがソフトウェアをより速くリリースできれば、チームはシステムの一部をより速く進化させることができる

サイクルタイム
→進化的アーキテクチャの重要なメトリクス。アトミックな適応度関数の優れた候補
 サイクルタイムが速ければ、速いほど、進化速度が速い
例:自動化されたデプロイメントパイプラインを使ってプロジェクトをセットアップし、3時間のサイクルタイムを達成
→検証や統合点を増やすにしたがって、サイクルタイムが徐々に増加
チームは サイクルタイムが4時間を超えると警告を出す適応度関数を確立
適応度関数 がしきい値に達する
→開発者はデプロイメントパイプラインの仕組みを再構築したり、4時間のサイクルタイムが許容できるかどうかを判断
ほとんどのプロジェクトでは、開発者は 徐々に上昇するサイクルタイム に気付くことはない。
→競合する目標に優先順位をつけることもないため、こうした決定を暗黙的に行っている。
適応度関数を 使用すると、将来の判断点を中心にしきい値を設定できる。

「進化の速度はサイクルタイムの関数だ。サイクルタイムを速めることで、進化を速めることができる」

落とし穴:製品のカスタマイズ

営業は製品を売りたいがために、無限にカスタマイズ可能なソフトウェアを欲しがる。
→カスタマイズ可能性は、実装技術が要する相応コストと引き換え 
・顧客ごとの個別ビルド
このシナリオでは、営業は厳しい時間スケールの上で機能の固有バージョンを約束
→バージョンを追跡するためにバージョン管理システムの ブランチやタグなどを駆使することを強制する。
・永続的な機能トグル
機能トグルは、しばしば永続的なカスタマイズを作成するために戦略的に使われることがある。 
→機能トグルを使って、顧客ごとに異なるバージョンを構築したり、
製品の「フリーミアム」バージョンを(料金を払うことでプレミアム機能 成形を解除できる無料バージョン)を作成したりする。

製品駆動カスタマイズ
製品の一部は、UIを介したカスタマイズを追加する方へ進む。
→アプリケーションの永続的な部分であり、他の全ての製品機能と同様の注意が必要
機能トグルとカスタマイズ
→製品に実行できる経路の組み合わせを多く含めることになるため、テストの負荷を大幅に増加

アンチパターン:レポート機能

組織はビジネスで必要となる可能性のある全ての視点(受注の月次報告など)を提供することに奮闘
特に苦労する点
→全てが同じモノリシックアーキテクチャやデータベース構造によってもたらされる場合
サービス指向アーキテクチャの時代
→アーキテクトは全てのビジネス的な 関心事を同じ「再利用可能な」サービスの集合を介してサポートする試みに苦労
そして、サービスがより汎用的になるほど、それを利用するためにカスタマイズする必要があることを発見
レポート機能
→モノリシックアーキテクチャにおける不用意な結合の良い例 
記録のシステムとレポートのシステムで同じデータベース を使いたいと考える。
→両方をサポートする設計はどちらにも最適化されないため、問題が生じる
開発者とレポート設計者が一緒になってレイヤ化アーキテクチャに作ってしまう、
→よくあるこの種の落とし穴:関心事が互いに反目しあっていることを示している。
不用意な結合を減らすため
→レイヤ化アーキテクチャを構築し、関心事をレイヤに分離
 レポートはその機能をサポートするためにレイヤの分割を必要としない。
ただデータが必要なだけ。さらに、レイヤを介したルーティング要求は待ち時間も増加させる。
したがって、優れたレイヤ化アーキテクチャを持っているにも関わらず、
多くの企業はレポー ト設計者にレポートを直接データベーススキーマに結合することを許してしまう
→レポートを壊すことなしにスキーマを変更できる能力を破棄

多くのマイクロサービスアーキテクチャは、動作の分離によってこのレポート問題を解決。
サービスの隔離は
→分離には役立つが、統合には役立たない。
 「記録のシステム (System of Record:SoR)」領域のデータベースとしてサービスのアーキテクチャ量子内にそれぞれ埋め込まれ配置される、
イベントストリーミングやメッセージキューを使い、トランザクション動作ではなく結里整合性をもって、これらのアーキテクチャを構築。
一連のレポートサービスは、イベントストリームをリッスンし、レポート用に最適化された非正規化レポートデータベース を作成。
→結果整合性を使うことで、調整から解放される。

これは アーキテクチャの観点での結合の一形態
→アプリケーションの様々な用途に対 して異なる抽象化を可能にする。
例:PenultimateWidgets のマイクロサービスアーキテクチャ
→アーキテクトは境界づけられたコンテキストに分割されたドメインを持ち、それぞれがドメインの「記録のシステム」用データを持つ。
結果整合性とメッセージキューを使いデータの追加や通信を行い、ドメインサービスとは別の一連のレポートサービスを提供。
UIがCRUD操作
→マイクロサービスとレポート サービスの両ドメインが通知を受け取り、適切な行動を取る。
レポートサービス
→ドメインサービスに影響を与えることなしにレポートに関する処理を行う。
ドメインを合成することで生じる不適切な結合を削除することは、各チームがより具体的で単純なタスクに集中することを可能にする。

機能横断型チーム
→サイロを超えて責任を指摘することを防ぎ、チームに責任感を生じさせることで、チームメンバーに最善の仕事を行うよう促進。
うまく機能しているアーキテクト
→リーダーシップの役割を果たし、技術文化を作り、開発者がシステムを構築するための方法を設計。
進化的アーキテクチャを構築するために必要なスキルを個々のエンジニアに教え、奨励。
 次のような質問をすることで、アーキテクトはチームにあるエンジニア文化を理解する質問
・チームの全員が適応度関数とは何かを理解していて、新しいツールやプロダクトの選択が新しい適応度関数を進化させる能力に与える影響を考慮しているか?
・チームは彼らが定義した適応度関数がシステムとどれだけ合致しているかを計測しているか
・エンジニアは凝集と結合を理解しているか?
・どのドメインと技術概念が一緒に属しているかについての会話があるか?
・チームは自分たちが習得したいテクノロジーに基づいてではなく、変更する 能力に基づいて解決策を選択しているか?
・チームはビジネスの変化にどのように反応しているか? 小さな変更を取り 入れるのに苦労しているか、あるいは小さなビジネスの変更に時間を費やしすぎていないか?
チームの振る舞いを調整
→チーム周辺のプロセスを調整。 人々はやるように言われたことに反応するから。

 「どのような尺度で私を評価するのか教えてくれれば、どのように私が行動するのか教えてあげましょう」
 -エリヤフ・ゴールドラット 「ゴールドラット博士のコストに縛られるな!』

 3度目になったらリファクタリング開始
 「最初は、単純に作業を行う。2度目に以前と似たようなことをしていると気づい た場合には、重複や無駄を意識しつつも、とにかく作業を続けてかまわない。そして3度目に同じようなことをしていると気づいたならば、そこでリファクタリングをする。 」

 多くのチーム
→新しい機能を提供することによって最もよく突き動かされ、見返りを与えられる。
コード品質と進化可能性の側面
→チームにとってそれを優先される場合にのみ考慮される。
進化的アーキテクチャを気に掛けるアーキテクト
→チームの行動について注意を払う必要。
・チームが進化可能性を助ける設計判断を優先したり、それを促進する方法を見つけたりしているかどうか

実験の文化

進化を成功させるには、実験が必要
→計画に忙しすぎるために実験に失敗する企業も存在する。
実験を成功させる
→小さいアイデア(技術的側面とプロ の期間の両方から)を試す習慣的な小さなアクティビティを実行
 うまく行った実験を既存のシステムへと統合することである。

「真の成功基準とは、24時間に詰め込める実験の数だ。 」
トーマス・エジソン

量子

量子あたりのコストは、量子の数が増えると下がることになる。
アーキテクチャがより小さい部分から構成されるため、
関心の分離はより離散的、定義的になることが挙げられる。
物理的な量子数が増加すると、運用面での自動化が必要になる。
特定の時点を超えると、手作業での処理が非現実的。
量子をとても小さくすると、せん断数はより重いコストとなる可能性がある。

アーキテクトは適切な量子サイズと対応する調整コストの間のスイートスポットを見つけようと努力する。
より小さい量子サイズはより短いサイクルタイム

量子サイズ:サービスベースのアーキテクチャを構築することが現実的かも

モジュール性を高めて結合を分離、適応度関数と漸進的な変更を実証できる

「実証が議論を打ち負かす」

漸進的な変更にとって、テストは重要
適応度関数はテストを積極的に活用

イノベーションのジレンマとして知られる現象は、
よりアジャイルなスタートアップがエコシステムのより良い変化に対処するにつれて、
十分に確立された市場にいる企業が失敗する可能性が高いことを予測してる。

Amazonは全てを1つのものに結合することが最終的にスケーラビリティを制約することに気づいた。
不適切な結合は進化にとって最大の難題。
スケーラブルなシステムは進化可能なシステムにも対応する傾向

進化は根本的な変化
適応度関数によって破壊から保護された場所でアーキテクチャを変更
内部に潜んだ時代遅れの解決策を増やすことなく、有用な方法で進化し続ける

泥団子は進化できない
修正はしばしば書き直しよりもコスト
既存アーキテクチャを進化可能に変換するための最初のステップ:モジュール性
現在のシステムに存在するモジュール性を何でもよいので見つけ出し、アーキテクチャをそれ中心に再構築
アーキテクチャの絡み合いが減れば、基礎の構造を確認し、再構築に必要な労力について合理的な決定が容易になる

組織の中の慎重な人々を説得するより、その考え方がどう自分たちの仕事を改善するか実証しよう

現代のソフトウェアアーキテクチャを持つ破壊的な企業は、
より優れた情報技術を持っているために、既存の企業の領域に入り込んできて突如支配的になる

進化的アーキテクチャの構築は、チームが自信をもってアーキテクチャレベルで漸進的な変更を行なっていける

進化的アーキテクチャは、漸進的な変更を装って、チームに現代の開発プラクティスを強要する。
これは有益な副作用
それらの実践がアーキテクチャを壊さず変更可能にしリリースの頻度を増やす

進化的アーキテクチャの考えをビジネス側に売り込む最善の方法は、
新しいビジネスを届ける能力を中心に展開する。
アーキテクトが技術的な改善を指摘に語ると、ビジネス側の人間はどんよりする。
彼らの言葉で影響を語るのが良いだろう。

最後に

翻訳は少し分かりづらかったが、それでも面白い箇所が多く、
本メモの量も増えてしまった。削る部分が難しい。

進化可能なシステムを構築する上でキーワードとなるのは、
やはり「疎結合」だと感じた。
進化可能とは、交換可能であり、更新可能であること。
密結合になってしまうと、これらが阻まれることが多い。

本書のマイクロサービス分割でも、
『マイクロサービスアーキテクチャ』と同様、DDDが取り上げられていた。
DDDもおさえておかないといけない技術で、現在本を読んでいるので、
読み終わったら、こちらもブログに公開したい。

【本メモ】『アウトプット大全』

話題となっていた『アウトプット大全』を読んだので、本メモを公開。

CHAPTER 1 RULES アウトプットの基本法

読む、聞くがインプットで、話す、書くがアウトプット

インプットは「脳内世界」が変化するだけ。
アウトプットして、初めて「現実世界」を変えることができる

情報の入力から2週間で3回以上アウトプットすると、長期記憶として残りやすくなる
脳に入力された情報は「海馬」というところに2〜4週間保存される
仮保存期間中に、その情報が何度も使われると、脳はその情報を「重要な情報」と判断し、
「側頭葉」の長期記憶に移動する

インプットとアウトプットのサイクルを回す
黄金比は3対7
平均的な比率は逆

自己成長にフィードバックは不可欠
うまくいったときも、失敗したときも、その「理由」を考えよう

「なぜ」を突き詰めると、その先に「気づき」が見つかる

アウトプット6つのメリット
・記憶に残る
・行動が変わる
・現実が変わる
・自己成長する
・楽しい
→圧倒的な結果が出る

成功を収めたいなら、とにかくアウトプットが不可欠。

CHAPTER 2 TALK 科学に裏付けされた、伝わる話し方

「話す」ことが、最も簡単なアウトプット

アイコンタクトで、お互いの細やかな感情の機微が伝わりやすくなり、
コミュニケーションが深まる
→ドーパミン分泌

クッション話法
相手にできるだけショックを与えずに伝える方法
YesBut話法
まず、ポジティブな情報を伝えて雰囲気を作ってから、悪いニュース
YesHow話法
疑問文形式で、本人に考えさせる
人間の行動が変わるためには「気づき」が必須
部下の行動を改善させる効果の高い方法

まずは「いい点」を伝えて、相手の心を開こう

挨拶は「あなたを認めています」のサイン

ザイオンス効果
雑談は、内容より回数が重要

「コントロールできる」という感覚を持つだけで、ストレスの影響は消えてなくなる
人に相談することで、対処法が示される。
あるいは、自分で順序立てて話すことで頭の中が整理され、自分で対処法や方向性が見えてくる
→現実は何も変わっていないのに、気分がものすごく軽くなる

CHAPTER 3 WRITE 能力を最大限に引き出す書き方

「話す」より「書く」ことのほうが、圧倒的に記憶に残り自己成長を促す
→脳幹網様体賦活系(RAS)が刺激されるから
別名「注意の司令塔」
脳は、その対象物に対して集中力を高め、積極的に情報を収集し始める

書くほどにRASが活性化し、脳全体が活性化していく

アウトプットするのはいつがベスト
→脳が最も多くの情報を保持している「インプットの直後」

貴重で素晴らしい体験もただのインプット
時間とともにどんどん失われて、劣化して、曖昧になっていく

文章を早く書くコツ
・時間を決めて書く
・構成を考えてから書く

TODOリストのメリット
・1日の仕事の流れが確認できる
・集中力が途切れない
・うっかりミスがゼロになる
・ワーキングメモリの容量が増える/仕事が効率化する
人間の脳が一度に処理できる情報量(ワーキングメモリ)は限られている
同時に処理できるのは、せいぜい3つまで
すべてTODOリストに書き出すことにより、脳のワーキングメモリを有効利用できるようになり、
目前のひとつの仕事にすべてに集中力を向ける
→仕事効率が大きくアップ

人は何かに気づいた際、脳の神経回路がつなぎ変わる
「アハ体験」
数秒前の自分とは異なる自分に自己成長している
→30秒〜1分で戻る。瞬間的にメモをする必要がある。

何も考えていないとき=ひらめいたとき
脳の状態はほぼ同じ

創造性の4B
Bathroom
Bus
Bed
Bar

ぼーっとする
「ぼんやり」が脳の働きを活性化

ひらめきに必要な4つのプロセス
・準備
・孵化(休息する)
・ひらめき
・検証

CHAPTER 4 DO 圧倒的に結果を出す人の行動力

「話す」「書く」以外のアウトプット、「行動する(Do)」

昨日までの行動と、今日の行動に変化がある
→自己成長

続ける人になるための5つの極意
・「今」「今日やる」ことだけにフォーカス
・楽しむ
・目標の細分化
・結果を記録
・ご褒美

ドーパミンは、目標達成のガソリン

教える
自己成長に最も効果のあるアウトプット
アウトプットであり、フィードバックであり、さらなるインプット
何かを習得したければ、
「人に説明できる」レベルを目指そう

人間の脳はマルチタスクができない

チャレンジのないところに自己成長はない
新しいことにチャレンジすると、脳内物質・ドーパミンが出る
ドーパミンは「楽しい」という感情を引き起こす幸福物質
同時に「新しいことを学習する」ことをサポートする学習物質でもある

無謀な挑戦は逆効果
実現可能で少しがんばれば達成できる「プチ目標」を設定しよう

「ちょい難」難易度の課題にチャレンジするとき、ドーパミンが最も分泌
→集中力、記憶力、学習能力が高まり、自己成長が最も進む

「まず始める」
5分だけがんばって「やる気」スイッチオン
「作業興奮」
作業を始めると、だんだん気分が盛り上がってきてやる気が出てくる
「側坐核」
側坐核の神経細胞が活動すると、海馬と前頭前野に信号を送り、
「やる気」が出て、脳の調子が上がっていく
しかし、側坐核の神経細胞は「ある程度の強さ」の刺激がこないと活動を始めない
→必要時間はたったの5分

ファーストチェス理論
プロチェスプレイヤーが、5秒で考えた手と30分で考えた手
→86%一致
最初の決断というのは、かなり正しい

睡眠不足は、6時間未満をさす
6時間睡眠を14日間と2日間完全徹夜
→同程度の集中力低下をきたす
何も積み上がらないし、記憶や経験として残らないし、自己成長にもつながらない
7時間以上の睡眠は必須

運動直後から得られる脳の活性効果
・集中力↑
・記憶力↑
・学習機能↑
・モチベーション↑

CHAPTER 5 TRAINING アウトプット力を高める7つのトレーニング法

1. 日記を書く
5つのメリット
・アウトプット力向上
・自己洞察力、ストレス耐性向上
・「楽しい」を発見する力
・ストレス発散
・幸福度アップ
2. 健康について記録する
「体重」「気分」「睡眠時間」を毎日記録
3. 読書感想を書く
4. 情報発信する
5. SNSに書く
6. ブログを書く
7. 趣味について書く

最後に

インプットは「脳内世界」が変わるだけで、アウトプットして初めて「現実世界」を変えることができると書いてあって、
確かになと納得してしまった。

本書にも書かれている通り、自分もインプット過多に陥ってしまっていた。
インプットとアウトプットの比率が、3:7ぐらいになるよう意識し、取り組んでいきたい。

【本メモ】『エンジニアリング組織論への招待 〜不確実性に向き合う思考と組織のリファクタリング〜』

去年話題となっており、 「ITエンジニアに読んでほしい!技術書部門ベスト10」にも選ばれた 『エンジニアリング組織論への招待〜不確実性に向き合う思考と組織のリファクタリング〜』についての、本メモと考察。

エンジニアリング組織論への招待〜不確実性に向き合う思考と組織のリファクタリング〜
エンジニアリング組織論への招待〜不確実性に向き合う思考と組織のリファクタリング

Chapter1 思考のリファクタリング

エンジニアリングとは「曖昧さ」を減らし「具体性・明確さ」を増やす行為
どうしたら効率よく不確実性を減らしていけるのか

未来に何が選ばれるか、乱雑で判断基準のない状態から、
選択肢が絞り込み、何をどのように実現していけばよいのか決めるのが「情報」

不確実なものに向き合うのは「不安」
わからないことは、自分自身を脅かす可能性を考えてしまい、
人は本能的に「攻撃」か「逃避」を選択する。
よって、安心だと「わかっている」物事を優先して実行してしまう。
不安を減らすには、不確実性に向き合う必要がある。

難しい問題は、「何がわかればわかるのか」という次の一手を考え、
それを「確かめる」ことに変換する。

プロジェクトマネジメントでも、不確実性の高いタスクに優先的に取り組めば、時間の読みは正確になる。
不確実なものに直面することは、とても「不安」。
初期に不確実なものを確実に仕上げると、全体像が早い段階で見えてくる。

コミュニケーションの不確実性
・他者理解の不確実性:人は他人や事象を完全には理解できない
・伝達の不確実性:コミュニケーションが到達するとは限らない
・成果の不確実性:仮に理解されたとしても予想されたように行動するとは限らない

コミュニケーションの不確実性は、情報の偏りを生み出す。
経済学においては「情報の非対称性」という。
また、自分と他人の利害が異なる場合に、それぞれが合理的な行動をとったとしても、
全体としては不合理な行動になることを「限定合理性」という。

お互いの情報伝達が不完全で、それゆえに引き起こされた問題でも、
何か害意や悪意をその中に見出してしまいがちなのが人間の性。

「情報の透明性」とは、意思決定と意思決定に関わる情報が、組織内に正しく伝達されるように継続して努力し、
何かわからない決定があったとしても、直接聞いてみようという関係性をつくることです。

わからないものがあったときに、人は「回避」か「攻撃」する機能が本能的に埋め込まれている。

「エンジニアリング」は、不確実性を下げ、情報を生み出す過程。

Chapter2 メンタリングの技術

元々、人の心理などにはとても興味があるため、大変面白く読めた章であった。
これから下の世代も増えてくるのが、意識して取り入れていきたい。

逼迫した問題を抱えた当人は、冷静でいることが難しくなって、
感情的になったり、事実に基づかない思考をしてしまったり、大きな不安でつぶされてしまったりと、
普段の思考力を発揮することが難しくなってしまう。

必要に応じて直接口頭で会話するいう解決策も、少ない時間でレビューを効率的に行う方法の1つ。

自立型人材は、物事の原因を自分に求める。
今より良い状態にするために自分がどうしたらよいか?という問いを常に抱えていて、
課題に対して正面から向き合うことができ、
人間関係のリスクを恐れずに勇気を出して、解決のための行動をとることができます。

メンタリングは、自立型人材を作るため、信頼関係の上に期待値を調整して、
適切に自己効力感をもてるようなフィードバックループを作り出す。

メンターは「何か課題を指摘する」ための存在ではなく、
課題に一緒に向き合い成長を支援するというコミットが求められる。

・他者説得:このように人から与えられた説得による知識
・自己説得:自分自身で気がついたこと
メンタリングでは、他者説得よりも自己説得を重視し、その獲得を促す。

他者説得の特徴
・他人が答えを伝える
・体感を伴わない
・理解を確認できない

目的はあくまでメンティの行動を変容させ、次のステップに移行させていくこと。

自己説得の特徴
・他人が質問で促す
・体感を伴う
・行動の変化が発生しやすい

自己説得を生み出すには、答えを言うのではなく、
「事実確認」と「情報の非対称性の解消」に気がつくような適切な質問の積み重ねが重要。

傾聴
・「相手の」感情への共感を言動で表す
・「相手の」話の内容を「可視化」をする
・「相手の」思考の「盲点」を探索しながら質問をする

私たちは物事を「認知する枠組み」をもっていて、その枠組みの中でしか情報を処理することができない。
このような認知の枠組みのことを「認知フレーム」という。
対話によって、認知フレームを変えることを「リフレーミング」。

情報の非対称性
・自分は「わかっている」けど、相手はわかっていない
・相手は「わかっている」かもしれないけれど、自分はわかっていない

「情報の非対称性」を解消するには、
・自分の情報を相手に伝える
・相手の情報を自分が聞く

心理的安全性
「問題点の指摘」「自分の弱みの開示」「失敗の報告」といった行為には、「対人リスク」が伴う。
「心理的安全性」が高い状態とは、このような「対人リスク」を伴う行動が増えている状態のこと。

メンターはメンティに対して「存在を認めている」というメッセージを発し続ける必要がある。
このようなテクニックを「アクノレッジメント(承認)」という。
相手に対して、興味関心をもち、変化にいち早く気がつき、時間を費やして、言葉や行動を通して伝えることがアクノレッジメントの基本。

メンタリングの最終工程は「これからどうするか」を話し合い、合意し、次回に振り返ることを約束すること。
心理的安全性のある関係性の土台を作り、傾聴と可視化、リフレーミングを通じて問題の変換を行った後に、
メンティとメンターは「次の行動」を決めていく。

Chapter 3 アジャイルなチームの原理

この章は「不確実性」との関連について説明している所は面白く読めたが、
以下3つの書籍を熟読しているので、基本的には目新しく感じる部分が少なかった。



Chapter 4 学習するチームと不確実性マネジメント

これまで大小さまざまなプロジェクトの開発マネージャーをしてきているので、
この章についても、感覚的に既に身についてる内容が多かった。

基本的なポイントをおさえておくのは大切だが、
プロジェクトは、構成メンバーの技量と理解度・要件と納期の難易度など、
色々な要因に左右される事が大きいので、あまり教科書的に対応していかない方が良いように感じている。
属人化した作業や作業間の依存関係によって生まれる制約も、プロジェクトを進めていくと肌で感じる部分である。

「エージェンシースラック」
依頼者からみて、代理人に「嘘をついたほうがトクになる」と思わせ、通常よりも高い費用が必要になる事。
「コントロールコスト」
「依頼者の利益」が「代理人の利益」になるように監視やインセンティブの形で支払う必要があるコスト。
「シグナリングコスト」
代理人である「情報をもつ側」が情報を開示し、非対称性を解消するために支払うコスト。

Chapter 5 技術組織の力学とアーキテクチャ

不確実性から生まれる「情報の非対称性」と「限定合理性」が組織において、
どう悪影響を及ぼすかが書かれている。
最後にアーキテクチャについても少し書かれていたが、マイクロサービスは以下の書籍に詳しい。


組織の中で「情報の非対称性」が加速すると、
いわゆるセクショナリズムと呼ばれるような、組織の一部では合理的であるが、全体的には合理的ではないといった論理が幅を利かせるようになる。

ソフトウェア開発において、多かれ少なかれ、次第に初期設計からの逸脱を要求されるようになる。
このような状態への追加開発は、
ソフトウェアの中身を知らない人々の感覚と、実際にソフトウェアを書いている人々にとって、
必要な作業との時間感覚の差が発生する。
その認識の差は邪推を生み出し(エンジニアの能力的な問題ではないか/努力不足ではないか)、
多くのハレーションが現場レベルで引き起こされる。

綺麗でシンプルなコードは、のちのち「技術的負債になりにくい」という性質をもっていることが多く、
汚いコードは、複雑であるがゆえに、全体を読み解くことが難しくなってしまい「技術的負債になりやすい」という性質をもっている。
「今必要な機能をシンプルに作る」

非機能要件の可視化
経営者や事業責任者にとっては、売上確保が最優先で、そのために保守性への時間を割くことの合理性があるように思えない場合がある。
このとき、コミュニケーション上のミスがあった場合(頭ごなしの否定/中間マネジメントが結論として、やらないという結果だけを伝える)、
エンジニアは「保守性への要件」提案は無駄なのかと考えるようになる。

最後に

不確実性が「情報の非対称性」と「限定合理性」を生み出し、
個人・メンター/メンティ・組織にどういった影響を及ぼすか、
またそれにどう対処するか言語化されていて、とても興味深かった。
システムの本というより、コミュニケーションや組織論の話でしたが、
一読の価値はあるなと思いました。

golang.tokyo #17に参加してきました!

golang.tokyo って?

プログラミング言語Goの導入企業メンバーが集まり、Goの普及を推進するコミュニティです。 トークイベント、ハンズオン、etcのイベントを開催していく予定です。

golang.tokyo #17 は、
テーマが「今あらためてテストの話」で、テストについての回でした!

f:id:abemotion:20180825001457j:plain

f:id:abemotion:20180825001542j:plain 会場は freee さん。
美味しい食事やお酒をたくさんご用意いただきました...!

各発表のポイントや気になった点について、まとめていきたいと思います。

タイムテーブル

時間 内容
19:00 ~ 開場・受付
19:30 ~ 19:40 オープニング
19:40 ~ 20:10 Tour of testing by budougumi0617
20:10 ~ 20:40 非公開な機能を使ったテスト by tenntenn
20:40 ~ 21:10 休憩
21:10 ~ 21:20 LT1 外部環境への依存をテストする by duck8823
21:20 ~ 21:30 LT2 Developer-friendly なテストを考える by izumin5210
21:30 ~ 21:40 LT3 止めたいのに止められないテストの話 by knsh14
21:40 ~ 21:50 終了・撤収

Tour of testing by budougumi0617

1つ目は、@budougumi0617 さんによる Tour of testing in 2018 の発表でした。

説明された内容や、文中のリンクは以下のブログに記載されています。 https://budougumi0617.github.io/2018/08/19/go-testing2018/

自己紹介

Today's contents

Today's goal

Introduction 01

Start test 02

  • Basic and Naming
    • ファイル名はxxx_test.go
    • go test のときだけビルド
  • Test data を用意する

  • Execute test

# カレントパッケージのテストを実行する
$ go test

# パスで指定されたパッケージのテストを実行する(相対パス指定が可能)
$ go test ./table

# サブパッケージを含めたパスで指定されたパッケージ以下のテストを全て実行する
$ go test ./...

# 特定のテストコードだけを実行する(テスト対象も含めて実行する)
$ go test sum_test.go sum.go

# カレントパッケージ配下にある"Minus"というサブテスト(後述)だけを実行するとき
$ go test ./... -v -run /Minus

# Race condition の検出
$ go test ./... -race
  • go vet を抑制する
    • $ go test -vet=off
    • Go 1.10からテストの実行前にgo vet が実行される
  • Test Cache

    • Go 1.10から go build/testの結果がキャッシュされる
    • キャッシュを削除する / go clean -testcache
    • キャッシュなしで実行 / go test -count=1
  • -parallel nオプションで最大並行実行数を制御する

    • T.Parallel()メソッドが呼ぶテストケースは並行実行
    • $GOMAXPROCS
    • parallel nオプションのnで同時実行数を制御
  • cpu listで$GOMAXPROCSを変更しながらテストする

  • playgroundでテストを実行できる
    • 実はそのまま動かせるようになったのは最近

How to write test

  • テストコードのパッケージ
    • ディレクトリに複数パッケージは通常許されない
    • 例外的に"xxx"と"xxx_test"は共存可能
  • TB.Error / TB.Errorf
    • テストの失敗が記録される
    • 後続処理は継続される
  • TB.Fatal / TB.Fatalf
    • 失敗が記録され、テストケースが即時終了する
    • その場で宣言済み
  • TB.Fail
    • TB.Error / TB.Errorf が内部的に呼んでいる
  • TB.FailNow
    • TB.Fatal / TB.Fatalf が内部的に呼んでいる
  • TB.SkipNow / TB.Skip
    • テストケースを無効化する
  • TB.Log / TB.Skip
    • -vオプション、あるいはFailしたときにログ出力
    • ベンチマーク時は常に出力
  • want / got
    • expected? NO!
    • actual? NO!
    • 変数名は短いほうがGo way

Get coverage

  • Goは標準機能でテストカバレッジを計測できる
  • Go1.10からは複数パッケージのカバレッジも簡単に取得できるようになった
    • go test -cover ./...
  • go toolでカバレッジの計測結果をHTMLに出力できる

Today's summary

  • go testコマンド / testing.T を改めて確認
    • Go 1.10までの仕様を復習
  • ベタープラクティスをまとめる
  • ひとつでも多く新しい発見をしてもらう

質疑応答

  • Q . 並行テストの使い方は?

    • 「あまり意識してないですが、単純に遅いので早くするため。 個人的にはやってないが、プロジェクトではやっています。」
  • Q . 並行のオーバーヘッドは?何行からやる?

    • 「意識して遅くなることはないと感じています。」

@budougumi0617 さんのスライドは、こちらも大変参考になりました!
※ クイズ形式みたいになっていて、解きながら読み進められます

初級者向けGoの落とし穴と解説 / Traps and Explanations in Go

非公開な機能を使ったテスト

2つ目は、@tenntenn さんによる 非公開な機能を使ったテスト の発表でした。

内容的には「こちらに、ちょっと情報を足したバージョンです」とのこと。
Go Fridayこぼれ話:非公開(unexported)な機能を使ったテスト #golang

TL;TD(too long; didn't read.)

  • テストはテスト対象と別のパッケージにしよう
  • 別パッケージだと非公開な機能にアクセスできない
  • export_test.go というファイルを使うと解決する

テストはテスト対象と別のパッケージにしよう

  • テストが外部のパッケージになる
  • テスト対象のパッケージのユーザーと同じ視点で書く必要がある
    • Exampleテストを使う手もある
    • 使いづらい部分を早期に発見できる
  • テストが内部のコードに依存しなくなる
    • 公開(exportedな)された機能にしかアクセスできない
    • 非公開な機能にはアクセスできない

別パッケージだと非公開な機能にアクセスできない

  • 内部で使用している複雑な機能をテストしたい
    • unexportedな関数で実装されている
    • いろんなところで呼ばれている
    • 関数単体でテストしたい
  • 本当に非公開にする必要があるのか?
    • そんな複雑な処理をunexportedにしておく必要があるのか?
    • internalパッケージにする?
      • internalパッケージのexportedな機能とする = テストできる
    • 別のパッケージに切り出す?

export_test.go というファイルを使うと解決する

// export_test.go
package mypkg // テスト対象と同じパッケージ
const ExportMaxValue = maxValue
// テストコード
func TestMypkg(t *testing.T) {
    if doSomething() > mypkg.ExportMaxValue { // ExportMaxValue が公開されているのでアクセスできる
        t.Error("Error")
    }
}
  • テストのときだけビルド対象にする
    • *_test.goはgo testのときだけビルドされる
  • _test.goをつけてテスト対象と同じパッケージにする
    • テストのときにしかビルドされないファイルになる
    • テスト対象パッケージのテスト用の機能になる

まとめ

  • テストは別パッケージにしましょう
  • 非公開な機能はexport_test.goが有効
    • テストにだけ一部を公開する
    • 公開する範囲がコントロールができる
    • メソッド式や型エイリアスを使いこなす

別のパッケージにすることで、
ユーザーの気持ちになってテストが書けるというのは面白いと思いました...!

@tenntenn さんには Gopher 道場でもお世話になっていますが、
スライドを流しながら、スライド外の細かい解説までして下さるので、
聞いていて本当に興味深いです...!

参考

メルペイがGopher道場をサポートする理由 #メルペイなう vol.16 #gopherdojo - mercan(メルカン)

最後に

LTいただいた方々の資料も、こちらにまとめておきます!

外部環境への依存をテストする

Tips for develoepr-friendly testing #golangtokyo - Speaker Deck

止めたいのに止められないテストの話

依存関係逆転の法則 with golang

先日書いたこちらの記事から一部抜粋したい

abemotion.hatenablog.com

今「API gatewayによるMicroservices化」プロジェクトを社内で進めている。
API gatewayには golang を採用した。

golang には、デファクトスタンダードフレームワークがまだ存在せず、
今回標準パッケージのみで開発することに決定。

レイヤ構成のベストプラクティスを調べていくうちに、
設計・デザインパターンへの理解が深まった。

フレームワークを使用しないという事は、レイヤ設計を自前で行う必要がある。

Go言語では循環参照があるとコンパイルエラーになってしまう。

今日は依存の方向性を考慮した設計について、自分の理解を残しておきたい。

大枠の設計は Lightweight DDD を採用した。

レイヤー例

interfaces層
↓
application層
↓
domain層
↓
infrastructure層

※矢印は参照の方向です。今回、大枠設計は説明の補足程度に使い、焦点をあてません。

依存関係逆転の法則(Dependency Inversion Principle : DIP)とは

上位のモジュールは下位のモジュールに依存してはならない。
どちらのモジュールも「抽象」に依存すべき
抽象は、実装の詳細に依存してはならない。
実装の詳細が抽象に依存すべきである

少しずつ噛み砕いていく。

まずはこの2文

上位のモジュールは下位のモジュールに依存してはならない。
どちらのモジュールも「抽象」に依存すべき

ここで重要なのは、
「上位のモジュールは下位のモジュールに依存してはならない」
という部分ではない。

循環参照でエラーになるからといって、
依存をなくすことは不可能。

A→Bという参照が発生する以上、
何かが何かに依存するという構図が生まれる。

ここで大切なのは、
「どちらのモジュールも抽象に依存すべき」
という部分。

モジュールではなく抽象に依存しよう。
という事。

では抽象とは具体的には何か?

その前に残りの2文

抽象は、実装の詳細に依存してはならない。
実装の詳細が抽象に依存すべきである

簡単に言うと

「抽象→実装」

ではなく

「実装→抽象」

に参照すべきという話。

まずは概念的な整理をした。

これを元に具体的な説明に入りたい。

  • what
  • how
  • why

what

まずは何をやるか。

概念だけ捉えても具体性がないと理解につながらない。

DIPで基本となるのが「抽象」だ。

「抽象」は
Go言語でいうとインターフェース(interface)にあたる。

まず前提として、
interface を用意し参照することで、
依存強度そのものを下げる必要がある。

how

次にどのようにやるか。

これはコードを見た方がわかりやすい。

type User interface {
        Save() User
}

type user struct {
        id   int
        name string
}

func NewUser(id int, name string) User {
        return &user{id, name}
}

func (u *user) Save() User {
        ...
}

まず interface を用意する。
※「まず」と書きましたが、実装の流れではなく、理解しやすい流れで書いてます。
 「抽象化を過度に先んじてやるのは悪手」とかの話とはまた別で。。。

type User interface {
        Save()
}

同じシグネチャのメソッドを実装すれば、
User interface を実装(implement)したことになる。

type user struct {
        Id   int
        Name string
}

...

func (u *user) Save() {
        ...
}

そして、user 構造体(struct)に、Save() メソッドを定義する。

この時点で user struct は User interface を implement する。

大事なのはここから

func NewUser(id int, name string) User {
        return &user{id, name}
}

NewUser() の返り値は User interface

返しているのは、user struct の実体そのものですが、
引数として保証するのは User interface かどうか。

golang は静的型付け言語なので、型情報で値の保証や制限ができる。

var u User
u = NewUser()

関数としての返り値も、NewUser() の利用側も、
User interface かを期待する。

つまりこれで実装の詳細ではなく、
interface・抽象を参照(抽象に依存)する形になる。

ここまでで「抽象への依存」の説明はできたので、 ここにDIPの「逆転」の概念を加える。

逆転とはなにか?

今までの説明で、特に逆転している所はなかった。

interfaces
↓
application
↓
domain
↓
infrastructure

矢印の方向で参照していった時に DIP を適用すると、

interfaces
↓
application
↓
domain
↑
infrastructure

最後の矢印が逆になる。
※ 適用のさせ方にもよりますが、概念的な説明のためにこうしています。

infrastructure の interface 定義を domain側で持ち、
実装コードで その interface を満たす。

一見、domain→infrastructureの方向で参照していても、
infrastructureは、domain側で定義されている interface を満たすよう要求されているので、
infrastructure → domain の方向で依存関係を保つことができる。

こうすることで、
domain 層はどの層へも依存しないよう死守する。

why

DIPをはなぜ適用するかは、
『レガシーコード改善ガイド』にも記述があったので抜粋したい

依存関係逆転の法則(Dependency Inversion Principle:DIP)
インターフェースに依存する場合、その依存は通常、とても小さく目立たないものです。
インターフェースを変更しなければ、コードを変更する必要はありません。
そして、インターフェースを変更することは、背後にある実装コードの変更に比べると、はるかに稀です。
インターフェースがあれば、そのインターフェースを使用するコードに影響を及ぼすことなく、
インターフェースの実装クラスを編集したり、新しい実装クラスを追加したりすることができます。
このような理由により、具象クラスに依存するよりも、インターフェースや抽象クラスに依存するほうが優れています。
変更の少ないものに依存することで、ある変更が巨大な再コンパイルを引き起こしてしまう可能性を小さくすることができます。

最後に

まだまだ依存性の注入(Dependency Injection : DI)の話などもありますが、
DIは、テストにおいての擬装クラス等にも関連してくるので今回は外しました。

参考

Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
依存関係逆転の原則