ugo's 読書感想文

読んだ本のまとめや学んだことを書いていきます。

フロントエンド開発のためのセキュリティ入門

概要

フロントエンドエンジニアとしてのセキュリティの知識を身に付ける必要がある。

当然、フロントエンドで発生しうるセキュリティ問題は多い。

XSSや、クリックジャッキングなど、一歩間違えば大きな問題につながる。

その手法や、対応策を知ることが重要になり、当書はその入門にはうってつけの本となっている。

別でガッツリまとめたのだが、こちらでも軽くまとめようと思う。

扱う内容

  • HSTS(HTTP Strict Transport Security)について
  • Same-Origin Policy
  • CORS
  • プリフライトリクエス
  • サイドチャネル攻撃
  • CSP(Content Security Policy)
    • Trusted Types
  • CSRF
  • クリックジャッキング
  • オープンリダイレクト
  • 認証

基本的に全ての項目でハンズオンを用意してあり、実際に自分で手を動かして脆弱性を仕込んでみたり、対策したりできたのがよかった。

ハンズオンには

バックエンドにExpressを使用し、ルーティングとミドルウェアを使用。

フロントはHTMLをそのまま使う時もあれば、ejsなどのテンプレートエンジンを使うこともあり。

各項目

HSTS

ユーザーにHTTPS通信を強制すること

mixed content

httpsの通信の中で、httpを含む通信が起こった時に、http通信が傍受され、改竄される危険性がある脆弱性

active mixed content

javascriptcssといったブラウザ上でコードが実行されるリソースに対するmixed content

Same-Origin Policy

他のWebアプリケーションからのアクセスを制限する。

制限されるリソース - JavaScriptを使ったクロスオリジンへのリクエストの送信 - JavaScriptを使ったiframe内のクロスオリジンのページへのアクセス - クロスオリジンの画像を読み込んだ要素のデータへのアクセス - Web StorageやIndexedDBに保存されたクロスオリジンのデータへのアクセス

CORS

クロスオリジンへのリクエストを可能にする仕組み

Access-Controll-Allow-Origin ヘッダを使うことで許可を行うことができる

ただし、これはレスポンスのリソースへのアクセスをJavaScriptに許可するものである。

プリフライトリクエス

副作用を伴うリクエストは安全とは言えないので、事前に送信しても問題ないかブラウザからサーバへ問い合わせを行う。

事前問い合わせのリクエストの結果をもとに、ブラウザはリクエストがサーバから許可されている内容かどうかを確認、

サーバから許可されていれば本来のリクエストを送信する。

プリフライトには OPTIONS メソッドが使われる。

リクエスト毎にプリフライトリクエストを送ると大量になるので

Access-Control-Max-Age ヘッダを使って、プリフライトリクエストを送信しない期間を設定することができる。

CORSのリクエストモード

サーバから受け取ったCORSヘッダをもとにリソースへのアクセスを行うだけでなく、

フロントエンドのJavaScriptからCORSでやりとりをするかどうかを指定することもできる。

  • cors CORSの設定がされていない or CORS違反となるリクエストが送信された時はエラーになる。 デフォルト値
  • no-cors 単純リクエストのみに制限される
  • same-origin 同一オリジンのみでやりとりを行う

サイドチャネル攻撃

コンピュータのCPUやメモリといったハードウェアの特性を悪用した攻撃のこと

XSS

Webアプリケーション内の脆弱性を利用して不正なスクリプトを実行する攻撃。

攻撃対象のページ内でJavaScriptを実行するため、同一オリジンポリシーでは防ぐ事ができない。

XSSの仕組み

攻撃者が不正なスクリプトを攻撃対象ページのHTMLに挿入して、ユーザーに不正スクリプトを実行させる。

ユーザーが入力した文字列をそのままHTMLへ挿入することで発生する脆弱性

XSSの種類

攻撃者が用意した罠から発生するリクエストに対して、不正なスクリプトを含むHTMLをサーバで組み立ててしまうことが原因で発生するXSS

リクエストに含まれるコードをレスポンスのHTML内にそのまま出力することから「反射型XSS」と呼ばれる

不正なスクリプトがリクエストの内容に含まれた時のみ発生するので、「非持続型XSS」と呼ばれる

攻撃者がフォームなどから投稿した不正なスクリプトを含むデータがサーバ上に保存され、その保存されたデータ内の不正なスクリプトがWebアプリケーションのページに反映されることで発生されるXSS

不正なスクリプトを含むデータがサーバ内へ蓄積されていくことから「蓄積型XSS」または「格納型XSS」と呼ばれる

全てのユーザーに影響が出る

「持続型XSS」とも呼ばれる

  • DOM-based XSS

JavaScriptによるDOM操作が原因で発生するXSS

サーバを介さないので攻撃を検知することが難しい

CSP

CSP(Content Security Policy)とは、XSSなど不正なコードを埋め込むインジェクション攻撃を検知して

被害の発生を防ぐためのブラウザの機能

Trusted Types

基本的にはDOM-based XSSは文字列をそのままHTMLへ反映してしまうことが原因で発生する。

innerHTMLや、script.srcの仕様を変更することで、動かなくなるwebアプリケーションもあり問題がある。

そのため、検査されていない文字列をHTMLへ挿入することを禁止する「Trusted Types」というブラウザの機能が提案された。

デフォルトでは無効にされているため、これまでのwebアプリケーションとの互換性を破壊することはない。

  • TrustedHTML
  • TrustedScript
  • TrustedScriptURL

の3つの型がある。

クリックジャッキング

ユーザーの意図しないボタンをクリックさせることで、意図しない処理を実行させる攻撃

方法としては以下のようなものがある。

  1. 攻撃対象のWebアプリケーションのページをiframeを使って罠サイト上に重ねる
  2. iframeの透明な部分にボタンを配置する
  3. ボタンをクリックさせる
  4. ユーザーは罠サイト上のボタンをクリックしたつもりで、実際は透明に重ねられた攻撃対象のページ上のボタンがクリックされる

オープンリダイレクト

Webアプリケーション内にあるリダイレクト機能を利用して、罠サイトなど攻撃者の用意したページへ強制的に遷移させる攻撃。

フィッシングサイトや悪意あるスクリプトが埋め込まれたページへリダイレクトさせられ、機密情報が盗まれるといった脅威がある。

サーバ側でリダイレクト先として利用する場合に発生するが、ブラウザでJavaScriptから画面遷移する場合はも発生する。

まとめ

この記事では細かくはまとめていないですが、実際の本ではより細かい内容や、対策の仕方、実際のコードなどが書かれていて

フロントエンドをやる上で最低限知るべきな脆弱性の紹介がありました。

JavaScriptを扱う関係上、それにまつわる対策が多いですが、ブラウザというフロントが欠かせない媒体を使っている以上、ブラウザの知識というのも必要になってきます。

フロント部分のセキュリティについての情報を追うソースなども紹介もあったりするので

フロントエンドエンジニアの方でこれからセキュリティを学んでいこうという人には良い最初の1冊になるんじゃないかと思います。

プログラマー脳

概要

プログラマーとしての考え方を学ぶ上で、どういう思考をすればいいのかなどはプログラマー歴が浅い人にとっては気になるところ。

僕自身もそれは気になっていて、プログラムを書くのは好きだけど、無闇に書いていてもよくなく

しっかりとしたプログラムを書くために身につけないといけないスキルというのを考える必要があった。

そこで、評判が非常に高かった本書を手に取る事にした。

コードをよりよく読むために

混乱タイプ

新しいコードを読んでいて混乱を招く3つの要因がある。

  1. 知識不足
  2. 情報不足
  3. 処理能力の不足

知識不足は長期記憶に関わる。

情報不足は短期記憶に関わる。

そして、ワーキングメモリに負荷がかかる。

長期記憶は、我々の行動全てに関係する。

Javaのコードを読む時は、短期記憶を使用し、変数や関数を覚えておくことができるが、

それも長期記憶からも読み解いて、短期記憶に保存しておくといったプロセスを踏んでいる。

認知プロセスの相互作用を利用し、プログラムを読み解くことを行っている。

プロセスは以下

  1. 長期記憶から情報を取得する
  2. 今向き合ってるプログラムに関する情報を保持する短期記憶
  3. コードが何をやっているかなどのワーキングメモリで、コードを判断する

コードの速読

プログラマーの仕事の60%が、読む事に時間を使っている。

人はプログラムを学ぶ時、書く事にばかり集中する。

しかし実際の仕事では、読むことの方が多い。

例えば、新機能の開発で関数の適切な配置場所はどこかなどは、読むところから始まる。

そのため、読む速度を上げることがプログラムを書くことの向上にもつながり、生産性の向上につながる。

人間の短期記憶の容量

人間の短期記憶の容量は、保持するのに30秒が限界な上に、入る容量も少ない。

そのため、変数や長期記憶にない処理が入っていると、その分短期記憶の容量を圧迫し、読むことも理解することも大変になる。

そのため、無意味な変数名や説明のない関数を作るのは避けましょうという話。

記憶のサイズ制限を克服する

チェスの例

チェスの上級者と初級者を集めて実験があった。

ある時の試合の途中の局面を両チームに短時間見せて、再現してもらうというもの。

上級者の方が多くのコマを再現することができた。

これは、上級者の中に定石などがあり、コマの意味を把握しながら覚えることができたということと、覚えなくても決まりごととして理解していたことで再現できたということ。

今度はランダムにコマを配置した局面を見せて、同じように再現してもらった結果

上級者でも初級者でも結果はほぼ変わらなかったそう。

これは、コードにも同じことが言える。

上級プログラマーが同じコードを見たときと、初級者が見た時とでは頭で処理する量が異なるということになる。

その結果、上級プログラマーには例えばデザインパターンなどが頭に入っていることによって、短期記憶の容量を超えず、無理なく短いスパンで再現することができるということになる。

このように長期記憶の量を増やすことで短期記憶しておく容量をセーブし、より少ないワーキングメモリーでコードを読むことが可能になる。

コメント

また、人はコードを読む時、コードがある時とない時とで集中力やコードの読み方に変化がある。

もちろん、コメントに関数の概要が書いてあればそれだけで理解できるだろうし、コードがあると、意外と人はコメントを読むということをしているそう。

そして、ビーコンを立てることが重要。

上記の再現実験を自分で行う時、自分が詰まったところにビーコンを立てて行うことで、自分に必要なもの、自分が短期記憶しなくてはいけないところが明確になり、より対処をしやすくなるというもの。

言語の関数を覚えるのが難しい理由と覚える必要がある理由

割り込み

プログラマーがプログラムを書いてる途中に、メールや別の調べ物で気が取られることがある。

調査によるとその作業からプログラムを書く作業に戻るのにほとんどの場合、15分以上が経っていて、再開した時には自分が何をしていたかを思い出す作業から始まる。

その時、文法を覚えているかどうかだけで思い出す時の労力が著しく異なる。

文法の覚え方

フラッシュカードを複数人で作る。(自分だけがこの問題に直面しているわけではないというのを知るため)

フラッシュカードを最短時間を何日もかけて覚える。

期間を空けて復習することが有効。

期間が短いグループと長い期間を空けたチームとでは、長く空けたチームの方が定着率は高かったそう。

記憶定着させるテクニック

  • 想起練習
  • 推敲

貯蔵強度と検索強度という二つのメカニズムがある。

貯蔵強度とは

特定の何かが長期記憶にどれだけきちんと保持されているかを示している。

九九の掛け算なんかは忘れることができないレベルまで定着しているもの。

検索強度とは

特定の何かを思い出すのがいかに簡単かを示している。

知っているはずなのに、なかなか思い出せないもの。

電話番号や、名前など。

つまり、

長期記憶に保持するだけではなく、簡単に取り出せるようにする必要がある。

そのためには、毎回関数を調べていたのでは、脳はその関数を覚える必要がないと認識する。

そうすると悪循環がうまれ、毎回調べることで向上することがない。

意識的に覚えることが大事になる。

精緻化

学んだばかりのことについて考えるプロセスのこと

スキーマ

脳の記憶は、他の記憶や事実との関係性を持ったネットワークを形成した形で保存される。

この関係を頭の中で整理したものがスキーマと呼ばれる。

既存スキーマを新しい記憶と結びつけることで長期記憶に適合させる方法。

記憶を長く保つためのコツのまとめ

  1. プログラミングの文法を覚える
  2. フラッシュカードを使う
  3. 定期的に練習する
  4. 調べる前に頭の中の記憶検索を行う練習をする
  5. 時間(期間)をかけて練習する
  6. 精緻化を行う

複雑なコードの読み方

認知負荷

・課題内在性負荷 ・課題外在性負荷 ・学習関連負荷

課題内在性負荷

問題そのものに難しくさせる要因が入っている状態

三角形の2辺の長さが分かってて、残り1辺を求めるような問題は

どのようにしてもそれ以上簡略化することができない。

このような問題のことを、「固有複雑性」ともいう。

課題外在性負荷

先ほどの三角形について

2辺の長さが a=8, b=6 のように別に定義されている場合など

その数値を辺の長さと繋ぎ合わせる必要がある。

そのような問題には、短期記憶を使う必要があり、問題が必要以上に難しくなる。

このようなことを課題外在性負荷という。

リファクタリング

リファクタリングをするのは、コードを共通化したりする時に行うが

通化することで参照先が増え、読む時により負荷の高いものになる、逆リファクタになる可能性がある。

しかし、それでもその時の読み手のためにリファクタをして読みやすくするということをすることをしてもよい。

例えばバージョン管理で、ブランチを切って、自分が理解しやすいようにリファクタをすることはコードを理解することの助けになる。

認知度を下げる

コードの中のつながりを可視化することで頭に留めておく時間や労力を下げるということを行う。

具体的には、同じ変数同士や、使っている関数を線で繋ぐなどをすることで、俯瞰してコードを見ることで一つ一つの認知度を下げるというもの。

そして、その変数がどのように変化するかなどの、状態遷移表を書くとよりコードの理解が深まるものだ。

ワーキングメモリーの負荷をいかに減らすかというところで、サポートしてくれるアプリがある。

PythonTutor は上記のような変数を丸で囲ったり、共通部分を線で繋ぐなどを視覚的に行ってくれ、訓練を行うことができるアプリである。

変数が持つ役割

変数をカバーできる11の役割がある。

  • 固定値 その名の通り、変化しない変数のこと。 定数として扱うことができる。

  • ステッパー ループ処理を行う時に、ループのたびに値が変更される変数

for文などで使われる i のような変数のこと

  • フラグ 何かが発生したことを示したり、何かの情報が含まれていることを表す変数。

is_setやis_available、is_errorなど。

  • ウォーカー ループ処理を開始する前には、どのように走査を行うのかが未知のケースで利用されます。

プログラミング言語の仕様によって、ウォーカーは、ポインタ変数であったり、整数のインデックスであったりします。

  • 直近の値の保持者 一連の値を純に処理していく際に、もっとも最新の値を保持する変数のこと。

配列要素のコピーなど(element = list[i] のような)

  • 最も重要な値の保持者 ある特定の値を探すために、値の一覧に対して反復処理を行うが、その過程で重要な値を保持するための変数のこと。

最小値や最大値、特定の条件を満たす最初の変数など。

  • 収集者 データを集めて、1つの変数に集約させているときの変数

配列の数値を足していく、最後のsumのような変数のこと。

  • コンテナ 複数の要素を内包し、追加や削除が可能なデータ構造のこと。

リストや、配列、スタック、ツリーなど。

  • フォロワー 前の値や、次の値を保持して参照するための変数。

常に他の変数とセットで使われる。

  • オーガナイザー 処理を進めるために変数を何らかの方法で変換する。

例えば、リストを並べ直して保存したい時など。

その時に形式を揃えるために使われる変数のこと。

  • テンポラリ 短期間だけ使われる変数。 tempやtなどがその代表例。

ハンガリアン記法

型がない場合に、名前自体に型の命名を含める記法。 strNameなど。

モデル

モデルとは、現実の具体を抽象化してコードに落とし込んだもの。

コードのモデルとは、バーで飲んでる際にコースターの裏に書いたような計算式もモデルと呼べる。

しかし、全てのモデルが便利というわけではない。

例えば、言語ごとに得意とする領域が異なる場合がある。

Pythonだと機械学習に関するライブラリが豊富であったりと、物事に対するモデルの最善手というのは異なる。

メンタルモデル

実際に手を動かすわけではなく、頭の中で考え、利用するモデルのこと。

これは、結構日常的に考えてるものである。

例えば、パソコンを開いて、IDEを立ち上げ、コードを開く時、パソコンの中ではバイナリという実行ファイルを開いているだけで、もっと細かく見れば、0と1を実行しているだけにすぎないのだが、人間の頭の中にはどこにどのファイルがあって、どれを開こうというファイル構造が存在している。

このように、自分の頭の中で抽象化されているものをメンタルモデルという。

しかし、これには欠点も多い。

メンタルモデルは、対象のシステムを完全に表現しているわけではないので、かなり不完全なものが混じることになる。

また変化も多く、常に同じということはない。

脳の労力を多く使うため、人は頭脳労働ではなく、デバッグなどもコードを微調整し実行することを繰り返すような筋肉で解決することに走ることもある。

想定マシン

実際のコンピュータがどのように機能するかを抽象化したもの。

プログラミングの概念を説明したり、プログラミングについて理解を深める際に利用される。

スキーマの重要性

変数を「箱」と表現することは多くの人にとって認知負荷は低い。

しかし、変数を「一輪車」と喩えた時、多くの人は一輪車で何ができるかなどを考える必要があり、認知負荷が高くなる。

つまり、人々にとってどれだけ慣れ親しんだものであるかというインターフェースが重要になるのである。

二つ目のプログラミング言語を学ぶことは一つ目より簡単

転移といわれる、すでに知っていることが新しいことを知ることに役立つ作用によるもの。

以下が大きく影響を与えるもの。

  • 習熟度
  • 類似度
  • コンテキスト
    • 二つのタスクの環境がどれだけ似ているか(IDEなどの環境が例)
  • 重要な性質に関する知識
  • 関連性
  • 感情
    • タスクに対してどのような感情を持つか。二分木を使った処理を調べるのが楽しかったと感じるとして、新しいタスクに対しても楽しいという記憶が蘇ることがある。

デメリット

すでにある知識が、新しいものを学ぶ時に弊害になる時がある。

例えば、Javaのチェック例外などは、Java特有の言語機能なので

C#などを学ぶ際には邪魔になってしまう。

概念変化

すでにある知識を新しい知識を学ぶ際にリセットし、概念理解を改変させる必要がある。

これにはただ、説明を受けただけでは書き変わらない。

長期記憶にある、すでにある知識を変化させるのは、一体化したものを分解する必要があるので通常の学習より大変になる。

以下のようなデメリットも存在する。

例えば

雪だるまにセーターを着せるとどうなるかという質問に対し

人々の持つ、「セーターを着ると暖かい」という印象があるということを考えると

雪だるまにセーターを着せると溶けてしまうという発想になるが

セーターの性能は、「その温度を内部で留める」というものであるため

雪だるまにセーターを着せても、溶けにくくなるということになる。

このように概念変化とは、新たな概念に対して、既知の概念が入ることで誤認識を正していく必要がある。

防ぎ方

プログラミングにおける防ぎ方として

自分が正しいと確信していることでも、間違っている可能性があると認識することが大事。

また誤認識に陥らないように常に意識して勉強しておく。

誤認識をまとめたチェックリストを使うのが良い。

そして、同じプログラミング言語を使っている人からアドバイスをもらうことで、誤認識を防ぐことができる。

これには、モブプロなどを行うことで、お互いの認識を合わせることができるのでとても有効。

また、誤認識があった場合は、テストを追加するだけでなく、同じ過ちを繰り返さないようにドキュメントを残しておくのが重要。

ルール

命名のルールを決めることが重要

ルールを決めることで、命名の一貫性を保つことができる。

初期の命名の慣習は永続的な影響を与える。

この場合、Camel Caseでの命名GitHubでも一番多く、そして一番多くの人に受け入れられている。

しかし、プログラマーではない人も含めた結果ではCamel Caseでは精度は高まるが、認識に少し時間がかかることが分かった。

プログラマーのみの場合は、認識する速度はむしろ上がったので、Camel Caseが良いと言える。

三つのステップモデル

  • 名前にどんな概念を使うか
  • その概念にどんな単語を使うか
  • それらをどう組み合わせるか

を適用することでより品質の高い名前をつけることができる

コードの臭い

リファクタが必要そうなコードに対して臭うことがある。

どのような時に感じるかというと

  • 長すぎるメソッド
  • 長すぎるパラメータリスト
  • switch文
  • 巨大なクラス
  • 怠け者クラス
  • 不適切な関係
  • 重複したコード etc...

が挙げられる。

言語的アンチパターン

  • メソッド名に書かれた以上の働きをするメソッド
  • 実際の働き以上のことをするかのごときメソッド名
  • メソッド名に書かれたのと真逆のことをするメソッド
  • 実際に格納されているよりも多くのものが含まれているかのごとき識別子名
  • 実際に格納されているよりも含まれているものが少ないかのごとき識別子名
  • 実際に格納されているものと真逆な識別子名

2種類の記憶

  • 手続き記憶(潜在記憶)

意識をせずに行うことができる記憶。

自転車の乗り方などがあげられる。

記憶したことを近くしている記憶のこと

forループの書き方などがあげられる。

アンラーニング

何かの知識が他のことを学ぶ上で障害になりうるということに繋がる。

顕在記憶を多く持っている場合、柔軟性が損なわれる可能性がある。

キーボードの操作などがそれにあたる。

時間経過と潜在記憶

プログラミングのための潜在記憶が多ければ多いほど、認知的負荷に余裕ができるので、大きな問題を解くことが簡単になる。

そのためには前述したフラッシュカードの手法などを使って、認知的負荷が下がるように覚えることも大事。

  • 認知的段階

新しい情報は、より小さな部分に分割する必要があり、目の前のタスクについて説明的に考えなければならないフェーズ

  • 連合的段階

パターンに反応できるようにまでに、新しいコードを対象として繰り返し作業する必要がある。

インデックスが0から始まることに慣れた人は、次第に欲しい要素の数から-1をすれば良いことに気づくなど

  • 自律的段階

潜在記憶になる。

自動化されたスキルといえる。

この潜在記憶と化したスキルを増やすことで問題解決に繋げることができる。

問題解決

問題解決にはしばしば、考えるという作業が重要と言われる。

それは当然なのだが、何もないところから考えてもうまく進まないのである。

ある研究によると

模範解答を渡されたグループと、渡されないグループで同じ問題を解き

また別の問題をどちらのグループにも模範解答を渡さずにやらせた結果、模範解答を得たグループの方が成績が良かったとある。

つまり、問題を解く際にワーキングメモリの使用率によって、問題の解決力が変わってくるのである。

プログラミングを書くこと

プログラミング中の活動

  • 検索
  • 理解
  • 転写
  • 増強
  • 探索

探索

コード内を調べ、特定の情報を探す作業のこと。

バグの正確な位置、特定のメソッドが呼び出される全ての箇所、変数が初期化される位置

この時、コメントなどを使って、探索の助けになるようにすることが大事。

理解

コードを読むところは検索と一緒だが、コードを実際実行し、リファクタリングも兼ねている。

このリファクタを通してコードの全体を理解したり関係性を知ることができる。

転写

単にコードを書くという活動

増強

検索と理解、転写をすべて組み合わせたもの。

機能の追加などでコードを追加することを指す。

検索

増強の作業と同様に、コードを書き、実行し、正しい方向に進んでいるかどうかを確認するためにテストを実行する。

その場その場で計画や設計を行うため、特にワーキングメモリに負担がかかる。

割り込みについて

プログラムを書いてる途中の割り込みについて

コードを書くのを中断された後に、同じ作業に戻るまで25分かかってしまうことが多い研究がある。

1分以内に作業を再開できたケースは、調査した全体のうちのたった10%だった。

しかし、割り込みが全くない状態でコードを書くのはなかなか実務の中では難しい。

そうした時に取る行動として

  • ロードブロックリマインダ

というものがある。

作業の途中で続きをやるのを忘れてしまわないように

わざとコンパイルエラーが出るようにしておいて、何をやっていたのかを確実に思い出せるようにしておくこと。

割り込みがある場合、都合の良いタイミング、つまりゾーンと呼ばれる時を避けるべきで、その状況を周囲に知らせることが重要になる。

例えばSlackのアイコンに集中のアイコンをつけるや、timesなどに今から1時間集中しますといったことを投げておくと良さそう。

基本的に人はマルチタスクはできないが、先ほどの自動化が多くなされた作業においてはマルチタスクをしても負担は大きくない。

なので、自分が今取り組んでいるタスクがどのようなものなのかを把握しておき、どれほど集中しなければいけないかを知っておく必要がある。

大きなシステムの設計と改善

ライブラリやフレームワーク、モジュールは他のプログラマーが変更はしないものの頻繁に利用するコードでよくあることとして

どのように構築しているのか、プログラムが理解しやすい形で書かれているかに関係している。

どんな言語でライブラリが作られているかなど。

コードを認知的側面から調査する方法をCDNと呼ぶ。

CDN

「このコードは他の人が変更が容易か」や、「このコードは他の人が内部の情報を見つけ易いか」といった質問に答える助けとなるもの。

元々、フローチャートなどの可視化の手法のために作られたもの。

思考やアイディアを表現するための表記法。

大規模なコードベースのユーザビリティを評価するために使用できる。

プログラミング言語が、その言語で書かれたコードが利用者にどのような認知的影響を与えるかをプログラマーが予測できるようにするためのフレームワーク

CDCB

CDNをどのように活用するかについて。CDNの拡張。

プログラマーが、自分のコードベース、ライブラリ、フレームワークが利用者に与える影響を理解するのを助けるフレームワーク

エラーの発生のしやすさ

Pythonは、Cほど強力な型システムがないので、エラーが検出しづらい。

JavaScriptのような動的型付け言語も、変数が生成される時に、特定の方で初期化されることがない。

それによるエラーの原因が生まれる。

一貫性

命名一つとっても、関数を作る際にそれが組み込み関数と同じ名前であれば

組み込まれているものなのか、誰かが作ったものなのかの判断がつかなかったりする。

命名規約が定まっていないことにより、フレームワークなどを使っていてもそれが認知負荷を引き起こす可能性がある。

拡散性

メソッドを必要以上に複雑にしたり、多くの機能を盛り込んでしまうことによって、メソッド名が長くなる。

プログラミングにおける、構成要素が多くなってしまい、どれほどの多くの記述や長さを必要とするかを表すものを拡散性という。

ワンラインで書くと一行で書けるが、とても読みづらいものになってしまうということが顕著。

暫定性

コードを書く前に構想を作っても、実際書き始めるとエラーが出たり、型の不一致などでなかなか進まないなどがあり、部分部分に集中せざるをえないことになる。

型というのはバグのないコードを書く上では便利だが、試行錯誤している最中は邪魔になってしまう。

このような状態を暫定性が低い状態と表現する。

粘性

既存のコードの変更がいかに難しいかを表す。

動的型付け言語で書かれたコードは、静的型付けに比べて変更が容易。

こういう状況は、粘性が低いと言える。

また、テストやコンパイルといった影響で実行に時間がかかったりする状況がある。

こういう状況は、粘性が高いと言える。

段階的評価

暫定制に関連している。

与えられたシステムにおいて、部分的な作業をチェックしたり実行したりすることがどれだけ簡単なのかを意味する。

シニアエンジニアとジュニアエンジニアの違い

シニアエンジニアは、チャンクで把握することができる。

エラーメッセージ、テスト、問題、解決策などのコードに関する知識にも対応できる。

しかし、ジュニアとシニアの間は二段階しかないのか?

実は、四つの段階に分けることができる。

  • 感覚運動期 - 計画や戦略は立てることができず、ただ感覚に基づいて動くことしかできない
  • 前操作期 - 仮説や計画を立て始めるが、それを確実に思考に活かすことはできない
  • 具体的操作期 - 目に見える具体的なものについては仮説を立てられるようになるが、一般的な結論を出すのはまだ難しい
  • 形式的操作期 - 形式的な推論をすることができるようになる

実際のプログラマーの行動

感覚運動期

プログラムの実行について、全く正しくない理解しか持たない。この段階では、プログラマーはプログラムを正しく読み、追いかけることはできない

前操作期

トレース表を作成するなどして、複数行のコードの結果を手作業で確実に予測することができるようになる。

前操作期のプログラマーは、コード全体ではなく、一部のコードについてどんな処理をしているかを推測することが多い

この期間が、一番プログラマーのフラストレーションがたまる段階。

コードの深い意味を理解することが難しく、推測で物事を進めがち。

そのせいで、一貫性がないように見えてしまう。

教える側からすると、「このプログラマーは頭がよくない」とか「やる気がない」と見えてしまい、イライラしてしまう。

具体的操作期

前操作期的な帰納的アプローチではなく、コードそのものを読んで、演繹的にコードについて理由づけを行うことができる

全てのコードをトレースしなくても、コードに対して推論をすることが可能になる。

コメントや識別子の名前を調べ、必要なときだけコードのトレースを行う。

形式的操作期

論理的で一貫性のある、体型的な推論ができる。

形式的操作的な推論には自分の行動を振り返ることも含まれ、これはデバッグには不可欠である。

コードと、自分自身の振る舞いについて、適切な意思決定ができる経験豊富なプログラマーであり、オンボーディングはほとんど必要ない。

新しいことを学ぶと一時的に物事を忘れてしまう

新しいプログラミングの概念を学んだり、初めて扱うコードベースを調べる際、プログラマーは一時的に低い段階に戻ることがある。

Pythonの経験があり、全ての関数を追いかけなくても読み解くことができるプログラマーだとしても、*argsを使った可変長低数の概念になじみがなければ、スムーズに読み解けるようになるまでに、いくつかの関数の呼び出され方を調べ、確認する必要がある。

初心者が学ぶプロセス

意味波に従うと言われている。

一般的な概念をまず理解し、何のために使われるのか、なぜ知る必要があるかを知ることから始まる。

最後に、具体的な内容から離れて抽象的なレベルまで戻り、概念が一般的にどのように機能するかを知り、腹落ちする必要がある。

これをリパッキングという。

アンチパターン

ハイフラットライン

初心者が抽象的な概念しか理解していない状態に起こる。

いかに便利かを知っていても、実際の構文を知らなければまだまだ学ぶことは多い。

ローフラットライン

熟練者が教える際に、なぜ必要なのか、どう便利なのかを説明せずに、具体的な情報を大量に与えてしまうこと。

下降専用エレベーター

熟練者が教える時に、なぜ重要かとどう扱うかを教えたとしても、その後のリパッキング、つまり新しい知識を長期記憶に統合するチャンスを与えなかった時に起こる。

新しい概念と、過去に知っている知識の間の共通点を明確に質問として尋ねることなどで後押しすることができる。

メタ思考トレーニング

概要

仕事をしている中で、ミーティングの会話の中で誰かの発言に対して、俯瞰的に見る事ができないことに気づいた。

1個1個をゆっくり説明されて1個1個を理解していけば、把握できるものの

パラパラと説明されて、それを自分の中で消化した上で、自分の意見を言うということが難しかった。

そのために、自分の理解に抽象度を含めることで自分の意見への変換ができるのではないかと考えたところからこの本を読みはじめました。

この本に関連して具体と抽象も読んでみようと思っています。

メタ思考とは

自らの視点を一つあげて、自らが思考に関してある壁に閉じ込められた「囚われの身」になっていることに気づくこと。

自分がいかにバイアスがかかった状態で思考を行なっているかを知るところから始まる。

そのために、自分の見えてる世界と、他人が見えている世界は異なるということをまずは認識する必要がある。

基本的に人は、自分の世界にどっぷり浸かった状態で自分自身をみているので、自分のことが見えていない。

例えば、「他人の悪口をネットで言ってるやつは許せない」とネットで悪口を言ってるなど。

こういった自己矛盾を抱える傾向があるので、一つ上からの視点で客観的に見ることが必要になる。

そうすることで、

無知の無知

自分がそれに気づいていないということに気づいていないということが無知の無知となる。

そしてそれが最大の問題点なのである。

この状況は、自分の価値観と反する事象に遭遇した時に、「相手がおかしい」と思うのではなく、「何か自分が理解できない世界がある」と受け入れることが大事。

LINEで病欠の連絡をすることに対する考え方の違いなどが当てはまる。

そのものについて考える

メールでの病欠の連絡が非常識かどうかは、時代の変化によって起こりうること。

つまり、電話->メール->LINE などと変化しただけで、

根本的には連絡することが問題なはずなのに、このように手段によって議論を生み出してしまうのは

自分の中で凝り固まった思考があったということに気づくことが重要。

メタのレベルで考える

メタの視点で考えるというのは、三段階に分けられる。

上記で記したものが第一段階となる。

  1. 準備編
    1. 自分を客観視する
    2. 無知の知
    3. 「○○そのもの(メタという言葉自体の定義)を考える」
  2. Why型思考
    1. 上位目的を考える
  3. アナロジー思考
    1. 抽象化する

Why型思考、アナロジー思考については後述する。

Why思考型

よく仕事とかでも、なぜ?を繰り返すことで本当の価値や答えを引き出すということを言われる。

その方法を具体的にやってみる。

例えば、上司に「○○について調べて報告してほしい」と言われる。

この時のアクションとして

  1. インターネットで検索する
  2. 社内で詳しそうな人に聞いてみる
  3. 関連書籍を買う

などのアクションがある。

しかし、その命令の真意を見つければ、手段は変わってくるかもしれない。

なぜ、それについて調べる必要があるのか?

という質問を自分に投げかける。

その結果を何に使うのかなどの疑問が浮かぶと思う。

そうすると、そもそもの目的を確認するという選択肢も上記のアクションに追加される。

これは、思考性の具体性、実効重視のHow志向と、目的重視のWhy志向かによって変わってくる。

問題を俯瞰的にみられるようにすることが、一つ上から考えるということ。

5W1Hの中で、Whyだけが具体化のための疑問詞になります。

問題の所在を知るには、この疑問視を使う必要があるということ。

定義し直し

先ほどの命令に戻ります。

この目的がどういう意図があったのかを知る事ができれば

もしかすると別のアプローチを取る事ができるかもしれないと考えられる。

つまり、目的の定義を変えてしまうのである。

「近くのマクドナルドを探して」と言われた時に、本当の真意は「バーガーが食べたい」というだけだったなら、「近くのバーガーキング」でも「近くのモスバーガー」でもいいので、もしかするとマクドナルドより近いかもしれない。

そのように、定義を変えてしまうことで、自分の行動を最小限に最大の成果をあげることができる。

例え、「マクドナルドのバーガー」という絞られた真意だったとしても、行動に優先順位がつけられる。

店を探すより、Uberなどで頼んだ方が早いとか、行く手間が省けるなどを考慮することも可能になるだろう。

これによって、どの土俵で勝負するかといったことがメタ思考になる。

戦略と戦術で

戦略は、どの土俵で戦うかに焦点を当てる

戦術は、いかに自分の得意な領域に勝負を持ち込むのかというところに焦点を当てる

これを問題解決に利用する。

Whyは時間を超える

因果関係を知る手段なので、現在と過去、現在と未来をつなぐ時間を超えた手段ということ。

Whyだけが次元が異なるということになる。

注意点

2つ弱点がある。

  1. 一度立ち止まって考えなくてはならないという点で、時間がかかるという点

  2. なぜ?という問いは人に対して不快な気持ちを抱かせる可能性があるという点

人は、他者を一般化したがるが、自分だけは特殊化してしまう傾向がある。

それによって、視野が狭くなってしまう傾向がある。

これは、物事を具体的なレベルでしか見る事ができておらず、抽象化してメタの視点で見ることができないことが原因。

もう一つは、新しい活動に反対したいとか、変化を嫌うことによるもの。

組織の活力

手段の目的化の発見

上記のようにWhy?を突き詰めることをしなくなった人が増えてきた職場では、思考停止状態になってしまう。

その結果、習慣化してしまい、繰り返すことに疑問を抱かない状態が生まれ、定例会議やルーチンワークが増えていくということが考えられます。

会議はビジネスの場では必須なことではあるが、手段の目的化によって、会議を開く事が目的になってしまって、非効率な会議が開かれるということになってしまう。

目的から見る競合

吉野家の牛丼を食べる人は、「松屋」か「すき家」かなどと考えているかどうか

ビジネスマンのランチタイムであれば、素早く食べれるところを考えてるところの可能性が高い。

そうなると、ライバルになるのは「立ち食いそば」や「カウンター席のみのカレー」などがある。

目的によって競合は変わってくる。

メタの視点で考えることで、同じものを扱うものだけがライバルではなく、その1つ上の視点で見ることで、ライバルの視野を広げることができる。

whyを突き詰めることで上流での戦いを行うことができるのである。

例えば、コンペで負けた時に、「他社と比較した結果、値段が安い方を選んだ」と言われてしまったら

値段が高かったから という言い訳をしがちだが、ここで値段のせいと言ってしまうことは思考を止めることと同意。

もう一つ上流の考え方を持って対策をとれば、次のコンペの時は別の手段が生まれて、値段以外のところで対抗できるかもしれない。

そういった思考停止に陥らずに、whyを突き詰めることが大事になる。

これは、忙しいから という言い訳も同様である。

言葉通りの受け取り方ではダメ

現場の人が「これだから現場を知らない人は困る」という言葉を聞いたことがあると思う。

この時、じゃ現場を改善するために、現場の人の声を全て反映すれば良くなるかというとそうではない。

それどころか、突然変えたりしたら「なんでいきなり変えたの?」というようになってしまう。

これは本社と現場、部下と上司、営業担当とお客様との関係で大いに発生する問題だと思う。

物事を具体的なレベルで見ることができず、抽象化してメタの視点で見ることができないことが原因。

もしくは、新しい活動に反対したいとか、変化を嫌っているだけという仮説もある。

人は、自分を特殊と思い込みたく、世間を一般化したいという思想を根本的に持っているため。

解決するために

常に習慣化してしまった行動に対して目的を問うていく姿勢が大事になる。

定例会やルーチンワークが増えてきた時に、本当に必要かどうか問いていくという必要がある。

どういったものがあるか

  1. 調査
  2. 分析
  3. 調整
  4. レビュー
  5. 管理
  6. システム導入
  7. 統合
  8. 見える化

アナロジー思考

アナロジーとは?

類推のこと

類似のものから類推すること。

パクリとアナロジーの違いについて見ていく。

パクリ

抽象度の低い、つまり具体的なレベルでの真似。

具体的なものとは、直接目に見えるもの。

つまり、形に表れているもの

アナロジー

目に見えない類似性や、関係性や構造のレベルで類似性を用いるもの。

アナロジー思考の基本は抽象化の考え。

アナロジーのプロセスは、「抽象化」と「具体化」の組み合わせによって成り立つ。

抽象度が上がれば上がるほど、汎用性が上がる。

そのため、遠くの世界が一緒に見えてくる。

アナロジーの重要性

アナロジーは不連続な発想を生み出すことができる。

論理思考とは対をなすもので、一貫性や連続性、つまり飛躍がないこととは反対のものであることを指す。

飛躍を起こすためのものである。

ビジネスの場でいえば、

一つには、期限が短くなっている昨今の状況により、過去の経験やデータを参考に方向性を決めるのでは合わなくなっているので、アナロジー思考は重要になる。

例えば、オンデマンドマッチングモデルや、シェアモデル、サブスクリプションモデルといったものがある戦略オプションの中ではアナロジー思考にする必要がある。

二つには、さらに新しい概念を理解する力が求められる。

たとえ話の力が重要になってくる。例えば、Fintechなどのような抽象度の高い概念に対して。

三つ目には、二つ目にもある複雑な事象を他者に簡単に説明するということになります。

アナロジーの弱点

アナロジーは、ぶっ飛んだ発想が大事で、仮説を立てる時に役立たせることができる。

しかし、いわゆる荒っぽく、大雑把な議論になりがちであるところが弱点になる。

ざっくりと理解したり、大きな方向性を考えたり、仮説を考えるのに向いてる思考法である。

関係性の類似

物事の比例を行うことでその関係性と類似のものを想定することができる。

AがBに変化する という関係性を CがDに変化する に当てはめることができる。

例えば

兄:弟 = 姉:妹

のような関係である。

二者間のみということで基本形ではあるが、複雑な関係性=構造というのも、つきつめると単純な関係性の組み合わせになっているということ。

IQテストにも同じようなものがあり、図形の関係性が同じものを当てるという問題もある。

ハエ取り草から学ぶ

ハエ取り草は、ハエが入ってくると閉じて捕獲する。

しかし、ハエ取り草は植物なため、自身を動かすだけでもかなりの労力を要する。

つまり、ハエを検知して間違えた場合、労力の消費が無駄になってしまうことが大きい。

このことから

  • 非常に重要でありながら、「誤作動」が許されない
  • しかも身長すぎては大事な機会を逸してしまう

という特徴を持つ。

1回目の検知ではハエ取り草は閉じない。

2回目の検知で閉じる。

その習性を応用し、火災検査地の作動などがあげられる。

職業別共通点

経理業務とスポーツ審判の仕事上の共通点

それは、両方とも人間相手の仕事というのもあるが

間違えなくて当たり前

ちゃんとやってもほめられることがなく、目立つときは失敗したとき

という点。

このような抽象化された切り口で見ると、一見異なる職業でも類似性があることが分かる。

まとめ

メタ思考について

  • why思考
  • アナロジー思考

について多くの練習台が多く用意されている本でした。

これをすることで、相手の意図を汲み取り、そのまんま行動人にならないように気を付けることができます。

それは最終的に仕事のやりかた、仕事上での動き方にも影響が大きく関わってくるため、上流思考ができることで

自分の評価なども変わることでしょう。

自分もよく、いろんなことを英語の学習や、プログラムの学習に例えて考えることが多いです。

このプログラミング言語ではこう書くけど、こっちではこう書くなど、関連性を持って見ることで新しい閃きも生まれる時があります。

言葉だけを受け取るのではなく、その真意を考える癖をつかせるといいかもしれません。

読みやすいコードのガイドライン

概要

今回こちらの本を読みました。

内容的には、コードの保守性や、可読性を高めることによって、開発スピードを上げようということを発信しています。

そのための手法はどのようにしたらよいかというのをKotlinを利用して実際のコードを書いて説明しています。

生産性について

コードを綺麗に書くこととハッキーな形で書く事について

綺麗に書くことのメリット

エンジニアは作業の多くを「コードを読む」ことに費やす。

そのため、読む負担というのを下げる必要がある。

単純に難読なコードは少しの改修でも時間がかかったりなどで負債としての影響は大きい。

ハッキーな書き方をする

上記理由につき、ハッキーになればなるほど読みにくくはなるが、反面実装スピードは早くなる。

これを天秤にかけた時、今はスピードを優先するかというのを考える必要がある。

注意しないといけない点として、ハッキーな方は実装は汚いが早いという点で、

エンジニア以外からは見えないところで手を抜いているのに、見えてる部分だけで評価されやすい

という点。

そういう場面もあるだろうが、基本的には綺麗なコードを書くことで全体の生産性を上げることも評価されるべきであるのに対し、実際はリファクタを重ねることで実装が遅くなったりすることで評価が適切にされないなどの難点がある。

綺麗なコードとは

では、綺麗なコードとはどんなものなのか。

  1. 意図が通じやすい明確なコード
  2. 独立性の高いコード
  3. 構造化されたコード

に対して注意を払う必要がある。

そのために、以下のことを行うと良い。

ボーイスカウトルール

「コードを見つけた時よりも良い状態にしておく」ということ。

  1. コードのリファクタリング
  2. コメントの追加や更新
  3. 不要なコードの削除
  4. テストの改善

YAGNI

「将来必要になるかもしれない」という理由で、現時点では必要のない機能やコードを追加しないという考え方

  1. 複雑さの低減
  2. 開発時間の節約
  3. 変更への柔軟性

KISS

Keep It Simple, Stupid原則

複雑さを避け、理解しやすく効率的な設計を実現すること

  1. モジュール化や関数の分割
  2. コードのリファクタリング
  3. クリアな命名規則

単一責任の原則

各クラスやモジュールが一つの責任を持つべきだという考え方。

早計な最適化を控える

97%の最適化は無駄だと戒めている。

コードを複雑にして最適化を行うくらいなら行わない方が良いという考え。

命名

命名にも、責任の範囲を限定したものにすることが必要。

  1. 曖昧性の少ない単語を選ぶ
  2. 紛らわしい略語を避ける
  3. 単位や実態を記すごくを追加する
  4. 肯定的な単語を用いる

曖昧な単語

  • flag
  • check
  • old

コメント

2種類存在する。

ドキュメンテーション

宣言や定義に対してある決まった書式で書くコメント。

これを書く事により、IDEによってはクイックヒントが表示される。

アンチパターンとして

  1. 自動生成されたドキュメンテーションを放置する
  2. 宣言と同じ内容を繰り返す
  3. コードを自然言語に翻訳する
  4. 概要を書かない
  5. 実装の詳細に言及する
  6. コードを使う側に言及する

非形式的なコメント

コードを読む際に補助をするためのコメント

コードのまとまりにコメントを追加する。

function ...() {
  // ここにコメントを書く
  if (messageModel == null) {
    ...
  }
}

状態

直交と非直交

2つの変数について、それぞれの値の取りうる範囲(変域)がもう一方の値に影響されない場合、それらの変数は互いに直交の関係にある。

コインの例を出すと

所持しているコインが1枚の時に、画面に1 coinと表示される。

2枚上の時に、画面に2 coinsと表示されるという要件の場合

コインの枚数と、表示する文字が別々で関数に渡されたりすると

10 coin といった表示になる可能性もある。

このように変数の関係によって片方に影響が与えられる状態のことを直交という。

片方の変数が決まることで、もう片方の変数も確定する場合、「従属」するという表現になる。

直和型

直交でも、従属でもない関係に対して使われる。

直和型とは、いくつかの型をまとめ、そのどれかひとつの値を持つような型のこと

列挙型

3つ以上の状態が存在し、出し分ける必要がある時は、列挙型を使う。

関数

関数の名前や仮引数、戻り値の型などの情報によって、関数の中身を読まなくても理解できるようになる。

  • コメントなどで処理の要約を書く。
  • コマンドクエリ分離の原則 (command-query separation, CQS)
  • 定義指向プログラミング
  • 早期リターン
  • 操作対象による分割

コマンドクエリ分離の原則

オブジェクトの振る舞いをコマンド(状態を変更する操作)とクエリ(状態を参照する操作)に分離すること

メソッドや関数を設計する際に、状態を変更する操作(コマンド)と状態を参照する操作(クエリ)を明確に分離する。 クエリ操作では、オブジェクトの状態を変更しないことを保証し、副作用が発生しないようにする。 コマンド操作では、状態の変更のみを行い、値を返さないようにする。ただし、例外的なケースやエラー処理のために値を返すことが適切な場合もある。

コマンドクエリを適用するかどうかは、

返り値が関数の主となる結果か、それとも副次的な結果(メタデータ)かを確認するとよい

副次的な結果とは、失敗するかもしれない関数におけるエラーの種別や、データを保存したデータサイズや、状態を変更する場合は変更前の状態など

定義指向プログラミング

ネスト

  • ネストはどこが重要なコードが分かりづらくなるので避ける
  • プライベート関数などを使ってネストを避ける

例:

if (isValidMessage(messageId) &&
    isViewShownFor(messageId) &&
    isUnderstanding(messageId) &&
) {
    showStatusText("sending")
}

メソッドチェイン

こちらも同様に、チェインが長くなると把握しにくくなる。

適切な情報が得られたら、そこで一度打ち切るのが良い

例:

const friendProfileBitmaps = 
  userModelList
  .filter(userModel => userModel.isFriend)
  .map(userModel => userModel.profileBitmap);

friendProfileBitmaps.forEach(
  bitmap => imageGridView.addImage(bitmap)
)

マジックナンバー

自明なものについては、ナンバーをそのまま使うのは良い。

同じ値が別の目的で使われる可能性があるものについては

定数でマジックナンバーを抜き出し、名前をつける。

早期リターン

関数の主な目的を達成できるケースをハッピーパス

関数の主な目的を達成できないケースをアンハッピーパス

先にアンハッピーパスを書くことで、残りをハッピーパスとみなすことができるので読む負荷が下がる。

そもそも、アンハッピーパスを作らないことを心がけるのが良い。

関数の呼び出し元でその関数を呼び出すかどうかを前もって判別できるのであれば、呼び出された関数で早期リターンを行う必要もない。

依存

結合

1.無結合(No coupling): 二つの部分が全く関連していない状態。

function functionA() {
  // 処理A
}

function functionB() {
  // 処理B
}

// functionAとfunctionBは互いに関連していない

2.データ結合(Data coupling): 二つの部分が単純なデータ(プリミティブ型)でやり取りをする状態。

function add(a, b) {
  return a + b;
}

const sum = add(3, 4);
// add関数は単純なデータを受け取り、処理を行う

3.スタンプ結合(Stamp coupling): 二つの部分がデータ構造(オブジェクト、構造体など) でやり取りをする状態。

function getFullName(user) {
  return `${user.firstName} ${user.lastName}`;
}

const user = {
  firstName: "Taro",
  lastName: "Yamada",
};

const fullName = getFullName(user);
// getFullName関数はデータ構造(オブジェクト)を受け取り、処理を行う

4.制御結合(Control coupling): ある部分が他の部分の制御フローに影響を与える状態。

function getFullName(user) {
  return `${user.firstName} ${user.lastName}`;
}

const user = {
  firstName: "Taro",
  lastName: "Yamada",
};

const fullName = getFullName(user);
// getFullName関数はデータ構造(オブジェクト)を受け取り、処理を行う

5.外部結合(External coupling): 二つの部分が外部資源(ファイル、データベースなど)を共有する状態。

6.共通結合(Common coupling): 二つの部分が同じグローバル変数やシングルトンオブジェクトに依存する状態。

function getFullName(user) {
  return `${user.firstName} ${user.lastName}`;
}

const user = {
  firstName: "Taro",
  lastName: "Yamada",
};

const fullName = getFullName(user);
// getFullName関数はデータ構造(オブジェクト)を受け取り、処理を行う

7.内容結合(Content coupling): ある部分が他の部分の内部実装に依存する状態。

class MyClass {
  constructor() {
    this._secretValue = 42;
  }

  getValue() {
    return this._secretValue;
  }
}

function accessSecretValueDirectly(obj) {
  return obj._secretValue;
}

const myInstance = new MyClass();
const secretValue = accessSecretValueDirectly(myInstance);
// accessSecretValueDirectly関数はMyClassの内部実装に依存している

単純なクラスから複雑なクラスへの依存

モデルなどの単純なクラスに対して、requesterのような取得に関わる複雑なクラスが依存すると便利ではあるが

requesterがデータベースやネットワークといったリソースを保持していたりすると、そのリソースを解放するためにモデルを使ってるコードを全て確認する必要がある。

モデルを通してrequesterが使われている可能性があるため。

そういう時は、関数に外部から渡すような形にすることで、モデルに組み込まないようにすることが重要。

それでも、複雑なクラスへの依存が発生してしまうパターンがある。

そういう時は、メディエータパターンを採用する。

しかし、過度な抽象化はしない方が良い。

コードレビュー

読みやすいPR、レビューしやすいPRというのがある。

PRの目的を明示的にすることは当然として

PRの分割には気をつけたいところ

大きくなりそうなPRに対しては

まずはスケルトンクラスを作るなど

こまめのコミットを行う方が良い。

また、コミットについても

機能AとBを作るに当たって

  • 機能AとBを実装
  • 機能AとBのテスト実装

とするより

  • 機能Aと機能Aのテスト実装
  • 機能Bと機能Bのテスト実装

とした方がレビュアーには優しい。

既存のコードとバッティングしてしまった時は

現在作業中のブランチから、新たにブランチを切って、元のブランチがマージされてからリベースをするのが良い。

元のブランチがマージされるまで期間があきそうなら、先にその対応だけを行ったPRを作成するのが良い。

頭に置いておく必要があるのは

レビューを受けたコメントは全てが正しい訳ではないので、全てを鵜呑みにしない方が良いということ。

まとめ

こちらの本は、愚直にコードを改善していくというところに着目していると感じました。

もちろん、プロジェクトによって、妥協する必要がある場面もあるかと思います。

しかし、それもトレードオフで受け入れるデメリットを理解し、どこかでその返済を行う必要があるでしょう。

その辺りの調整は、エンジニアだけではできない部分もあるので、いろんな人を巻き込んでの話し合いにもなるかもしれません。

そうなった時に、可読性やコードの綺麗さによって、生産性にどれほどの影響をもたらすのかというのを計測したり、プロトタイプなどを作るなどして目安を把握しておく必要があると思います。

今回読んだ中で出てきた表現には、当然別の本で読んだ表現も含まれていて

同時並行で読んでいたこともあり、理解が深まったり、より信憑性が高まったところもありました。

少し横道逸れますが、同じ系統の本を同時進行で読むことも効果が高いことを実感できたと思います。

エンジニアのためのマネジメントキャリアパス

概要

こちらの本を読んだのでまとめようと思います。

 

 

 

 

 

300ページ程の本でしたが、かなり内容的にはボリュームのある、ずっしりとした本という印象を受けました。

 

これまで読んだマネジメント系の本と部分部分で被るところはあるにせよ、かなり一つ一つが細かく、細かいのに内容としては広範囲を網羅していました。

 

テックリードといった階層からVP、CTO(ここら辺はコンテキストによって意味が分かれます)と呼ばれる層の人に向けての内容が多く、自分としてはまだ先の話だなと思いながらも、やはり知っておくことに意味があると思い読んでいました。

 

本の中でも、管理者、とりたて技術系に関わる管理者にとって一番大事なことは、「好奇心を絶やすな」ということが一貫して書いてあったので、そういう意味でも知っていくという気持ちは大事にしたいなと再確認できました。

 

では、まとめを書いていこうと思います。

 

 

# マネジメントの基本

第一章ではマネジメントの基本について書かれています。

マネジメントする側になる前に必ず人が通る道として、マネジメントされる側になることです。

マネジメントの基本として、マネジメントされる側の視点からこの章はできています。

他の本でも書かれていたことが多かったのですが

  • 1on1について
  • フィードバックについて
  • 人間性

について書かれています。

 

やはり、上司との1on1といっても、何を話せば良いか分からなかったり、意味のない1on1になってしまうことがあります。

それを避けるための改善方法や心持ちを書いてあります。

 

## 1on1の意味

1on1は、人間的なつながりを作ることに一役買うものです。

上司といえど、人間なのでいろんな理由で感情が揺れる時もあります。

また合う合わないといった人間的なところでのコンフリクトも起こりやすくなります。

 

そういった中で、自分の今のやりたいことや、気になる言動などの面から上司を見て、フィードバックをするということも大事になっていきます。

1on1では、自分の考えてることを伝えると同時に、上司に自分の考えるキャリアについてアドバイスをもらう場として活用することが良いです。

 

エンジニアとして有能で尊敬できる人が上司になった途端、自分と合わなくなるといったこともあります。

そういったことがある時、チームを変えてもらうなどの相談をすることも必要になってくるでしょう。

 

## フィードバック

気がついたらその場ですぐに行うことが大事になります。

しかし、誉める時はみんなの前で、注意をする時は1on1などで個別に行うということを心がける必要があります。

 

# メンタリング

第二章では、メンタリングについて書かれています。

初めてマネージャーとなる前に、インターンなどの研修を任されると流れ的には良いです。

新卒1、2年の方がメンターをやる際には、まだ自分がメンティーだったことが新鮮な記憶としてあるうちにやることで良いことを引き継げるという利点もありますし、シニアエンジニアであれば技術力や経験を伝えることもできるという利点があります。

しかし、インターンの研修と言えど、細心の注意を払う必要はあります。

 

これからインターンを受ける人にとって、そのインターンが良いものであったかどうかによって自分達の会社の見え方も変わってくるでしょうし、良いこと悪いことの広まり方にも大きく関わってくることだからです。

## インターンシップ

学生であることが多いと思うので、学業などにも時間が割かれてしまっています。

その中でインターンとして選んでいただいているので、無理な要件を提示することは良くないです。

### インターン中のプロジェクト

プロジェクトは自分なら、2、3日でできるようなタスクをしてもらうのが良いでしょう。

特に納期が迫っていないものを選んであげるのが良いです。

### 最初の2,3日程度はインターンに付きっきりの気持ちで取り組む

インターンの最初の活動は新入社員とほぼ変わらないです。

会社概要など説明を受けたりなど。

その期間は付きっきりで

  • IDEの設定
  • コードの説明
  • また、タスクによって圧倒されていないか様子を見る

などでそばにいるように心がけます

### 傾聴する

ひたすら自分だけ喋りっぱなしではなく、インターンからの言葉を理解することです。

ここでの理解というのが、言葉上だけのものではなく

  • 表情
  • 言葉
  • 仕草

など、その所作全てを注意しながら見て聞くことが重要になります。

特に相手にとって自分は「強大な力のある人間」に見えてるはずなので、相当の緊張とプレッシャーがあるはずです。

そのため、まずは自分自身がゆったりと構え、質問しやすい雰囲気を作ってあげることで言葉を引き出すようにすることが特に重要になります。

### プレゼンテーション

最後にはプレゼンテーションをしてもらうのも良いでしょう。

自分がやり遂げたインターンの集大成を先輩社員に見てもらうのでも良いです。

達成感や、プレゼンテーションのやり方を学ぶ機会にもなります。

それにより、良いインターンができたと思ってもらえたら最高です。

## 新入社員

新入社員は、まず会社の文化についてはほぼ知らない状態で入ってきます。

それは、休暇の取るタイミングや、質問の仕方、この時期は繁忙期といった背景の部分の知識です。

そのため、自分自身がもう雰囲気の中に浸かっている場合、気づけない点があるので新入社員が入ったタイミングでメンタリングを通してリフレッシュさせる良い機会になります。

### ドキュメント

環境構築は誰もが行うことですが、その資料というのはすぐに変化が起こりうるものです。

その変更に対応するためにも、新入社員が入ったタイミングで洗い出し更新していくことが必要になります。

### アルファギーク

アルファギークとは、チームのまとめ役にはもっとも優秀な人がなるべきという思考の人のことを言います。

どういう弊害があるかというと、ヘマをした部下などに対してけなしたり、部下の仕事を勝手に作り替えたりしてしまったりすることになります。

 

しかし、短所ばかりだけではなく、良い面もあります。

気が向きさえすれば、素晴らしいことを山ほど教えてくれます。

画期的なシステムを設計できる腕もあるので、部下としてそのプロジェクトに参加するのは楽しいものだそうです。

そういったこともあり、上記にあるような短所に目をつぶるようなエンジニアもいるようです。

## メンターの重要な心得

### 常に好奇心を絶やさずオープンな心で

メンターにとってメンタリングは、新人のフレッシュな目を通して世界を見つめ、好奇心を刺激してもらう絶好の機会です。

 

自分では不明点なことなど一つもない状態から、質問されて初めて実は外から見たら不明な点だらけだったということに気付かされることも多いです。

新人を指導することで隠されたパターンが見えてきて、普段思いつかないような方法を導き出すということにも結びつけることができます。

 

### 相手の言葉をよく聴き、相手の言葉で話す

これはメンターだけに留まらず、全ての人にいえることですが、コミュニケーションスキルにおいて重要なことになります。

特に上記にもある「傾聴」のスキルが重要です。

しっかり、メンティーの言葉面だけではなく、その所作や声色、表情などからも聞き入れることが大事になります。

 

そして、シニアエンジニアの中には悪い癖として、反論されたりするとお説教などをしてしまう人もいますが、チームとして一緒に仕事をする上で相手が理解できるやり方で傾聴し、意見を伝える必要があります。

# テックリード

よくある誤解として、テックリードはプログラムを書くことに没頭していたい人や没頭してしまう人がなるべきものというものです。

プログラムに没頭したい人はテックリードにはなるべきではありません。

つまり、誰よりも経験豊富なエンジニアや、誰よりもすばらしいコードが書けるエンジニアがなるべきというわけではないということです。

 

では、テックリードにはどんな責務が定義されるでしょう。

これの答えとして、厳密には定義はありません。

この本では、コードを書くことももちろん責務の一つにはなりますが、主に

  • 経営陣との連絡や話し合いの場でチームの代表を務める
  • 昨日をデリバリするための計画を練る
  • プロジェクト管理の大部分を細部まで担当する

といったことが説明されています。

そして、多くの場合スキルとリーダーシップの両方が求められるため、「1人が長期にわたって就く職位」ではなく、「複数の人が順次一時的にそのすべてを担う職責群」として定義された方が良いです。

 

ここにThoughWorks社のプリンシパル・テクニカル・コンサルタントのパトック・クアが提唱したものを引用しています。

テックリードとは、(ソフトウェアの)開発チームに対する責任を担い、最低でも自身の職務時間の3割はチームと共にコードを書く作業に充てているリーダーのこと。

 

非技術系の相手との協業する際には重要な役割を演じることも責務になります。

人的な管理を望んでいないエンジニアにとっても、プロジェクト管理のスキルはシステムを設計する作業と類似点は多いので、有意義なスキルになります。

## テックリードなら必ず知っているコツ

実際のプログラミングの作業からあっさり一歩引き、技術面での貢献とチーム全体のニーズへの対応のバランスを取る努力を惜しまない ということです。

これは、これまで得意としていたプログラミングという領域から出て、不慣れな新しい仕事を覚えていかなければならないといった面においてかなり辛いことです。

会議などが増えることにより、コードを書く時間が減ったりや、細切れ作業になることによりガッツリプログラムに向き合う時間が取れないという点において、時間のバランスを取るスキルが求められます。

 

しかし、他のメンバーにはしっかりプログラムに向き合って作業してもらう必要があるので、それを可能にするスケジュールを組むことも重要になってきます。

## テックリードがコードに触れるということ

上記で、「実際のプログラミングの作業からあっさり一歩引き」と書いたのですが、「職務時間の3割はチームと共にコードを書く作業に充てている」と矛盾していると感じた人もいるかと思います。

では、これの意味するところは何なのか。

 

例えば、何か問題があったとして、すぐに自分でその原因を掴みたいと思ってもそこに自分が注力しすぎてしまうのは良くないです。

まずはチームにその問題を伝える必要があります。

プロダクトマネージャーや技術管理者にも伝える必要はあるでしょう。

そして、任せられるメンバーに適任を見極めるということも重要になります。

その上で自分が取り掛かるかどうかを判断します。

## プロジェクト管理

アジャイル開発が流行っている今、プロジェクト管理は不要では?という問いもあるかと思います。

これについては、そんなことはなくアジャイルを通して、タスクを分割し、それに基づいて計画を練り、価値を「全部一度に」ではなく「徐々に追加していく」ため、プロジェクトを検討する上で大変有用になります。

 

詳細がはっきりしない中でのタスクの分割などを行うことは恐ろしいことです。

また長期にわたるプロジェクト管理を好んでやりたいと思う人は少ないでしょう。

しかし、キャリアラダーを登るにつれて、自分1人がこなせる範囲を超えた複雑な仕事をする上でこの分割作業をするコツというのを身につける必要があります。

## 管理者としての日々

この本では、管理者となる前のイメージと、実際に管理者になったあとのイメージとを比較して書いてくれています。

実際になったあとのイメージだけまとめておきます。

  • 人は言葉で伝えるだけでは動いてくれないということ。
  • 何もしなくてもあなたの意見に賛同し、ついてきてくれるというのは幻想
  • 昇格や昇進についてネガティブなことを伝えないといけない時の士気を高めることの難しさや、自分の無力さを感じることへの辛さ

こういった大変さがあることに、管理者になった後に気づいたとしても

進路変更が可能ということは忘れてはいけません。

また技術畑に戻ることも可能ということを念頭に置きつつ、自分には何が向いているのかを常に目を開いておく必要はあります。

## 優秀なテックリードとは

ざっくりとまとめます。

  • アーキテクチャを把握している
  • チームプレイの大切さを心得ている
  • 技術的な意思決定を主導する
  • コミュニケーションの達人である

# 人の管理

## コミュニケーションにおいて大事なこと

信頼感と親近感を作るために1on1などで聞くと良いこと

  • 褒められる時は人前がいいか、個別がいいか
  • フィードバックの伝え方
  • 不機嫌な時どんな仕草をするか。もしくは、不愉快な気分にさせる要因はどんなのがあるか。
  • 耐え難い上司の振る舞い
  • チームにきてから良いこと悪いこと、なんでも言ってもらう

こうしたことを質問し、把握しておくことで幾分かコミュニケーションをしやすくしたり、その人の状態を知ることができます。

## 1on1のスケジュリング

標準的には、週に1回とされています。

一度週に1回で運用し、多すぎる少なすぎるの判断を見極めるのが良いかと思います。

また、時間に関しては午前中が良いです。

午後はあれこれ忙しくなることも多かったりするため、お互い午前に出社し、スタンドアップミーティング(朝の定例のような)ものがない場合は午前に設定するのが良いでしょう。

しかし、部下の抱えてる対顧客のスケジュールがある場合は、そちらを尊重すること。

## 1on1のやり方はそれぞれの部下によって変わる

部下によっては、TODO形式でやりたい人もいるでしょう。

Google Driveなどで事前に話すことを共有するのもいいでしょう。

フィードバック型(非公式なフィードバックやコーチング)が必要な人もいるでしょう。

どのように報告したり、共有するかはチームメンバーによって変わると思うので、一貫してこれといったものを貫くプロセッサーにはならないようにしましょう。

# チームの管理

エンジニアリングリードは、シニアエンジニアであった時と同じようにコードに触れるという時間は圧倒的に少なくなります。

しかし、そうとはいえ、小規模な技術成果物の作成や、バグ修正や機能の作成といったことについては携わることが必要です。

エンジニアリングリードは、独立した管理者であり、自分とは異なるスキルセットをもつメンバーから成るチームを管理する権限と能力を有します。

優れた管理能力に加え、製品に関する技術的ロードマップを管理するリーダーの役割を持ちます

## ITスキルの維持

コードを書くことから卒業してしまった後も、技術面においての意思決定を行い、責任を負います。

この時、システムのアーキテクトや、細部の責任を負うシニアエンジニアに対しても自分の下した決定に責任を負う必要があります。

そのを可能にするのが、「技術者の勘」というもので長年培われるものです。

 

しかし、そうとしてもコードを少なからず書くということをする必要がでてきます。

それは、ボトルネックや作業工程の問題点のありかをすばやく察知するために、コードに従事しておく必要があります。

それが上記でも書いた、ちょっとしたバグ修正や小機能開発などになります。

そのおかげで、コードのデプロイに時間がかかるなどの問題点にも当たり、改善点といったことも見えてきます。

## データ重視の文化

チームの生産性に関するデータ(機能の完成までの所要時間など)や、品質の測定に関わるデータに基づき、機能開発や技術的改変についての意思決定を評価するように慣れてもらう必要があります。

## 将来を見据える

「今、ここ」より2歩先を見据えて考えていく必要があります。

プロダクトロードマップに描かれている今後の展開を把握することで、テクニカルロードマップをベースにした管理がやりやすくなります。

また、新しいJavaScriptフレームワークなどによって、よりインタラクティブな体験を作るなどのためにも、現在に対する見方を変えてしまう可能性のある新技術を常に把握しておけるように情報収集の時間も設ける必要があります。

## 納期間近にはノーという務め

上からも下からも要求の中に、相当複雑な実装作業が必要なものもあります。

その場合には、しっかり実装作業のコストを提示し、ノーと断る判断をしなくてはいけません。

本当に期限内に完成させなければならないものをチームと共に厳選しないといけないです。現実的に何なら実装可能か、すべてを完成させるにはあとどれくらい時間が必要なのかの選択肢をチームに提示することもあり得ます。

### ノーの言い方

ただ、ノーと言うのだけでは良くないのは、これまでにもコミュニケーションの大事さから分かったと思うのですが、ではどう言えばいいかです。

 

「はい、それでですね」

といった表現を使うテクニックがあります。肯定系で受けつつも、その後に問題となる点を論うことで、優先度を見据えた現実的な交渉に持ち込めることが多くなります。

### ポリシー

自分が何に対して、どの基準を超えたらノーと言うかという基準のポリシーを持っておくことが良いです。

そしてそれをメンバーが認識することで、メンバーや上司からの要望があった時にそのポリシーに満たしているかどうかをメンバーから説明があったりすることで自分がイエスと言いやすい状況を作ってくれます。

もしくは自分自身が決定を下す際の武器となりえます。

また、低リスクで影響の小さな意思決定に対して、即座にノーと言えるように慣れることも大事になります。

# 複数チームの管理

複数のチームの管理となると、技術部長レベルになってきます。

つまり、外部との間にも入っていき、関係を築いたり予算編成をするような立場になります。

そういった役職になると、さすがにコードを書く作業は全くなくなってきます。

週に2日は丸々コードを書く時間に充てられない限り、コードでの作業生産ができないからです。

## それでもコードに追いつくことは必要

そんな状況でも、コードレベルで追いかけないといけない場面もあります。

そのために何ができるか。

  • コードレビューを(少なくとも副レビュアーとして)引き受ける
  • インシデント時に必要に応じてペアプログラミングを行う(デバッグが苦手なメンバーに対しての教育の一環として)
  • 全くコードを書くつもりがない人でも、週に半日でもいいのでまとまった自由な時間を作り、何か創造的な活動に使う。
    • 技術系のブログを書く
    • カンファレンスで行う講演の準備
    • オープンソースに参加するなど

## クイックウィンはない

コードを書くと、その場でバグがなくなったり、新しい機能が追加されたりとクイックウィンがありますが、管理系には新米時代には早々そういったものがないです。

そのため、自分の生産性に対して不安であったり、せっかく身につけたプログラミングのスキルを失うという不安が生まれてきます。

しかしこれはしょうがない話で、トレードオフとして「あちらを立てれば、こちらが立たず」といったふうに諦めるしかありません。

どちらかを選ばざるをえないです。

エンジニアとしてのヘマであれば、自分のバツの悪さですみますが、管理者でのヘマは、チームのみんなに迷惑がかかるため、管理者としての仕事をお座なりにしてクイックウィンのためにコードに向き合ってしまうのは良くありません。

 

しかし、そんな時でも管理者として自分が1日にこれだけの仕事をやり遂げたのだと振り返ることが大事です。

それだけでも1日の仕事としては十分になります。

## 委任する仕事、しない仕事

1. 頻繁で単純な仕事

直属のチームのテックリードやシニアエンジニアなら訓練なしで任せられます。

  • スタンドアップミーティングを開く
  • 週毎のチームの作業の進捗状況の要約を書く
  • 小規模なコードレビューを行う

2. 頻繁でない単純な仕事

自分で行う方が手っ取り早い

  • カンファレンスのチケットを予約する
  • 四半期報告書を生成するアプリケーションを実行

3. 頻繁でない複雑な仕事

あなた1人でこなすべき仕事ではありますが、後輩の有望な管理者に伝授していく必要があります。

  • 勤務評価の要約を書く
  • プロジェクト支援要因を新たに何人雇う必要があるかについて意見を言ってもらう

4. 頻繁で複雑な仕事

チームの有望なメンバーを育成と同時にチーム全体の運営力を強化する機会になります。

  • プロジェクトの計画立案
  • システムのデザイン
  • システム障害の復旧作業のまとめ役

## エンジニアはせっかちであるべき

管理者としての地位が上がってくると、部下から模範行動を求められるようになる。

その時に教えることが、「焦点の絞り方」になります。

「せっかちに重要なことを見極める」ということと「帰宅する(無精になる)」という2つを実践するのが良いです。

 

ろくに考えもせず時間ばかり費やすのではなく、重要なことを見極めて自動化を推進し、効率をよくすることで、面白い仕事ができる環境を作る必要があります。

面白い仕事というのは、脳を広範囲に使う仕事で、何時間も何日もぶっ続けでやれる類の仕事ではないです。

そのため、せっかちになることで重要なことをできるようにし、面白い仕事をしていきましょう。

# 複数の管理者の管理

最大限のテコ入れができるようになるまで、自分が「本当に重要かどうか確信はもてないが、何となく怪しいと感じること」を最後まで見届ける必要があります。

そうでない時は、いつどこで介入するか直感的に判断するための経験則や勘を十分に身につけられていないということなので、十丁だと思える時でも顔を出すことが推奨されます。

## スキップレベルミーティングは一つの手段

上記のようなことを判断するために、一つの有効な手段としてスキップレベルミーティングがあります。

これは、2つ以上ランクが離れた部下との関係を維持することために行われます。

2つ以上離れた部下となると、人的リソースとしてしか見れなくなってしまいます。

そうならないために、1人の生身の人間として見る必要があり、そのために時間を割くというのは必要なことになります。

ただし、1on1のような形式ばったミーティングだと40人、50人レベルの部下になってくるとそれだけで時間はなくなってしまいます。そのため1on1ではなくとも、お昼に行くであるとか、チームの人たちとちゅ食をとりながら近況を話すなどでも効能が得られます。

## 新任管理者の管理

管理者の最初のころというのは自分が何を知らないかも分からない状態です。

新任管理者を統率する管理者にとって、自分の職務時間の一部を部下達のために有意義に使うのは非常に大事なことです。

長期にわたって自分の組織に利益をもたらす上で欠かせない初期投資とみなすべきです。

 

そういった新任管理者の中には、自分が経験したことのない大変そうな職責を前にし、「知らんぷり」を決め込む人もいます。

そうなると問題が潜在化し、大きくなったあとに発覚するということもあり、そのせいで新任管理者が辞めてしまうといったことも起こり得ます。

そうならないために、十分な指導ができるようにスキップレベルミーティングを設定するなどを行うと良いです。

## ベテラン管理者の管理

新任管理者と違って、何をすべきかを心得ていて、あなたのてを借りなくてもきちんと遂行するので、良いこと尽くめと思われるかもしれません。

しかし、マネジメントは会社や組織の文化に根ざした仕事です。

あなたが採用した人材が社風に合わない人材であったりすれば、あなた自身が問題を抱え込むことになります。

草創期からいるメンバーを経営チームに参画させたがるのは、その会社のDNAを理解しているからというのがよくある理由になります。

 

そう言うわけで、ベテラン管理者が入ってきた時にあなたが取り組むべきことは、「チーム全体に合う人物であるかどうかを確認すること」になります。

管理者はサブカルチャーを生み出す存在なので、今のカルチャーにそぐわないサブカルチャーを生み出すことは問題になってしまいます。

 

管理者も人ぞれぞれで、どんな文化を持った管理者であるかは人によることが多いです。

そのため、新たな人材を採用する際にも、信奉する文化を判断基準の一つにする必要があります。そぐわない人を採用してしまった場合

1. 管理者がチームを掌握できず、あなたはその管理者を辞めさせざるを得なくなる

2. チームメンバーの大半が辞めてしまって、やはりあなたはその管理者を辞めさせざるを得なくなる

といった状況に陥ってしまいます。

## チームが機能不全になってしまったら

  • 仮説を立てる
  • データをチェックする
  • チームを観察する
  • 質問をする
  • チームの人間関係をチェックする
  • 支援する

といったことをする必要があり、常に好奇心を失わずチームのデバッグをしていく必要があります。

## 技術力の点で時代遅れにならないように

  • 情報収集のための質問をする
  • 勘の拠り所に
    • コードを読む
    • 自分が疎い領域に詳しいエンジニアに解説を仰ぐ
    • ポストモーテムに同席する
  • 業界のトレンドを常に把握する
  • 社外での技術系の人脈作り

# まとめ

ここでまとめられなかった部分(経営管理についてや、採用の詳細、キャリアラダーについてなど)の部分もありましたが、一先ず今の自分に必要なところをまとめたような感じになります。

 

まとめの割に1万字を超えてしまったので、もう少し厳選すべきかと思いましたが、今の自分には再び理解するために読み直すには、それだけ書かないといけないほど中身の濃い本だったということです。

 

かなり内容的には濃い本だったので、これからマネージャーになるという0からベースの人にはかなり内容的に重たいかもしれませんが、読んで良かったと思います。

童話でわかるプロジェクトマネジメント

概要

童話でわかるプロジェクトマネジメントを読んだので、学んだことをまとめようと思います。

 

 

この本を読み始めた時点で、エンジニアリングマネージャーやプロジェクトマネジメント系の本は3冊程読んでいました。

 

それも連続で読んでいたので、かなり頭の中に、それ関連の知識や考えの回路が構築されている状態で読んだので、とてもスムーズに頭に入ってきました。

 

しかし、それを抜いても分かりやすい本だったと思います。

 

まず、童話というのは子どもに話す様な物語が多く、多くの人が知ってる内容やストーリーなので、プロジェクトマネジメントにおける用語や状況と置き換えした時にとてもイメージしやすいものでした。

 

三匹の子豚や、シンデレラ、ヘンゼルとグレーテルの様な、多くに人に馴染みのある話がプロジェクトマネジメントの視点で見ると、こういうステージに適しているといったような説明ができるというのは面白い視点だなと感じました。

 

その上で、PMBOK に対応し、前段階という知識をつける足がかり的な役割を担っています。第7版にも対応済みということですが、第6版までの知識でも重要なところは変わらないため、6版以前の話を盛り込んだ内容が大枠になります。

 

僕自身はまだPMBOKを読んだ事がないので、この足がかりを読んだ今なら次のステップとして読み進めてもいいのではないかなと考えているところです。

 

 

プロジェクトの進行・用語

プロジェクト:

決められた期間内に、今まで誰もやったことがない新しいプロダクトや、サービスなどの成果物をつくる業務

「何を」「どこまで」「期限内か」「予算内か」「資源は十分か」「品質基準を満たしているか」を制約条件とし、プロジェクトを成功させること。

プログラム:

複数の関係するプロジェクトをまとめたもの

各プロジェクトの調整などを一つ上の目線で行い、全体の目標を達成するための活動。

ポートフォリオは、プログラムやプロジェクトをまとめて、どれを優先的に進めるかや、各活動の調整や監視を行うことで、資源の配分を見極める。

PMBOKにおけるプロセス群

プロセス群とは

PMBOKでは、プロジェクトの知識体系をプロセスごとに分けて整理していて、プロジェクトの目標を達成するためにやるべきことを指す。

5つのプロセス

1. 立ち上げ

プロジェクトを定義し、認可を得るプロセス

2. 計画

プロジェクトの目標を達成するための全体的な計画を立てるプロセス

3. 実行

計画に従い、実作業を行っていくプロセス

4. 監視・コントロール

実績と計画の差異を監視し、必要に応じて対策や対応をするプロセス

5. 終結

プロジェクトで生み出した成果物を正式に受け入れ、プロジェクトを公式に終了するプロセス

知識エリア

1. 統合

プロジェクト全体の進行を管理する中心的な分野。他の9つの分野のプロセスや活動をまとめ、調整するために必要なプロセスと活動

2. スコープ

最終的に生み出すモノやサービスなどの成果物と、必要な作業と範囲を明確にするプロセスと活動

3. スケジュール

所定の期間内にプロジェクトを完了させるために必要な、スケジュールの管理や調整などのプロセスや活動

4. コスト

所定の予算内にプロジェクトを完了させるために必要な、スケジュールの管理や調整などのプロセスと活動

5. 品質

プロジェクトで生み出すモノやサービスなどの成果物の品質と、作業自体の品質を管理するためのプロセスと活動

6. 資源

プロジェクトに必要な資源を決め、その資源を最大限活用できるよう働きかけ、活用できているか見張るためのプロセスと活動

7. コミュニケーション

ステークホルダーとのコミュニケーションを円滑に進めるために、必要な情報収集、用意、保管、配布などのプロセスと活動

8. リスク

プロジェクトに関するリスクに備え、チャンスを活かすために必要な、リスクの特定、分析、対応、管理や調整などのプロセスと活動

9. 調達

作業を実行するために必要なサービスやモノを外部から取得・購入あるいは委託、管理などのプロセスと活動

10. ステークホルダー

プロジェクトを確実に進めるために必要な、プロジェクト関係者の特定、関係者からの影響の分析、対応、管理、調整などのプロセスと活動

三匹の子豚

計画が一番大事ということを伝える章。

当然と言えば当然だが、とにかく始めるというのは失敗の原因になってしまうので、計画を立てましょうというお話。

ステークホルダー

ここでいうステークホルダーは三匹の子豚のお母さんで、実際にはプロジェクトの関係者を指します。

メンバーであったり、スポンサー、顧客、ユーザーなどです。

彼らに対して、常に関心度と、権力でのマトリックスで分析して、必要に応じて話をし情報を集めるというのは大事です。

今回でいうと、家を作るという作業において、お母さんの発言は大きいものです。

そのため、三男の子豚はお母さんに何度も仕様の確認であったり、どのように進めるかのアドバイスを求めに行きました。

こうしたアドバイスを適切な人にもらうというのはステークホルダーと共に進行していると言えますね。

 

また、相談事の例として、目的地と進路というのがあります。

キックオフミーティングなどを通して、メンバーと目的地の認識合わせをし、頑張るぞという打ち合わせをするなどして共通認識を持つことが大事になります。

そのために、5W1Hを利用するとよさそうです。

何の目的で? なぜ必要なのか? 何を持って完了か? 優先されるべきものは? 目標は簡潔か? 記録しようとしているか?

時間のスケジュール

それぞれの作業が終わる時間の見積りを行うために、WBS(ワーク・ブレイクダウン・ストラクチャ)を作ります。

これにより、それぞれの作業を細かく割り、時間見積りがしやすくなります。

当然、プロジェクトは1人で行う訳ではないので、その作業に見合うよう、人員の調整が必要になります。

そのためにも、社内などであれば政治的なものも含めて、人員な確保にも行動する必要があるでしょう。

クリティカルパス

絶対に遅れてはいけない作業。

作業時間が長く、これが遅れると全体の進行が遅れてしまうようなタスクのことです。

自分が作業する上で、その作業がクリティカルパス線上にあるのかどうかを把握するだけでも、心構えが変わってきますね。

マネジメントする方も、それぞれのタスクの重要度を洗い出したのち、WBSを作成する助けになります。

リスク

計画と実態はよくズレるものです。

期待と現状もギャップがあります。

このズレこそがリスクになります。

そのため、このリスクをあらかじめ洗い出す事ができれば、事前に対応ができます。

それには

  • チームの人と話、洗い出す
  • アイディアをまとめ、投票でアイディアを選ぶ
  • 専門家へアンケート調査、意見をまとめる
  • 作業に対して、問題がないか常に確認・質問をする

などの対応ができます。

また、リスクへの対応として

  • 予防策と、起きた時の発生時対策を決める
  • 起きた時の発生時対策を決める
  • その都度、判断する
  • 無視しても可

などの候補を出しておく必要があります。

具体的な対応策として

  • 回避・転嫁・軽減・受容
  • 誰が、いつ、何をどのように対応するか
  • 対策の実行トリガー決め
  • WBSにも対策活動を追加
  • 定期的に再評価、リスク管理内容を記録。

などがあげられます。

大事なのは、「困った…どうしよう」という状況を作らないように尽力することです。

ズレに対して

プロジェクト進行のズレに対しては

  • 並行で作業を進める方法(ファスト・トラッキング
  • 資源(人、お金など)を追加することで、所要時間を短縮する方法(クラッシング)

などがあります。

上記を行うための、別の問題なども発生することも考えられますが、うまく調整するためには上記を行うしかない場面もあるでしょう。

スケジュール調整には常に手直しや、コストなどのリスクが伴うものです。

ウサギとカメ

目標への意識が大事という章。

チームで行うということについて書かれています。

チームについては別の本も読んでいるので、参考にしてください。

ugo-ev.hatenablog.com

まず、チームメンバーでプロジェクトする際は、自分で目標を定めると自発的に動く方へ変わってくるという話があります。

SMARTの法則

  • Specific: 具体的でわかりやすい
  • Measurable: 計測可能で数字になっている
  • Atteinable: 達成可能で、現実的になっている
  • Relevant: プロジェクトでなすべきことや成果に特化している
  • Timely: 期限が明確になっている

の法則になります。

優秀なマネージャーは完全な計画を立てる事は不可能と理解しているが、不確定要素が多いプロジェクトや仕事の大枠を理解しているので、プロジェクトを成功に導く要素も理解しています。

不確定要素については他の本にも書いてあるので参考にしてください。

ugo-ev.hatenablog.com

やらないことを決める

このケースでは、ウサギはレースの途中で寝てしまいます。

そしてカメに抜かされて負けてしまいます。

この時ウサギは、「寝ない」という選択をするのではなく、寝るとしても「1時間以上寝ない」などのやらないことの範囲を決めてやるべきでした。

このように、やらないことと定めるということは重要になってきます。

明確にすることで、「寝ない」といった選択肢を取るよりも効率的に進めることができるかもしれません。

しかし、それにより出る影響などは考える必要があることを念頭に置いておかないといけません。

なぜの問いかけ

失敗が発生した時は、原因について「なぜ?」という質問を繰り返すことが大事です。

そして、なぜの後は「何?」という質問を繰り返します。

この時の注意は、問題を解決する、あるいは今後改善のために、視点を仕組みやシステムに向けることです。

また意識ではなく、行動に焦点を当てることも重要です。

桃太郎

不確実性に対してのチームの心得を説く章です。

不確実性については別記事の本でも紹介しています。

チーム全員が不安

不確実性に対しては、自分だけでなくチーム全員が不確実性に対して不安を感じています。

しかし、これにより逆に連帯感を生ませることができます。

マネージャーがプロジェクト関係者一人一人に声をかけていくなどし、不安要素に対して素直に懸念点などを語ることを通して、「不安なのは1人だけではない」ということを共有し、連帯感を生み出すことができます。

大事なのは、1人でプロジェクトを終わらせるということではなく、チームとして行い1、人でやろうとしないということになります。

何を期待するか

やる気というのは「自分で、目標を立て、計画し、実行し、達成感を得られる」という環境によって生まれます。そして、それを通して成長し、次のプロジェクトへ立ち向かいます。

そのため、メンバー1人1人が何を期待するのかを傾聴することが大事になります。

それにより、それぞれの価値観に対して、プロジェクト内でのポジションや役割などが決定し、プロジェクトに対する当事者意識を持って取り組み、お互いにwin-winの状態で成長することが可能になります。

権力

プロジェクトマネージャーは最初は権力が全くないところから始まります。

そのため、キックオフミーティングを開催し、ステークホルダー一人一人と密にコミュニケーションをとることで権力を獲得していき、影響力を身につけます。

マネージャーは最初から権力を持ってるように感じてる人もいるかもしれません。途中からチームに参画したりするとすでにある程度チームができている状態が多いので、マネージャーに権力がすでにある程度ついてることが多いためです。

しかし、プロジェクト初期にはほぼない状態から始まります。そして、継続的な強力を得るためには、重要な作業を達成したり、困難なことがうまくいった時にはお祝いしたり、個人的に感謝したり、ポジティブなフィードバックをすることが重要になってきます。

人を動かすために意識すべき6つ

  1. 味方になると考える
  2. 目標を明確にする
  3. 相手の世界を理解する
  4. カレンシーを見つける
  5. 関係に配慮する
  6. 目的を失わない

具体的な行動の計画を立てる際のNGワード

行動が曖昧な表現

管理する、監視する、把握する、確認する、チェックする、競技する、話し合う、議論する、調整する、調べる、研究する、勉強する、覚える、努力する、徹底する、図る、実践する、実行する、実施する、遂行する、運営する、推進する、進める、活用する、励む、踏ん張る、協力する、支援する、助言する、効率化する、有効化する、迅速化する、明確化する、定着化する、円滑化する、安定化する、共有化する、工場する、育てる、発展させる、企画する、浸透する、評価する

行動ではなく頭で考える表現

検討する、考える、意識する、心がける、頑張る、目指す

程度が曖昧な表現

具体的に、効率的に、明確に、ハッキリ、きちんと、しっかり、できるだけ、なるべく、もっと、可能な限り、極力、必要に応じて、積極的に、臨機応変に、迅速に、強調して

コンフリクト

人との対峙・対決はチームで行う上で起こるものです。

その時重要になるのは、聴く力になります。

相違点を洗い出し、対立の原因を特定し、目的を踏まえた上で納得し合意できる最適な方法を生み出すことになります。

コンフリクトの解消策は主に以下の5つ

  1. 矯正
    一方的に押し付ける。長期的な効果がある。
  2. 鎮静
    あまり大きな問題として扱わず、なんとなく妥協点が見出された暫定的対応。
  3. 妥協
    当事者同士が互いに譲歩し、合意した方法。
  4. 対決・対峙
    最適な方法。対立は消滅し、長期的な効果がある。
  5. 撤退
    当事者の一方があきらめ、話し合いを拒否する最も悪い方法。再びコンフリクトが起こる。

ヘンゼルとグレーテル

不確実性に対しての対応策を説く章です。

ヘンゼルとグレーテルという2人の子供に対し、継母ときこりは森の中に置いてくるという行動を行うも、継母ときこりの目的がズレていたため、ヘンゼルとグレーテルは回避策を行い一度失敗してしまいます。

その後結局、回避策を準備する間もなく、もう一度森に置いていかれてしまい、魔女に遭遇。魔女の企みにも回避策を行い、助かるという話です。

リスクに対する発生率と影響度

リスクに対しての発生率とその影響力により、マトリックスを用意できます。

発生率が高く、影響度が高いものは優先度を1とし

発生率が低いが、影響力が高いものは優先度を2とするなど

それにより、対応すべきリスクへの対応策が具体的になっていきます。

そして、大事なことはリスクの対応が終わったあとに、再評価することにあります。

記録に残し、振り返りとするということも大切になります。

継続的な再評価を心がけます。

プロジェクトが変化し続けることによるズレ

変化し続けるということは、当初の計画より実績がズレてきます。

これは避けられないことでほぼ必ず発生すると言っても良いほどだと思います。

変更に対応するためにも、必ず変更に対して上司に相談したりステークホルダーと話すなどをして承認を得ることも大事です。

また、自分がどれくらい把握しているか、持っている知識や経験がどこまで活かせるかなどを、客観的に分析します。

しかし、現状把握や目標、成果物、リスクが曖昧だと共通認識を持つことが難しいです。

そこで、「ということは?」という質問を繰り返すことで、具体化していきます。

曖昧な点に対しては、ということは?と自問自答を繰り返し、時には「だから?」「どうやって?」を交えていくと良いです。

問題がない or 問題を隠すことが問題である

何か問題が発生した時、発見者が対応しなきゃいけないであったりとか、発見者が1人で解決しないといけないという文化は、問題を隠してしまう問題にも繋がります。

その問題は、発見者のみに関係するものではなく、他にも影響がありそうであればそれはチームに報告し、チーム一丸となって解決に取り組まなければならないので、そういった文化作りというのは非常に重要になります。

発見者だけが、悩み抱え込むということを回避するためにも、ルールやプロセス、体制を作ることが必要になります。

リスクを味方に

リスクは悪いことだけではありません。

リスクを活用することもできます。例えば、ヘンゼルとグレーテルでは、帰れなくなった2人は魔女のお菓子の家に行きますが、魔女が2人を太らせて食べようとしていました。

そのことを知った2人は、食べられる危険性もあるが、逆に言えばしばらくの食料や寝床の確保ができたと捉えることができます。

その間に、魔女から逃れる方法を考え、無事逃げることができるわけです。

このような、チャンスに対するリスク対応策を行うにあたっての行動は以下の4つ

  1. 活用
    チャンスを確実に活かす。資源投入により期間短縮をする。
  2. 共有
    チャンスを最も活かせる第3者にうまくやってもらう
  3. 強化
    チャンスが発生する確率や影響度を大きくし、利益を得られるようにする
  4. 受容
    チャンスなら利益を普通に受け入れる

アリとキリギリス

コミュニケーションの大事さ。計画と実績のズレの確認を繰り返しの重要さを説く章です。

価値観や考え方の違い

チームメンバーはみんな考え方や価値観が異なるため、理解するのが難しい局面というのはあります。

それにより、メンバー同士の距離感のようなものが生まれてしまうこともあります。

それを避けるためには、「相手と自分の立場や状況が違う」「基準となる考え方が違う」といったことを認識することが大事になります。

自分以外は自分とは違うということを認識する(コミュニケーションを通じて相手の価値観や背景をする)ことで情報共有の効率が飛躍的に上がります

問題解決に向けて

ミーティングの時間を厳守するなどの明確なルール決めにより無駄なミーティングを省いたり、シミュレーションをする上で、資源の制約や、スケジュールや見積もりをする中で新たな矛盾や課題が見えてきます。

そういった前段階として、チームと話合うことで対策や解決策を検討することができます。

 

そして、今後問題になりそうなところはチームと話し合うと言いましたが、聞くことで発見されることが多くあります。

メンバーの進捗には主観が入るものなので、その人の感覚でのスケジュールより、具体的な進め方、詰まった問題点など、より細かく聞くことにより詳細なスケジュールを作りやすくなります。

対応すべきか

問題があったとして、それを対処すべきか、緊急度はどうかというのも話し合うことが重要になります。

その中で、対応すべきと判断したものに対しては、しっかりアクションプランを立てることが重要になります。

具体的には、「誰が」「何を」「いつまでに」「どのレベルまで達成したら対応を終わりとするか」を明確にする。

長靴を履いた猫

人間関係に対して焦点を当てた章

第一印象

人は、言語的、聴覚的に理解できない場合、視覚的に理解することに重きを置くようになります。

そのため、見た目、ボディランゲージなどが重要になってきます。

そしてその時に受けた第一印象で人の印象がある程度決まってしまうので、ここで人間関係の一歩目となる印象を良くしておくということが重要になります。

自己開示

ジョハリの窓というものがあります。

  1. 自分は知っている
  2. 自分は知らない

といった二つの観点で分類した2*2のマトリックスを指します。

  • 解放の窓 - 自分も知っているし、相手も知っている
  • 盲点の窓 - 自分走らないが、他人は知っている
  • 秘密の窓 - 自分は知っているが、他人は知らない
  • 未知の窓 - 自分も知らないし、他人も知らない

この中で、解放の窓を広げていくことがコミュニケーション円滑への一歩になります。

まずそのためには、自分のことを知ってもらう必要があります。

そこで自己開示が重要となってきます。

長靴をはいた猫では、亡くなったお父さんとの思い出を、新しい主人と共有し、それをキッカケに共通理解を深めました。

このように同じ認識から広げていくという手段は有効そうです。

初対面の人の印象

信頼関係(ラポール)を構築することが重要になります。

  • 話し方や呼吸などのペースを合わせる(ペーシング)
  • 動作や姿勢、表情などのボディーランゲージを合わせる(ミラーリング
  • 適度なタイミングでの相槌、相手の話すことの繰り返し(バックトラッキング

を行うことで、自分の話を聞いてくれているという安心感や、理解してくれているという信頼感に繋がります。

話を聞く時の姿勢

自分の価値観や、経験を基に、何らかの返事をしようとしてしまうので、相手の話をしっかり理解するというのは実は難しいです。

そのため、自分の勝手な思い込みに左右されないで、相手基準で話を聞く姿勢が大事になります。

それには、「ありえるかもしれない」という気持ちで聞くのが良いです。

立場を理解する

立場が違う人の目線や、考え方は異なってきます。

人ぞれぞれに価値観があり、常識があるのと同様に、立場上変えざるをえない状況もあるでしょう。

そういう時の理解は難しいです。

そのために、相手の感情を理解することが重要になります。

相手の立場と状況を分かろうと努力し、何をすればこのコミュニケーションの目的を達成できるのかを考えることで、コミュニケーションをうまく行うことができます。

 

プロジェクトマネージャーの視点から見ると、各メンバーへの関心度を上げることになります。そうすることでメンバーそれぞれが当事者意識を持ちやすくなり、個人の行動に対するモチベーションが高まります。

そのため、プロジェクトマネージャーは個人の活躍によりどのようにプロジェクトが成功するのかというのを話し合うことが必要になります。

シンデレラ

ここでも、人との関わり方について説く章になります。

人との関わり方を分類分けする

関わり方を計画することが精神的ストレスにおいて重要になってきます。

そのために、ステークホルダー関与度評価マトリックスというものを作ります。

権力を縦軸に、関与度を横軸にしたマトリックスです。

シンデレラは、継母と2人の義姉に対して、このマトリクスを当てはめました。

  • 要求を満たし満足な状態を保つ
  • 注意深く対応する(最大限の努力)
  • モニターする(最小限の努力)
  • 情報を共有する

失敗の原因

多くの人は失敗の原因をまず自分のせい以外にします。

次のような原因があります。

「自分に能力がなかった」

「自分が努力しなかった」

「仕事が難しすぎた」

「運が悪かった」

この時、仕事が難しかった、や運が悪かったというのは失敗に対して恥ずかしいという気持ちがあります。これは悪循環に繋がります。

次も運が悪いかもなどの考えに陥りやすいです。

対して、努力が足りなかったと考えるようになると、次は頑張ろうというポジティブな考えになります。

これらを都合のいい風に捉えることで、自分のやる気を出すことにも繋がります。

余計な議論をしない

苦手な人や、合わない人というのは人間誰しもいると思います。

そういった人とも仕事をすることになることもありますし、避けられないことだとは思います。

ではどのように対処したら良いか。

まず、感情に振られないということです。イライラしながら接すると余計相手を不快にさせるだけで、状況が良くなることはありません。

シンデレラは継母とかと接する時、オウム返しや、一言だけ返答するなどを行いながら、余計な競争や議論をしないコミュニケーションをするようにしました。

まとめ

当書のイメージとしては、ページ数は多かったのですが、童話も挟まっていたり、文字も大きかったりでとても読みやすい本という印象でした。

比較的読みやすい本な上に、しっかり重要なポイントを抑えていてくれたので勉強になりました。

自分はマネジメント系やチーム、組織系の本はこれで4冊目になるのですが、1冊目の方でもスムーズに入っていけるのではないかなと思いました。

The Team

 

概要

前回に引き続き、マネージャーとしての働きに合わせて、チームでの働きについての知識をつけようということで読み始めました。

学んだ事をまとめておこうと思います。

読んだ感想としては、チーム、いわゆる組織の生産性を上げるためにはチーム一人一人のモチベーションを上げることを題した、モチベーションエンジニアリングが必要という言葉は

 

エンジニアリング組織論への招待でもあった

エンジニアリング = 不確実性の解消

にも繋がる言葉になると思います。

 

チームの生産性という不確実なものに対してのアプローチとしてのエンジニアリングとなります。

「偉大なチームには、偉大なリーダーがいる」
のではなく、

偉大なチームには、法則がある
という言葉の通り、法則によって生産性を上げていくアプローチが記述されています。

 

 

チームとは

2人以上の集団のことをグループという。

グループに共通の目的を作ることで「チーム」と呼びます。

この共通の目的を目標とし、**全員が同じ方向を向くこと**が条件となります。

目標を適切に設定することが良いチームになります。

AIM

チームのパフォーマンスのための
活動意義・成果・行動・目標の繋がりなどの役割について

目標の設定

3つの目標を用意し、チームメンバーという立場から見て、
それぞれの役割のメリットを理解する必要があります。

  • 行動目標: 具体的な行動から影響を与えるが、影響力は低い
  • 成果目標: 行動目標を達成した時に得られるもの、影響力はより大きくなる
  • 意義目標: 最終的に達成される目標、ここでは具体的な行動までは落とし込めていないが影響力は高い

ここでの例は、少しスケール的には小さいものですが

  • 意義目標に「エンジニア同士の交流を深めていきたい」と定義します。
  • 成果目標に「交流するイベントを開催する」と定義します。
  • 行動目標に「イベントの内容や段取りを考える」と定義します。

最終的に、エンジニア同士の交流は、イベントを通して達成されることになります。

このように、それぞれが持つ役割とメリットを理解しておくことで、メンバーが実際に行う時の指標となります。

これら目標の一つだけしか頭にないと、メンバーから出てくる意見に偏りが発生する。

これがビジネスの世界になると、行動目標のみに囚われることにより、
後述する「チーム全体の雰囲気」へ影響を及ぼし負の循環に繋がる可能性が高くになります。

変化のスピード

特に昨今のビジネスの変化スピードにより、これまで良かったと思われていた方法がベストでなくなるという事も早くなります。
そうなった時に、行動目標のみ想定していたら、柔軟な変更に対応できなく、変更に対して大きな振れ幅が発生します。

意義目標がしっかり定められていれば、取るべき行動への柔軟な変化を可能にします。
個人の責任により、意義目標を定めることができるようにすることで、このスピードの変化に対応できるようになります。

これには、個人が自発的に行動するチームが必須ということになります。

BOARDING

チームにおいて人員は非常に重要なファクタになります。
そのための人員選定について

4つのタイプ

チームのタイプは4つに分かれますが、
分類するために2つの軸があります。

  • 環境の連携度合い: 高いと状況の変化に合わせて行動を変更する度合いが高まる。
  • 人材の連携度合い: 高いと同じ時間に行動する度合い高まる
環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
メーカーの工場 生命保険の営業 飲食業の店舗スタッフ スマホアプリの開発チーム

といった分類分けができます。

人の入れ替わり

人の入れ替わりが多いチームは悪いかどうかについては、チームのタイプによります。

  • 環境の変化が小さいチームでは、人の入れ替えは少ない方が良い
  • 環境の変化が大きいチームでは、人の入れ替えがあった方が良い

チームの多様性

チームには多様なメンバーがいる方がいいについては、チームのタイプによります。

特に現代だと、新卒一括採用といった体系が少しずつなくなりつつあるため、
似たメンバーで揃えるといったことせず、変化の激しいビジネスシーンでは異なるメンバーを揃える流れがあります。

  • 人材の連携度合いが小さいと、似たメンバーが揃っていた方が良い
  • 人材の連携度合いが大きいと、異なるタイプのメンバーの方が良い

COMMUNICATION

コミュニケーションにおいて重要なことは
「ルール作り」です。

 

コミュニケーションのルールが高いとコストがかかり、また精緻すぎてもコストが高くなります。

 

その間の区間を見極めることが大事になります。

 

そして大事なこととして、**コミュニケーションは少ない方が良い**です。

  • 人材の連携度が小さいチームは、ルールを細かくする必要はない
  • 人材の連携度が大きいチームは、ルール化しないとコミュニケーションが大きくなりがち

では、ルールはどのように作った方がいいのでしょう。

ルール作り

ルールを増やすか、減らすか

環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
中間 少ない方が良い 中間 多い方が良い

誰が決めるか

環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
チームと話し合いながら 自分で決める 中間 リーダーが決める

どこまで責任を負うか

環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
個人成果に責任を負う 中間 チーム成果に責任を負う 中間

何を評価するか

環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
中間 成果を評価 中間 プロセスを評価

どれくらい確認するか

環(低) & 人(低) 環(高) & 人(低) 環(高) & 人(高) 環(低) & 人(高)
確認が少ない 中間 確認が多い 中間

感情によってコミュニケーションが阻まれる

簡潔であればあるほど、内容に密度が生まれます。

そういったコミュニケーションは、無駄を省いた意思の伝達ができます。

 

しかし、これは無駄話をするなという意味ではなく、

意志の伝達に無駄な情報を含ませても意味がないという意味です。

 

無駄な情報を含ませた伝達をおこなったとしても、メンバーが動かないことはあります。感情によって、「自分なんかが」といったネガティブな感情により行動が制限されてしまうので、誰がどのタイミングで言ったかが重要になります。

無駄を含んでも大丈夫な場合

まずは理解に専念することです。

 

自分が理解されたと感じた人は、その人のことを理解しようとします。

 

そこで信頼関係が生まれます。

 

まず理解することを行うために、必要なのが無駄を含めて、その人の人となりを理解することに努めることです。

 

ここで、重要なワードは、チームメンバーの

  • 経験
  • 感覚
  • 志向
  • 能力

そして、そのメンバーの人生を知ることが近道になります。

 

何を頑張ってきたか、何を目的にしてきたかを理解することで

 

何かを頼む時の言葉に信憑性を持たせることができます。

 

例: 「〜さん、このタスクをお願いできますか。」ではなく、「〜さんは、過去にこういった経験があるから、このタスクをうまく回せそうな気がするので、お願いできますか」など

 

以下の指標などが

モチベーションタイプ

  • アタックタイプ
  • レシーブタイプ
  • シンキングタイプ
  • フィーリングタイプ

ポータブルスキル

  • 対自分
    • 外交的スキル 
      • 決断力
      • 曖昧力
      • 瞬発力
      • 冒険力
    • 内向的スキル
      • 忍耐力
      • 規律力
      • 持続力
      • 身長力
  • 対人力
    • 父性的なスキル 
      • 主張力
      • 説得力
      • 統率力
    • 母性的なスキル
      • 傾聴力
      • 受容力
      • 支援力
      • 協調力
  • 対課題力
    • 右脳的なスキル
      • 試行力
      • 変革力
      • 発想力
    • 左脳的なスキル
      • 計画力
      • 推進力
      • 確動力
      • 分析力

昨今の状況

昔だと、新卒一括採用などの影響で、同じ考え、同じ思想を持つ人同士が被る事が多かったため、コミュニケーションは最小限で抑えられていた部分がありますが、

最近のビジネス傾向的に、いろんな人材を入れることで多様性を図り、その中で新しいアイディアを生み出していくという企業が増えてきているため

コミュニケーションというのが重要なファクタの一つになっている傾向があります。

 

そうした解決策の一つとして、1on1のような形式で、社員と話をすることが今後のビジネスにおいて、より重要なになっていくように思われます。

その中で心理的安全性*1といったものを担保していく必要があります。

DECISION

誰が意思決定をするかは、物事の行末を決めるのに大きな影響を与えます。

3つのタイプが存在し、それぞれが適切な形で決定権として使われるのが良いです。

  1. 独裁
  2. 多数決
  3. 合議

独裁はよくないのではないかという誤解

それぞれの決定権には、一長一短があるので「独裁は選択肢としてはあるが、実行するには良くない」といった先入観はない方がいいです。

 

それぞれの決定権によって、主に影響するのは

  • メンバーの納得感の得やすさ
  • 意思決定にかかる時間の長さ

に影響を与えます。

独裁は、意思決定者が1人になるため、意思決定にかかる時間は著しく短いです。

一方、合議に関しては、メンバーの意思決定が関与するため、納得度が高くなる傾向になりますが、その分時間もかかります。

このように、どのタイミングで誰が意思決定をするかというのを決めておかないと、要らぬところでストレスを抱えることになり、チームとして健全とは言えない状態になり得ます。

KT法

ケプナー・トリゴー・ラショナル・プロセス

という方法があります。

次のステップを踏まえる事により、納得感を得た状態で、スピーディに結論に至る事ができるというものです。

  1. 状況把握
  2. 決定分析
  3. 潜在的問題・潜在的好機 分析

まず、意思決定には選択肢を提示するというところから始まりますが

この選択肢に対し、基準を設けます。

その基準に対し、優先順位をつけ、最後に優先基準が高く合致するものを選んでいくという方法になります。

 

いきなり、選択肢同士を比較から始めてしまうのは良くなく、まずは選択肢がなぜ選ばれて、今の問題に対する優先順位をつけ、それぞれを表に表すところが鍵となります。

 

明確な判断がすぐにつかない選択

明確に、100:0でメリデメがはっきりしている選択に対しては悩むことはありませんが、49:51などで揺れている選択肢に対してのアプローチとして

 

えいやっと決めてくれる意思決定者がいることの方が素早い結果を得られることになります。こういう問題にあったとき、30分かけて出た答えと、5秒で出した答えというのは86%が同じ答えらしいです。

なので、まず1%でも高い方を選び、少しでも実行時間をかけて精密に比較ができるようになった方が後々的には有意義ということになります。

51%しかなかったメリットを70, 80%と引き上げる実行に時間を使った方が良いでしょう。

こういった決断を独裁的に決めてしまうことはメリットになります。

影響力

決定には、誰が決定したかの影響力も大きく関係します。

重要な点は5つあります。

  1. 専門性
  2. 返報性
  3. 魅了性
  4. 厳格性
  5. 一貫性

ENGAGEMENT

どんな人でも(プロフェッショナルだとしても)、モチベーションに左右されることはあります。

そういった時に、チームとしてどういうものがあるか。

個人であれば、大変な仕事だけどその分給料が良いなどの動機などがモチベーションにダイレクトに影響するものだと思います。

この動機の高さやモチベーションによる貢献度のことをエンゲージメントと言います。

チームとしてのモチベーション

4つの概念があります。

  1. Philosophy(理念・方針)
  2. Profession(活動・成長)
  3. People(人材・風土)
  4. Privilege(待遇・特権)

活動自体に魅力があるものは、Professionに分類されます。

雰囲気や文化に魅力があれば、Philosophyに分類されます。

その文化の中で、気があう人などがいるとかであれば、Peopleに分類されます。

さらにその中で、自分にとって有意義な利権が得られそうであれば、Provilegeに分類されます。

自分がどこに魅力を感じるかを分析することは重要です。

何に注力すべきか

とは言っても、全てを魅力的にすることは企業としては不可能に近いです。

時間や人員などのリソースは有限だからです。

 

では、どうするべきか。

配分が重要になります。

一つの魅力に絞って、それに対して共感を得られるメンバーを募ることが重要になります。

求人などを見て、企業ごとにどこに注力しているかを見てみるのはいいかもしれないです。

 

その注力しているものがその会社の文化となり、自分がストレスなく働けるかにつながっていきます。

総エンゲージメントを高めるためには、広く高い人を集めるのではなく、一つの魅力に対して特化させた方が、高めやすいということになります。

エンゲージメントの方程式

エンゲージメント = 報酬・目標の魅力(やりたい) * 達成可能性(やれる) * 危機感(やるべき)

 

それぞれを

  • will
  • can
  • must

と言い換えることができます。

willは、目標

canは、具体的行動

mustは、できなかった時のペナルティ

として捉えられます。

 

当事者意識

当事者意識が高められるチームが理想系になります。

「自分1人くらい…」という意識を無くすことになります。

 

どうするか。

 

ポイントは3つ

  1.  人数
    単純に人数が多いと、自分1人くらいと思ってしまう割合が増えてしまう点
  2. 責任
    責任の所在をハッキリさせる点
  3. 参画感
    意思決定が自分の関係のないところで進んでいるなどにより、他人事のように感じてきてしまうという点

チームの雰囲気をマネジメントする

1人に意見が同調してしまうことや、みんなの意見に同調してしまうという現象により、ネガティブな雰囲気というのは広がりやすいです。

ポジティブな雰囲気をキープするには、二つのポイントがあります。

  1. スポットライト
  2. インフルエンサー

スポットライト - ポジティブな人に光を当てることで、その考えを持つ人がメジャーなチームという雰囲気を広める

インフルエンサー - チームの影響力が高いメンバーに働きかけ、転換させることで雰囲気をマネジメントする

まとめ

チームの方向性であったり、雰囲気というのは誰かがやるべきものというわけではなく、「メンバーそれぞれが持つべき意識」ということです。

もちろん、それぞれの責任、責務があるのでできることなどの制限などはありますし、制限は設ける必要のあるものです。

しかし、その中でもやはり自分とチームの相性であったり、これからチームをどうしていくかの心持ちによって雰囲気や方向性はいくらでも変わるものだと思います。

 

チームを強固なものにするのは、上司やリーダーだけでなく、メンバー全員にそういった権利はあるということを伝えたかったのではないかと思います。

人と一緒に働く、それ以外にも人と活動を行うというチーム戦全てに対して有効的な効果があると思うので、この本にあることを少しずつでも意識して実践していくというのは長い人生の中での良い資産になるのではないかと思いました。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*1:心理的安全性については、また別の記事にしようかと思います。