Jekyll2024-02-14T04:53:34+00:00https://aloerina01.github.io/feed.xmlmille-feuille codeWeb Developer。同じような過ちを繰り返さないように備忘録を残しています。
マネージャーやリーダーからチームメンバーへの仕事の任せ方、裁量の渡し方2023-05-22T00:00:00+00:002023-05-22T00:00:00+00:00https://aloerina01.github.io/blog/1<p>チームのリーダー、エンジニアリングマネージャー、新入社員のメンターなどの役割をすると、『チームメンバーにどのように仕事を任せるか』と考えることがあります。特にそれなりにスキルがあるチームメンバーに対してこれを考える場合、『どれくらい/どのように裁量を渡すか』がポイントの一つです。</p>
<p>私がマネージャーとしてチームメンバーに仕事を任せるとき<strong>『その仕事をどのように進行しどのように完了させるか(何を持って完了とするか)』を決める裁量を渡す</strong>方針であり、その旨をチームメンバーに重ね重ね伝えています。</p>
<p>以下はチームメンバーとの実際のコミュニケーション例です。</p>
<div class="note">
<p>
「あなたが開発案件を担当するとき、仕様に対してどのようにプランナーやデザイナーとすり合わせるか、どう設計しどれだけ実装の風呂敷を広げるか、どのように見積もりどう進行するか、など幅広い裁量があります。
</p>
<p>
とはいえ、必ずすべてに責任を持てという意味ではありませんし、やり切らないと期待に沿えないという意味でもありません。<strong>なるべく広めに裁量を渡すので、その中で自身できるものを選びとりながら</strong>仕事を進めてください。分からない部分やできないと感じた部分は自分に投げ返してください。
</p>
<p>
<strong>私は広く裁量を渡す、あなたは一部の裁量を担う/返す、とラリーを重ねながら</strong>できることを増やしていったり得意分野を見つけたり、新しいチャレンジをしていきましょう。」
</p>
</div>
<h3 id="裁量をうまく活用してもらうための工夫">裁量をうまく活用してもらうための工夫</h3>
<h4 id="1-チームのフェーズやタスクの期限を考慮する">1. チームのフェーズやタスクの期限を考慮する</h4>
<p>前提として、チームが締切に追われ続けている自転車操業状態ではこの裁量の渡し方は不可能です。またお願いするタスクの期限が厳密である場合や、満たすべき要件が多い場合にも難しいでしょう。<br />
今までにない広い裁量の中で冷静に選択や決断をしていくためには、仕事を受け取ったチームメンバーが<strong>時間と心の余裕を持てていること</strong>が大切です。</p>
<h4 id="2-必要に応じてこちらの期待値を添える">2. 必要に応じてこちらの期待値を添える</h4>
<p>広く裁量を渡すと言っても、一言も口出ししてはいけないということではありません。たとえば「実装方針について自身で考えてみてほしいが、最終的にはチームの合意を得てほしい」と条件をつけることもあります。<br />
また「この前の取り組みを資料にまとめてほしい。どんな構成にすべきか私もまだイメージできていないので、何度かレビューのやり取りが続いてしまうかもしれない」とある程度レビュー回数が多くなることを事前に申し添えることもあります。</p>
<p><strong>裁量を渡されたチームメンバーが、どれだけ自由な選択ができるのか、もしくは何かしらの制約があるのかを理解して仕事に臨める</strong>状況をつくることを心がけます。事前にすべてを伝えるのは難しいので条件を後出ししてしまうこともありますが、その可能性を最初に伝えておくだけでも多少良いかもしれません。</p>
<h4 id="3-ペアアサインやチームアサインをする">3. ペアアサインやチームアサインをする</h4>
<p>広い裁量の中で選択や判断を重ねて仕事を完遂することは、人によって難易度の感じ方が違いますし、取り得る選択肢も違います。難しいと感じる人にはいくつかの選択肢やヒントをマネージャーが提案しフォローすることもできますが、私はそれよりも好きな手段があります。裁量をペアやチームに対して渡す方法です。</p>
<p>人により得手不得手が違うので、<strong>補い合ったりアイデアを出し合ったりして裁量を存分に活かせるケースが多く、私には思いもよらない素晴らしいアウトプットが出ることもある</strong>ので仕事をお願いするときのちょっとした楽しみでもあります。</p>
<p>注意点ですが、あんまり人数が多いと何もしない人を生みかねないので、複数人アサインは2〜3人がベストだと思います。また、チームメンバー同士でうまく相互作用が起きているのは、私たちのチームがこれまでにモブプロやふりかえりなどを重ね複数人でワークすることに慣れていたからかも、と注釈しておきます。複数人での仕事に不慣れなチームだと、誰かがリーダーとなり「仕事を分担する人、言われた通り分担をやる人」の関係になってしまい全員が裁量を活かせてるとは言えない結果となってしまうかもしれません。</p>
<h3 id="おわりに">おわりに</h3>
<p>今となっては当たり前でも、マネージャーになったばかりの頃はどうしていいか見当がつかなかったことが山程あったので、それらを思い返しながら言語化しました。こういった細かいTipsを今後も書いていきたいところです。</p>
<p>マネジメントのやり方はメンバーの数だけ(もしくはそれ以上に)あるので、引き出しの多さはマネージャーのスキルを考える上で重要な要素の一つです。過去の手札をまったく同じように使い回すことは難しくとも、それらを組み合わせたり、それらに着想を得て新しい手段を取ったりできます。自分のためにも手札を見える形で残しておきたい思いがあって書きまとめましたが、新任マネージャーのどなたかのお役に立てれば何よりです。</p>チームのリーダー、エンジニアリングマネージャー、新入社員のメンターなどの役割をすると、『チームメンバーにどのように仕事を任せるか』と考えることがあります。特にそれなりにスキルがあるチームメンバーに対してこれを考える場合、『どれくらい/どのように裁量を渡すか』がポイントの一つです。「来月からエンジニアリングマネージャーやってね」と言われたら2022-12-16T00:00:00+00:002022-12-16T00:00:00+00:00https://aloerina01.github.io/blog/1<p>タイトルのように「来月からエンジニアリングマネージャーやってくれませんか」と言われた経験が私にもあります。もう3〜4年くらい前のことです。おそらく多くのエンジニアと同じように当時の私はマネジメント業に興味がなく、マネージャーになってみたものの何から手を付ければ良いかも分からず、とりあえずチームメンバーとの1on1をセッティングしてみたりしました。</p>
<p>まさしく”レベル1”だった私ですが、いくらか経験を積み、今では見える景色や解像度が変わるくらいにはレベルアップした実感があります。</p>
<p>当時に戻れるならこんなふうにマネジメント業務に取り掛かろう、というイメージが具体的に持てるようになったので、今回はそれを言語化してみようと思います。少しレベルアップした自分から、レベル1だった当時の自分へのアドバイスのつもりで書いてみます。</p>
<p>※ちなみに数人のエンジニアで構成されるチームのエンジニアリングマネージャーを任された場面を想定してます。</p>
<ul id="markdown-toc">
<li><a href="#まえおき" id="markdown-toc-まえおき">まえおき</a></li>
<li><a href="#1-帽子のかぶり直しには時間がかかることを理解する" id="markdown-toc-1-帽子のかぶり直しには時間がかかることを理解する">1. 帽子のかぶり直しには時間がかかることを理解する</a></li>
<li><a href="#2-名前のある仕事や日々進捗が出る仕事はごくわずかだと理解する" id="markdown-toc-2-名前のある仕事や日々進捗が出る仕事はごくわずかだと理解する">2. 名前のある仕事や日々進捗が出る仕事はごくわずかだと理解する</a></li>
<li><a href="#3-マネージャーへの期待値を理解しチームを観察する" id="markdown-toc-3-マネージャーへの期待値を理解しチームを観察する">3. マネージャーへの期待値を理解し、チームを観察する</a></li>
<li><a href="#参考書籍" id="markdown-toc-参考書籍">参考書籍</a></li>
<li><a href="#まとめ" id="markdown-toc-まとめ">まとめ</a></li>
</ul>
<h3 id="まえおき">まえおき</h3>
<p>当時の自分に伝えたいことは山程ありますが、まずはマネージャーになりたての時期を想定し、<strong>具体的なアクションよりも、考え方や向き合い方について</strong>触れていこうと思います。<br />
マネージャーになった以上1on1をしたりアサインをしたり指示出しをしたり……と業務内容をガラッと変えて成果を出さねばと当時は焦っていましたが、<strong>焦って行動を変えてもなかなか結果が追いつかない</strong>ことのほうが圧倒的に多かったです。”名実ともに”マネージャーになるために、まどろっこしいかもしれませんが<strong>まずは考え方のシフトから</strong>始めてみるのはいかがでしょう。</p>
<h3 id="1-帽子のかぶり直しには時間がかかることを理解する">1. 帽子のかぶり直しには時間がかかることを理解する</h3>
<p>それまでチームメンバーだった自分が今日からマネージャーになるということは、<strong>『チームメンバー』の帽子から『マネージャー』の帽子にかぶり直しをする必要があります</strong>。そして帽子をかぶり直したことを自分と周囲の全員が真に理解するには時間がかかります。被り直しが浸透しきっていない例を体験談をもとに挙げてみます。</p>
<p>1つ目の例では、チームメンバーとの会議の場で、私が「〜〜したい」と意思表示をした場面を思い返してみます。私はチームメンバーと対等な目線で(『チームメンバー』の帽子を被って)アイデアを<strong>提案したつもり</strong>でいたものの、チームメンバーには<strong>マネージャーからの指示</strong>だと伝わってしまっていました。このとき私は、周囲から「マネージャーの帽子被っている」と認識されていることを理解していませんでした。私自身が帽子のかぶり直しを自覚できていなかった例です。</p>
<p>もう1つ例を挙げます。当時私は業務上必要な指示/依頼をする行為を、偉そうな行為と捉え抵抗感を抱いていました。今であれば誠実さや敬意の有無こそが大事だと分かりますが、当時は「何様だ!」と思われないかソワソワしていたのだと思います。この例は、<strong>頭では帽子のかぶり直しをしたことを理解した</strong>上で指示/依頼業務に臨んでいたものの、<strong>感情が追いつかずにいた</strong>例です。<br />
また、チームメンバーのほうが感情が追いつかず「先日まで同僚だったお前になぜそんなこと言われなきゃならないんだ!」と反発してしまうケースも起こり得るでしょうし、チームの代表として他部署の人と会話をしようとしても対等に扱ってもらえないケースもあり得るでしょう。</p>
<p>これらの例をまとめるとこんな感じです。
<img src="/assets/2022-12-13-1.jpeg" alt="被り直しができていないパターン一覧" /></p>
<p>帽子のかぶり直しは<strong>自分自身だけでなく周囲の人にも認識してもらう必要があります</strong>。まずは自分自身が帽子のかぶり直しを意識し行動し、それを積み重ねて少しずつ周囲にも頭で理解し心で納得してもらうことが必要です。感情の問題がある以上、時間をかけることでしか解決できないと割り切って、<strong>徐々にマネージャーになっていく</strong>つもりで日々の業務に臨むと良いと思います。</p>
<h3 id="2-名前のある仕事や日々進捗が出る仕事はごくわずかだと理解する">2. 名前のある仕事や日々進捗が出る仕事はごくわずかだと理解する</h3>
<p>マネージャーになると、自分の成果をうまく自覚できず不安や焦りを覚えることがあります。私は今でもあります。その理由は、<strong>分かりやすい名前が付く仕事が少ない</strong>からと、<strong>短期間で進捗する仕事がほぼない</strong>からだと考えています。逆に言うとそれまでのエンジニアリング業務は、名前を付けやすく短期間で進捗が見える業務が多いので「今なんの仕事をしているか」がはっきりしていました。たとえば</p>
<ul>
<li>昨日は5件バグフィックスした</li>
<li>昨日は10コミットした</li>
<li>次のリリースに向けて〇〇機能を実装している</li>
</ul>
<p>といった具合に、作業内容を具体的に表現しやすく、成果を実感しやすいです。</p>
<p>一方でマネジメント業務では</p>
<ul>
<li>プロダクトやチームメンバーの状況を観察する</li>
<li>今後の方針について考える</li>
</ul>
<p>と、なんとも地味な時間の使い方になりがちです。もちろん長期的に見たらこの積み重ねがインパクトのある大きな成果に繋がるのですが(そこが面白さでもありますが)、<strong>昨日と今日の差分を測るのが非常に難しい</strong>です。<br />
私が日頃している仕事で名前のある仕事と言ったら『1on1』『採用面接』『ミーティングファシリテーション』くらいです。それ以外の時間は<strong>情報収集しているか、チームメンバーを観察しているか、次のアクションを考えているか</strong>といった無名のタスクをしています。</p>
<p>進捗の見えにくい仕事ばかりしていると「何もしていないのではないか」「自分は役に立っていないのではないか」と不安になります。分かりやすい成果が欲しくて、チームビルディングのイベントを企画したり、コードを書きたくなることもあります(もちろんそれらが悪いことではなく、本来マネージャーとして優先すべきことをせずに<strong>目先の達成感のために仕事を選ぶのが良くない</strong>ということです)。</p>
<p>そんなとき私は一呼吸おいて、マネジメント業務とは名前のある仕事や日々進捗が出る仕事が少ないものだと思い出すようにしています。マネージャーがチームと向き合って第一にすべきことは、そしてし続けるべきことは、<strong>チームメンバー1人1人を観察し、こまめにフィードバックし、チームとしての成果を高め続けていくこと</strong>です。1日観察したからといって成果は出ないですが、1日観察をサボればフィードバックの機会を1つ逃すことになるかもしれません。長期的な成果や目標を目指して辛抱強くマネジメントしていくことが大切です。</p>
<h3 id="3-マネージャーへの期待値を理解しチームを観察する">3. マネージャーへの期待値を理解し、チームを観察する</h3>
<p>マネジメント業務とは、極端に言えば「上手く成果を出すために何でもする」ことです。言い換えると、<strong>状況に応じて具体的なタスクが変わる</strong>ということです。ですので、<strong>自分をマネージャーに任命した上長が自分に何を期待しているのかを理解する</strong>ことが、行動のヒントになります。</p>
<p>例えば、毎日締め切りに追われて疲弊しきったチームが健全に働けるよう立て直してほしいとか、はたまた前任のマネージャーによってある程度自己組織化されたチームを引き継ぐことで少しずつマネジメント業務に慣れてほしいとか。そういった期待を理解すると、自分がどんなマネジメントをすべきかの糸口が見えてくると思います。もし既に頭の中にその方向性がある場合でも、上長やチームメンバーが自分に望むことと照らし合わせれば、より確度を高められるはずです。</p>
<p>そして、周囲からの期待にせよ、マネージャーの業務内容にせよ、<strong>『チームの状態』に依って決まることが多い</strong>です。上述の例では「疲弊しきったチーム」と「自己組織化されたチーム」が登場し、それに依ってマネージャーへの期待内容が変化しています。チームの状態を適切に把握できれば何をすべきかが見え、期待内容も理解しやすいということです。</p>
<p>それを踏まえて、当時私が参考にしていた<strong>チームの状態を理解するための3つの指標</strong>を紹介します。</p>
<ol>
<li>チームに時間や心のゆとりがない<strong>サバイバルフェーズ</strong></li>
<li>十分な時間やゆとりがあり、その時間を使って学習や検証を行っている<strong>学習フェーズ</strong></li>
<li>自分たちの問題を自力で解決し変化し続けている<strong>自己組織化フェーズ</strong></li>
</ol>
<p>今の自分たちはどのフェーズにいるのかじっくり観察し見極めることで、次にすべきことが見えてくるかもしれません。チームの状態を測る指標はこれ以外にもたくさんありますが、まずはお手軽な3フェーズに分けて観察するだけでも十分ヒントが得られると思います。</p>
<h3 id="参考書籍">参考書籍</h3>
<div class="amazon-link-container">
<div class="amazon-link-body">
<div class="amazon-link-image">
<a href="https://www.amazon.co.jp/%E3%82%A8%E3%83%A9%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97-%E2%80%95%E8%87%AA%E5%B7%B1%E7%B5%84%E7%B9%94%E5%8C%96%E3%83%81%E3%83%BC%E3%83%A0%E3%81%AE%E8%82%B2%E3%81%A6%E6%96%B9-Roy-Osherove/dp/4873118026?keywords=%E3%82%A8%E3%83%A9%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97&qid=1671075668&sprefix=%E3%81%88%E3%82%89%E3%81%99%E3%81%A6%E3%81%83%E3%81%A3%E3%81%8F%E3%82%8A%E3%83%BC%E3%81%A0%2Caps%2C377&sr=8-1&linkCode=li2&tag=aloerina09-22&linkId=68586bb84c53d51c6f606ae553e20cbe&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4873118026&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aloerina09-22&language=ja_JP" /></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aloerina09-22&language=ja_JP&l=li2&o=9&a=4873118026" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</div>
<div class="amazon-link-border"></div>
<div class="amazon-link-label">
<span>エラスティックリーダーシップ 自己組織化チームの育て方</span>
<a href="https://amzn.to/3WaenlU" target="_blank">Amazon.co.jp で購入する</a>
</div>
</div>
</div>
<p><strong>エラスティックリーダーシップ 自己組織化チームの育て方</strong><br />
上で紹介した3つのフェーズはこの本で紹介されていました。それぞれのフェーズをどう見極めるか、どう対処するかが詳しく書かれています。タイトルには「リーダーシップ」とありますが、マネジメントにも通ずる内容、むしろマネジメントとして取り組むべき内容だと思います。マネジメント入門期に読んでもためになりましたし、今読み返しても気づきが得られているので、繰り返し読んで参考になる本です。</p>
<div class="amazon-link-container">
<div class="amazon-link-body">
<div class="amazon-link-image">
<a href="https://www.amazon.co.jp/EQ%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97-%E6%88%90%E5%8A%9F%E3%81%99%E3%82%8B%E4%BA%BA%E3%81%AE%E3%81%93%E3%81%93%E3%82%8D%E3%81%AE%E7%9F%A5%E8%83%BD%E6%8C%87%E6%95%B0%E3%81%AE%E6%B4%BB%E3%81%8B%E3%81%97%E6%96%B9-%E3%83%80%E3%83%8B%E3%82%A8%E3%83%AB-%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%9E%E3%83%B3/dp/4532149754?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=14OKULLVD14FV&keywords=eq%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97&qid=1671009538&sprefix=eq%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97%2Caps%2C161&sr=8-1&linkCode=li2&tag=aloerina09-22&linkId=4882c154a9da157651954bf44f019b78&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4532149754&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aloerina09-22&language=ja_JP" /></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aloerina09-22&language=ja_JP&l=li2&o=9&a=4532149754" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</div>
<div class="amazon-link-border"></div>
<div class="amazon-link-label">
<span>EQリーダーシップ 成功する人のこころの知能指数の活かし方</span>
<a href="https://amzn.to/3Pxvr31" target="_blank">Amazon.co.jp で購入する</a>
</div>
</div>
</div>
<p><strong>EQリーダーシップ 成功する人のこころの知能指数の活かし方</strong><br />
あまりメジャーな本ではないのですが、個人的に気に入っています。こちらもタイトルに「リーダーシップ」とありますが、この本ではマネージャーのスキルとしてのリーダーシップが説明されています。チームの状況に応じた6つのリーダーシップが紹介されていて、レベル1の頃に私が抱きがちだった「マネージャーなら〇〇しなきゃ」といった固定観念から解放してくれて、マネジメントの多様性を理解する手助けになりました。</p>
<h3 id="まとめ">まとめ</h3>
<p>「マネージャーになったし1on1もしっかりやってメンバーのキャリアもいっぱい考えて開発プロセスもいい感じにしてコード品質も高めて……それからそれから……」と意気込んでスタートしたものの、1ヶ月経っても何も変わってないしマネージャーとして頼られることもないし、どうやってマネージャーとして踏み出せば良いんだ……。<br />
と悩んだ記憶をたどりながら、当時の自分に向けたアドバイスを書きました。<strong>とにかく焦らず、少しずつマネージャーになっていくんだぞ</strong>、というのが一番の思いです。</p>
<p>……なんて大げさにメッセージを残してみたものの、まだまだマネージャーとして道半ばです。チームのフェーズによってマネジメントタスクが変わると書きましたが、比較的得意なフェーズと苦手なフェーズがあったりもします。様々なシチュエーションを経験し試行錯誤をしながら手札を増やしていくという点では、レベル1だった頃と変わりません。そういった意味でも、やはり焦らず少しずつ前進するしかないのだと思います。</p>
<p>感想はぜひ<a href="https://twitter.com/aloerina_" target="_blank">@aloerina_</a>までよろしくお願いします。それでは、良いお年を。</p>タイトルのように「来月からエンジニアリングマネージャーやってくれませんか」と言われた経験が私にもあります。もう3〜4年くらい前のことです。おそらく多くのエンジニアと同じように当時の私はマネジメント業に興味がなく、マネージャーになってみたものの何から手を付ければ良いかも分からず、とりあえずチームメンバーとの1on1をセッティングしてみたりしました。スクラムチームがぶち当たる「相対見積もり」の壁と、私たちの乗り越え方2021-10-29T00:00:00+00:002021-10-29T00:00:00+00:00https://aloerina01.github.io/blog/1<p>これまでエンジニアやスクラムマスターとしてスクラムチームに関わって来ましたが、その過程で何度も「相対見積もり」や「ストーリーポイント」に纏わる悩みにぶち当たってきました。工数や期間での見積もりに慣れていた私にとって、それらは理解も実践もしにくい手強いものでした。</p>
<p>今回は、私が実際に直面した問題と、それらを打破するためチームで取り組んできたことを思い返してみようと思います。</p>
<ul id="markdown-toc">
<li><a href="#壁1-相対見積もりの考え方を理解できない" id="markdown-toc-壁1-相対見積もりの考え方を理解できない">壁1. 「相対見積もり」の考え方を理解できない</a></li>
<li><a href="#壁2-ストーリーポイントが何を見積もる手段かを理解していない" id="markdown-toc-壁2-ストーリーポイントが何を見積もる手段かを理解していない">壁2. ストーリーポイントが「何を見積もる手段か」を理解していない</a></li>
<li><a href="#壁3-見積もりをコミットメントと捉えてしまう" id="markdown-toc-壁3-見積もりをコミットメントと捉えてしまう">壁3. 見積もりをコミットメントと捉えてしまう</a></li>
<li><a href="#まとめ" id="markdown-toc-まとめ">まとめ</a></li>
</ul>
<h3 id="壁1-相対見積もりの考え方を理解できない">壁1. 「相対見積もり」の考え方を理解できない</h3>
<p>バックログ上に積まれたユーザーストーリーやエピックを見積もろうとしたとき、私たちは真っ先に「こんなコンポーネントを新規実装するだろう、おそらく2日くらい掛かる」「あの既存機能をいじる必要があるが、複雑な箇所なので時間がかかりそうだ」と<strong>具体的な作業内容とそれにかかる時間をセットで</strong>イメージしていました。それらを足し合わせて(さらにバッファを加えて)最終的な見積もりを出していました。</p>
<p>しかし、これは相対見積もりではありません。</p>
<p><strong>相対的に見積もるには、過去に取り組んだ仕事を基準とし、その仕事との比較で考える</strong>必要があります。ストーリーポイントで見積もるにせよ、日数で見積もるにせよ、です。<br />
これを理解し体に馴染ませるために、見積もりの度に「このストーリーは(基準としている)あの仕事と同じくらい? 倍くらい? 半分くらい?」と聞き合うようことを繰り返しました。今では基準と比較することにも慣れてきましたが、長いこと苦戦した問題でした。苦戦した要因は、次の『壁2』で紹介する問題と合わさって、相対見積もりをより難しく捉えていたからでもあります。</p>
<h3 id="壁2-ストーリーポイントが何を見積もる手段かを理解していない">壁2. ストーリーポイントが「何を見積もる手段か」を理解していない</h3>
<p>ストーリーポイントの考え方は、慣れるまでは分かるようで分からないものでした。分かったつもりになっていた私がよくやった失敗は、「このストーリーは基準の2倍くらいの4日程度かかりそう、であればポイントは5だ」と期間を見積もりストーリーポイントに換算してしまうことでした。これはまさしくストーリーポイントの用途を理解していないことの現れです。</p>
<p><strong>ストーリーポイントは「規模」を見積もります</strong>。規模を「作業量」と言い換えることもできます。ストーリーポイントを使う理由は、<strong>作業量の見積もりと期間の見積もりを分離して行うこと</strong>だと考えると分かりやすかったです。上述の失敗例では期間を見積もってからストーリーポイントに変換していますが、本来のストーリーポイントの使い方に習うなら、<strong>ストーリーポイントによって作業量を見積もり、ベロシティと照らし合わせて期間を導き出す</strong>が正解です。</p>
<p>私たちがこの考えに馴染めず苦労した背景には、「相対見積もりをするならストーリーポイント(またはTシャツサイズ等のそれに準ずるもの)を利用しなければならない」と思い込んでいたことがあります。また、いくつかあるストーリーポイントの利点をチームメンバー各々が断片的に知り、それを利用目的だと思い込んでいたことも要因でした。例えば「ストーリーポイントを使えば個々人の力量に依存しない見積もりができること」や「ストーリーポイントを使えば仕様が曖昧でも見積もれること」を、ストーリーポイントを採用する理由だと思っていました。<br />
そういった利点は多々あるものの、本質的には<strong>ストーリーポイントは「期間」と「作業量」を切り離し別々に見積もる道具</strong>だと腹落ちしたことで前進しました。</p>
<p>とはいえ、理解できてもすぐにうまく実践できたわけではありません。</p>
<h3 id="壁3-見積もりをコミットメントと捉えてしまう">壁3. 見積もりをコミットメントと捉えてしまう</h3>
<p>先述の2つの壁を少しずつ乗り越え、ストーリーポイントを使った相対見積もりに慣れてくると、仕様が固まっていない曖昧な案件に対しても見積もりをするようになりました。言い換えると、作業量の見積もりに「複雑さ」を加味するようになりました。</p>
<p>「この手の案件はステークホルダーの時間が取りにくく後になって仕様がひっくり返るケースがある」「細かい仕様は決まってないけど、この画面の機能をいじるのであればおそらく作業量はこのくらいになる」と、<strong>作業量に複雑さをかけ合わせたものにポイントをつける</strong>ようになりました。</p>
<p>このやり方は一長一短だとは思いますがそれはさておき、より深刻な失敗だったことは、一度見積もったポイントは根性で守り抜こうとしていたことです。もちろん期限を守ることはエンジニアには必須です。ただし<strong>見積もりはコミットメントではない</strong>ということも忘れてはなりません。見積もりを基にコミットメントを決めることはありますが、見積もりのすべてがコミットメントになるわけではないのです。</p>
<p>“不確実性のコーン”と表現されるように、見積もりは初期段階ほど不正確です。ましてや私たちのように複雑さを加味するのであれば尚更です。ですので作業量に影響する要素が明らかになる度に<strong>再見積もり</strong>をし、その確度(実現可能性)を上げることが必要でした。<br />
加えて、プランナーと「あとどんな情報が揃えば再見積もりができるか」や「見積もりと実働がズレたらどう対応していくか」などについて事前に認識を合わせておくことも、再見積もりを繰り返すプロセスを維持するために必要でした。</p>
<p>見積もりの確度がどの程度かは、見積もった私たちにしか分かりません。ですのでそれを丁寧にステークホルダーに共有し、確度に応じたプランを用意しておくところまでをセットで行うよう習慣化することで、周囲から再見積もりのプロセスの理解を得やすくなると考えています。</p>
<h3 id="まとめ">まとめ</h3>
<p>「相対見積もりといえばストーリーポイントでしょ!」と勢いで始めたもののなかなか定着せず、効果を得られなかった私が、どのような問題に陥っていたかを紹介しました。</p>
<ul>
<li>相対見積もりとストーリーポイントをごちゃまぜに捉えていたこと</li>
<li>ストーリーポイントにより「作業量」を見積もり、その値から「期間」を算出する、という根本的な考え方を理解していなかったこと</li>
<li>再見積もりをして確度をあげようとしていなかったこと</li>
</ul>
<p>これらが主な失敗でした。乗り越えるためには失敗を自覚し向き合うことはもちろん大事ですが、併せて根気も必要だったと思います。時間をかけて実践とふりかえりを重ねてようやく今の理解度に到達できたので、総括すると「根気強く向き合う」が私たちの乗り越え方だったと言えるかもしれません。と言っても、まだ完璧な相対見積もりができているわけではないので、これからも新しい壁にぶつかりながら試行錯誤していこうと思います。</p>
<p>最後に、参考書籍を紹介して締めくくります。<br />
いろいろ読みましたが、一番理解が捗ったのは<a href="https://amzn.to/3ny06zy" target="_blank">アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~</a>でした。同じような悩みを持つ開発者の手助けになれば幸いです。</p>これまでエンジニアやスクラムマスターとしてスクラムチームに関わって来ましたが、その過程で何度も「相対見積もり」や「ストーリーポイント」に纏わる悩みにぶち当たってきました。工数や期間での見積もりに慣れていた私にとって、それらは理解も実践もしにくい手強いものでした。esbuild 入門者のための書き置き2021-09-15T00:00:00+00:002021-09-15T00:00:00+00:00https://aloerina01.github.io/blog/1<p>最近開発環境を改善する機会が減っていて、Babelやらwebpackやらの情報を追っていませんでした。が、チームメンバーが爆速なesbuildを導入してくれて感動したのを機に、久々にフロントエンドの開発環境について考えてみました。</p>
<p>今回は手始めに、初めてesbuildに触ったときに感じた「これなに」「どう使うの」「気をつけることは」あたりを書き置きしておきます。ちなみに執筆時点でのesbuildのバージョンは<a href="https://github.com/evanw/esbuild/releases/tag/v0.12.28" target="_blank">0.12.28</a>です。</p>
<ul id="markdown-toc">
<li><a href="#esbuild-とは" id="markdown-toc-esbuild-とは">esbuild とは</a></li>
<li><a href="#使い方" id="markdown-toc-使い方">使い方</a></li>
<li><a href="#利用例" id="markdown-toc-利用例">利用例</a></li>
<li><a href="#気をつけたいこと" id="markdown-toc-気をつけたいこと">気をつけたいこと</a> <ul>
<li><a href="#css-modules未対応" id="markdown-toc-css-modules未対応">CSS Modules未対応</a></li>
<li><a href="#tsconfigの解釈" id="markdown-toc-tsconfigの解釈">tsconfigの解釈</a></li>
<li><a href="#動的import-code-splittingの展望" id="markdown-toc-動的import-code-splittingの展望">動的import, Code Splittingの展望</a></li>
<li><a href="#es5との付き合い方" id="markdown-toc-es5との付き合い方">ES5との付き合い方</a></li>
<li><a href="#top-lebel-await未対応" id="markdown-toc-top-lebel-await未対応">top-lebel await未対応</a></li>
</ul>
</li>
<li><a href="#おわり" id="markdown-toc-おわり">おわり</a></li>
</ul>
<h3 id="esbuild-とは"><a href="https://github.com/evanw/esbuild" target="_blank">esbuild</a> とは</h3>
<blockquote>
<p>An extremely fast JavaScript bundler</p>
</blockquote>
<p>とにかく速さに重点を置いたバンドラのようです。バンドラということは、並列で比較できるものは<a href="https://webpack.js.org/" target="_blank">webpack</a>、<a href="https://rollupjs.org/" target="_blank">rollup.jp</a>、<a href="https://ja.parceljs.org/" target="_blank">Parcel</a>などです。バンドルと同時にトランスパイルもしてくれるようなので、その点で言えば<a href="https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html" target="_blank">tsc</a>や<a href="https://babeljs.io/" target="_blank">Babel</a>が比較対象になるでしょう。</p>
<p>esbuildは標準で、JS、JSX、TS、TSX、CSS、JSONなどを解釈しバンドルします。パッと見た感じはビルドに必要な一連の処理を担ってくれる印象ですが、<strong>ES5への変換に未対応</strong>だったり、TypeScriptを解釈するものの<strong>型チェックはしなかったり</strong>と、ビルド時によく使われる機能が一部ないので、利用の際は要件に合うかの確認が必要そうです。</p>
<h3 id="使い方">使い方</h3>
<ol>
<li><code class="language-plaintext highlighter-rouge">npm install -D esbuild</code></li>
<li><code class="language-plaintext highlighter-rouge">npx esbuild --bundle ./index.js</code></li>
</ol>
<p>configファイルなしで実行できるので、<code class="language-plaintext highlighter-rouge">npm install</code>して即利用できます。基本的なオプションも揃っています。</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>効果</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">--bundle</code></td>
<td>依存関係をインライン化します。esbuildはデフォルトでは依存関係をバンドルに含まないので、明示的に有効化する必要があります。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--minify</code></td>
<td>ビルドしたファイルを圧縮します。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--watch</code></td>
<td>ウォッチモードを有効にします。ファイルの変更を検知して再ビルドが走るようになります。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--target</code><br />例: <code class="language-plaintext highlighter-rouge">-target=es2020,chrome58,node12</code></td>
<td>ビルド後に生成するJSのターゲット環境を指定します。デフォルトは<code class="language-plaintext highlighter-rouge">esnext</code>です。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--sourcemap</code></td>
<td>sourcemapを生成します。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--define</code><br />例: <code class="language-plaintext highlighter-rouge">--define:DEBUG=true</code></td>
<td>グローバル変数を定義します。</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">--splitting</code></td>
<td>Code Splitting を有効化しますが、まだWIPのオプションです。</td>
</tr>
</tbody>
</table>
<p>自分がよく使いそうなものをピックアップしました。これ以外のオプションは<a href="https://esbuild.github.io/api/#build-api" target="_blank">公式</a>をご確認ください。</p>
<h3 id="利用例">利用例</h3>
<p>ES5に変換できないので、Production buildには使いにくいのが現状です。ですのでProduction buildは今まで通りwebpackを使って、Development buildにesbuildを利用するのが無難だと思います。<a href="https://github.com/privatenumber/esbuild-loader" target="_blank">esbuild-loader</a>を使うとwebpack上でesbuildを利用できます。</p>
<h3 id="気をつけたいこと">気をつけたいこと</h3>
<p>まだBeta版ということもあって気をつけたほうが良いことはいっぱいあるとは思いますが、私がドキュメントやIssueを見ていて目に止まった部分を書き置きしておきます。</p>
<h4 id="css-modules未対応">CSS Modules未対応</h4>
<ul>
<li>0.7.7でExperimentalなCSSのサポートを開始</li>
<li>sass/scssの対応はまだの様子</li>
<li><a href="https://github.com/evanw/esbuild/issues/20" target="_blank">Issue</a>にて議論中</li>
</ul>
<h4 id="tsconfigの解釈">tsconfigの解釈</h4>
<ul>
<li>TS, TSXをビルドするときはtsconfigの設定を読み取る</li>
<li>tsconfigの特定フィールドのみ参照される、詳細は<a href="https://esbuild.github.io/content-types/#tsconfig-json" target="_blank">公式</a>にて</li>
</ul>
<h4 id="動的import-code-splittingの展望">動的import, Code Splittingの展望</h4>
<ul>
<li>動的importの構文には対応している</li>
<li>現時点ではCode SplittingはESMのみ対応してるが、ほかのモジュール形式も対応していくつもり</li>
<li><a href="https://github.com/evanw/esbuild/issues/16" target="_blank">Issue</a>にて議論中</li>
</ul>
<h4 id="es5との付き合い方">ES5との付き合い方</h4>
<ul>
<li><code class="language-plaintext highlighter-rouge">--target=es5</code>とした場合、元々ES5のコードはES5のままになるが、ES6のコードをES5に変換することはない</li>
<li>今後ES5に対応することはなさそう</li>
<li>参考<a href="https://github.com/evanw/esbuild/issues/297" target="_blank">Issue</a>はこちら</li>
</ul>
<h4 id="top-lebel-await未対応">top-lebel await未対応</h4>
<ul>
<li>今後もしばらくは対応できそうにない</li>
<li>細かい議論は<a href="https://github.com/evanw/esbuild/issues/253" target="_blank">Issue</a>にて</li>
</ul>
<h3 id="おわり">おわり</h3>
<p>以上、簡単ですがesbuildについての書き置きです。<br />
冒頭にも書いたように、最近は環境構築する頻度が減っているので、おそらく数カ月後に久々にesbuildを使おうとして右往左往している自分がいることでしょう。そのときに少しでも役立てばいいなと思います(バージョンが進んでほとんど役立たなくなっているかもしれませんが😫)。</p>最近開発環境を改善する機会が減っていて、Babelやらwebpackやらの情報を追っていませんでした。が、チームメンバーが爆速なesbuildを導入してくれて感動したのを機に、久々にフロントエンドの開発環境について考えてみました。穏やかで簡潔なHAPPYコードレビューを実現するChrome拡張をつくってみた2021-07-15T00:00:00+00:002021-07-15T00:00:00+00:00https://aloerina01.github.io/blog/1<p>コードレビュー時に思うように意図が伝わらず、会話のラリーがやたら増えてしまったり、詰問合戦のようなギスギスした雰囲気になってしまったことありませんか? 私はあります。もう少し気持ちよく無駄なくレビューできないものかと思っていたのですが、先日ふと思いついた対処策があったので試してみました。</p>
<h3 id="つくったもの">つくったもの</h3>
<p><img src="/assets/2021-07-15-1.gif" alt="demo" /></p>
<p>コードレビュー時に「アイデア」「質問したい」「議論したい」「修正したい」の4つのアイキャッチをお手軽に付与できるようにするChrome拡張です。</p>
<h3 id="解決したかった問題">解決したかった問題</h3>
<blockquote>
<p><strong>「ここ、なんでこう実装したんですか?」</strong></p>
</blockquote>
<p>こんな質問をしたレビュワーにはどんな意図があるでしょうか。こんな質問を受け取ったレビュイーはどう感じるでしょうか。</p>
<p><strong>レビュワーの意図</strong></p>
<ul>
<li>他にもいろいろ実現手段がある中でこの方法を採用した根拠を知りたい</li>
<li>特殊な背景があるようだったらコメントを残すようにお願いしたい</li>
<li>納得できない実装方法だったので変えてほしい</li>
<li>自分には思いつかない方法だったので、経緯を聞いて学びたい</li>
</ul>
<p><strong>レビュイーの受け取り方</strong></p>
<ul>
<li>しまった、良くないやり方だったのかも知れない😣</li>
<li>散々悩んでたどり着いた解なんだよ、イチャモンつけるな…😡</li>
<li>どの選択肢を取るかは「決め」の問題なのになぜ突っ込んできたんだろう🤔</li>
</ul>
<p>このようにパッと思いつくだけでもいろいろな意図があり、感じ方があります。意図を含めて互いに丁寧にコメントし合うことができれば最高ですが、言葉選びはレビュワーによりムラが出ますし、忙しいときに言葉足らずになってしまうことがあるかもしれません。レビュイーも見てほしい部分を適切に伝えることが難しいかもしれませんし、未完成の部分が混じっていることもあるでしょう(そして当たり前ですがこれはどちらが悪いかという話ではありません)。</p>
<p>一人ひとりが解決するのは難しい、だったらツールで解決しよう、という経緯で開発に至りました。</p>
<h3 id="コンセプト">コンセプト</h3>
<p>アイキャッチには「〜したい」と書かれています。「〜すべき」「〜してください」といった言葉は使われていません。</p>
<p>多くの場面で、コードレビューにおける対話では互いの背景知識に差があります。実装者(レビュイー)の悩み抜いたプロセスやボツになった選択肢のすべてがレビュワーに見えているわけではありません。レビュワーが持つ広い視野やバイアスのない視点は、長い時間コードを見つめ続けてきた実装者には欠けがちです。<br />
そういった互いの差に配慮しつつ、正しく自分の考えを伝える(汲み取ってもらう)には、<strong>「〜すべき」といった断定的な言い方や「〜してください」といった命令的な言い回しでは力不足</strong>です。</p>
<p>代わりに、効果的にレビューを進める言い回しが「〜したい」という主観的な表現です。</p>
<p>私たちがレビューの場でしている会話は、実は「何が正しいか」「何が最適か」「このコードは良いか/悪いか」という<strong>事実を正しく理解するための会話</strong>ではありません。「何を正しいと考えているか」「このコードをどうしたいか」という<strong>認識・解釈・価値観の会話</strong>の会話です。ですので「(自分は)〜したい」と、主観的な認識を伝えようとすること、ひいては「私は自分のコメントが主観的なものだと自覚しているよ」と伝えることが、丁寧かつ効果的な会話に繋がります。</p>
<p>「私は正しい、あなたは間違っている」という思い込みのもと行われる会話を減らし、<strong>違って当たり前の認識・解釈・価値観を互いにすり合わせる会話のきっかけを作る</strong>ことが、今回つくったもののコンセプトなのです。</p>
<h3 id="実装の紹介">実装の紹介</h3>
<p><strong>Repository</strong></p>
<p><a href="https://github.com/aloerina01/pr_review_toys" target="_blank">aloerina01/pr_review_toys</a></p>
<p><strong>使った技術</strong></p>
<ul>
<li>TypeScript</li>
<li>Preact</li>
<li>Parcel</li>
</ul>
<p>Github上のコメント入力欄を<code class="language-plaintext highlighter-rouge">querySelectorAll</code>して、Preact製のプルダウンをマウントしているだけです。コードレビュー時のコメント入力欄はユーザーの操作により増減するので<code class="language-plaintext highlighter-rouge">MutationObserver</code>で検知しています。<br />
小さなアプリケーションをサクッとつくるときはParcelでバンドルすることが多いです。</p>
<p>ちなみにストアでの提供はしていませんが、リポジトリのREADMEに使い方を記載していますので、気になった方は試してみてくださいね。</p>
<h3 id="おわりに">おわりに</h3>
<p>今回作ったChrome拡張自体は大したものではありませんが、そのコンセプトには私がコミュニケーションにおいて大事にしている考え方が詰め込まれています。そしてその考え方は、<a href="https://amzn.to/3yWHAoI" target="_blank">話す技術・聞く技術―交渉で最高の成果を引き出す「3つの会話」</a>という本の内容が基盤になっています。日常生活の中で頻発する難しい会話を3つに分類し、なぜ難しいのか、どうすれば良くなるのか、について体系的にまとめた内容です。<br />
何度も読み返していて、私のルーツのような本なので、もし読んだことがある方がいれば<a href="https://twitter.com/aloerina_" target="_blank">@aloerina_</a>まで感想を送ってくれると嬉しいです!</p>コードレビュー時に思うように意図が伝わらず、会話のラリーがやたら増えてしまったり、詰問合戦のようなギスギスした雰囲気になってしまったことありませんか? 私はあります。もう少し気持ちよく無駄なくレビューできないものかと思っていたのですが、先日ふと思いついた対処策があったので試してみました。Vuex5 Proposal リーディング - Vue3での状態管理はどう進化するのか2021-05-18T00:00:00+00:002021-05-18T00:00:00+00:00https://aloerina01.github.io/blog/1<p class="note">
この記事は<a href="https://github.com/vuejs/rfcs/pull/271" target="_blank">Vuex5 RFC Proposal</a>を参考にした内容です。正式リリース時には変更されている部分があるかもしれませんし、私自身も実際に触ってみて意見が変わる可能性があります。
</p>
<ul id="markdown-toc">
<li><a href="#vuexの役割のおさらい" id="markdown-toc-vuexの役割のおさらい">Vuexの役割のおさらい</a></li>
<li><a href="#vuex-5-の簡単なチュートリアル" id="markdown-toc-vuex-5-の簡単なチュートリアル">Vuex 5 の簡単なチュートリアル</a> <ul>
<li><a href="#1-storeの定義" id="markdown-toc-1-storeの定義">1. Storeの定義</a> <ul>
<li><a href="#option-store" id="markdown-toc-option-store">Option Store</a></li>
<li><a href="#composition-store" id="markdown-toc-composition-store">Composition Store</a></li>
</ul>
</li>
<li><a href="#2-storeのインスタンス化" id="markdown-toc-2-storeのインスタンス化">2. Storeのインスタンス化</a></li>
<li><a href="#3-componentからstoreへのアクセス" id="markdown-toc-3-componentからstoreへのアクセス">3. ComponentからStoreへのアクセス</a></li>
</ul>
</li>
<li><a href="#感想" id="markdown-toc-感想">感想</a></li>
<li><a href="#参考" id="markdown-toc-参考">参考</a></li>
</ul>
<h3 id="vuexの役割のおさらい">Vuexの役割のおさらい</h3>
<blockquote>
<p>this RFC focuses on making Vuex an official global state management tool for Vue</p>
</blockquote>
<p>Vuexには、親子関係にないVueComponent間で状態を共有する機能、つまり<strong>グローバルな状態管理</strong>機能を公式に提供する役割があります。今まではその実現手段としてFluxアーキテクチャをベースにしていましたが、Vuex5では脱却するようです。</p>
<p>また、グローバルな状態管理に加えて、Vuexが持つべき要件が4つ定義されています。</p>
<ul>
<li><strong>Code Splitting</strong></li>
<li><strong>SSR 対応</strong></li>
<li><strong>Vue Devtools 対応</strong></li>
<li><strong>Vuex を利用した状態管理の拡張性</strong></li>
</ul>
<p>私がVuexに期待することもこの要件の通りなので、今後のリリースを楽しみに待ちたいと思います。</p>
<p>ちなみにFluxには随分お世話になったし好みに合う考え方でした。時代とともに設計方法も進化していくもので今後利用頻度は減るかもしれませんが、頭の片隅に残っていてくれると、いつかどこかでシナジーが生まれるかもしれません。その日まで少しのお別れです。</p>
<h3 id="vuex-5-の簡単なチュートリアル">Vuex 5 の簡単なチュートリアル</h3>
<ol>
<li>Storeの定義</li>
<li>Storeのインスタンス化</li>
<li>ComponentからStoreへのアクセス</li>
</ol>
<p>の順でRFCにて紹介されています。</p>
<h4 id="1-storeの定義">1. Storeの定義</h4>
<p>Vuex5ではStoreの定義方法が2種類用意されています。<strong>Option Store</strong> と <strong>Composition Store</strong> です。Vueで用意されているOptions API, Composition APIに寄せた手法なので馴染みやすそうです。</p>
<h5 id="option-store">Option Store</h5>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">defineStore</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vuex</span><span class="dl">'</span>
<span class="kd">const</span> <span class="nx">useCounter</span> <span class="o">=</span> <span class="nx">defineStore</span><span class="p">({</span>
<span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">counter</span><span class="dl">'</span><span class="p">,</span>
<span class="na">state</span><span class="p">:</span> <span class="p">()</span> <span class="o">=></span> <span class="p">({</span>
<span class="na">count</span><span class="p">:</span> <span class="mi">1</span>
<span class="p">}),</span>
<span class="na">getters</span><span class="p">:</span> <span class="p">{</span>
<span class="nx">double</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">count</span> <span class="o">*</span> <span class="mi">2</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="na">actions</span><span class="p">:</span> <span class="p">{</span>
<span class="nx">increment</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">count</span><span class="o">++</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">})</span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">defineStore</code>にstate, getters, actions等を含むオブジェクトを渡す形です。今までのVuexで書き慣れたプロパティなので分かりやすいですが、stateが関数になっている点は要注意です。mutationsは廃止されるようです。</p>
<h5 id="composition-store">Composition Store</h5>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">computed</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vue</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">defineStore</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vuex</span><span class="dl">'</span>
<span class="kd">const</span> <span class="nx">useCounter</span> <span class="o">=</span> <span class="nx">defineStore</span><span class="p">(</span><span class="dl">'</span><span class="s1">counter</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">count</span> <span class="o">=</span> <span class="nx">ref</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">double</span> <span class="o">=</span> <span class="nx">computed</span><span class="p">(()</span> <span class="o">=></span> <span class="nx">count</span><span class="p">.</span><span class="nx">value</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span>
<span class="kd">function</span> <span class="nx">increment</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">count</span><span class="p">.</span><span class="nx">value</span><span class="o">++</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nx">count</span><span class="p">,</span>
<span class="nx">double</span><span class="p">,</span>
<span class="nx">increment</span>
<span class="p">}</span>
<span class="p">})</span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">defineStore</code>にkeyとsetup関数を渡す形式です。Vueの<code class="language-plaintext highlighter-rouge">ref</code>や<code class="language-plaintext highlighter-rouge">computed</code>などのReactivity APIを使い回しているのが特徴的です。</p>
<h4 id="2-storeのインスタンス化">2. Storeのインスタンス化</h4>
<p>ここまでで定義してきたStoreは、Vuexインスタンスにregisterされることでインスタンス化されます。<br />
<code class="language-plaintext highlighter-rouge">vuex.store</code>関数に先程定義した<code class="language-plaintext highlighter-rouge">useCounter</code>を渡しましょう。</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">createVuex</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vuex</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">useCounter</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/stores/counter</span><span class="dl">'</span> <span class="c1">// Option Store or Composition Store</span>
<span class="kd">const</span> <span class="nx">vuex</span> <span class="o">=</span> <span class="nx">createVuex</span><span class="p">()</span>
<span class="kd">const</span> <span class="nx">counter</span> <span class="o">=</span> <span class="nx">vuex</span><span class="p">.</span><span class="nx">store</span><span class="p">(</span><span class="nx">useCounter</span><span class="p">)</span>
<span class="nx">counter</span><span class="p">.</span><span class="nx">count</span> <span class="c1">// <- 1</span>
<span class="nx">counter</span><span class="p">.</span><span class="nx">double</span> <span class="c1">// <- 2</span>
<span class="nx">counter</span><span class="p">.</span><span class="nx">increment</span><span class="p">()</span> <span class="c1">// success</span>
</code></pre></div></div>
<p></p>
<p>インスタンス生成後は、<code class="language-plaintext highlighter-rouge">getters</code>や<code class="language-plaintext highlighter-rouge">dispatch</code>などを使わずともStoreにアクセスできるようになりました。今までのVuexより直感的です。</p>
<p>Composition Storeでは<code class="language-plaintext highlighter-rouge">ref</code>を利用していてるので<code class="language-plaintext highlighter-rouge">counter.count.value</code>としたいとことですが、その必要はないようです。Option StoreかCompositon Storeかを区別することなく実装できるのはいいですね。</p>
<p>また、<code class="language-plaintext highlighter-rouge">vuex.store(useCounter)</code>は初回実行時にStoreインスタンスを内部的に保持し、2回目以降の実行時にはそれを返す仕組みがあります。言い換えるとStoreは使用されるまで登録されないということになります。これはCode Splittingの観点でも恩恵があります。</p>
<h4 id="3-componentからstoreへのアクセス">3. ComponentからStoreへのアクセス</h4>
<p>ComponentがStoreを利用するためには、何はともあれ最初にVueアプリケーションにVuexインスタンスをinjectする必要があります。</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">createApp</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vue</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">createVuex</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vuex</span><span class="dl">'</span>
<span class="k">import</span> <span class="nx">App</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/App.vue</span><span class="dl">'</span>
<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">createApp</span><span class="p">(</span><span class="nx">App</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">vuex</span> <span class="o">=</span> <span class="nx">createVuex</span><span class="p">()</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">vuex</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">mount</span><span class="p">(</span><span class="dl">'</span><span class="s1">#app</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div></div>
<p></p>
<p>準備ができたところで、<strong>Options APIで実装されたComponent</strong>からのアクセス方法を見てみます。</p>
<p><strong>方法1</strong></p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">useCounter</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/stores/counter</span><span class="dl">'</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
<span class="na">computed</span><span class="p">:</span> <span class="p">{</span>
<span class="nx">counter</span> <span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">$vuex</span><span class="p">.</span><span class="nx">store</span><span class="p">(</span><span class="nx">useCounter</span><span class="p">)</span>
<span class="p">},</span>
<span class="nx">count</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">count</span>
<span class="p">},</span>
<span class="nx">double</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">double</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="na">methods</span><span class="p">:</span> <span class="p">{</span>
<span class="nx">increment</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">increment</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p></p>
<p><strong>方法2</strong></p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">mapStores</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vuex</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">useCounter</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/stores/counter</span><span class="dl">'</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
<span class="na">computed</span><span class="p">:</span> <span class="p">{</span>
<span class="p">...</span><span class="nx">mapStores</span><span class="p">([</span>
<span class="nx">useCounter</span>
<span class="p">]),</span>
<span class="nx">count</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">count</span> <span class="c1">// storeのkey "counter" でアクセスする</span>
<span class="p">},</span>
<span class="nx">double</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">double</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="na">methods</span><span class="p">:</span> <span class="p">{</span>
<span class="nx">increment</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">counter</span><span class="p">.</span><span class="nx">increment</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>今までのVuexに似ていますね。<code class="language-plaintext highlighter-rouge">computed</code>でStoreの値を利用するか、<code class="language-plaintext highlighter-rouge">mapHelper</code>を利用するか、の2択です。後者の方法では<code class="language-plaintext highlighter-rouge">vuex.store</code>が暗黙的に実行されているようです。ちなみに<code class="language-plaintext highlighter-rouge">mapStores</code>に渡されたStoreにアクセスする際は、<code class="language-plaintext highlighter-rouge">difneStore</code>で定義した<code class="language-plaintext highlighter-rouge">key</code>の値が利用することになります。</p>
<p>次に<strong>Compositon APIで実装されたComponent</strong>からのアクセス方法です。</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">useCounter</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/stores/Counter</span><span class="dl">'</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
<span class="nx">setup</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">counter</span> <span class="o">=</span> <span class="nx">useCounter</span><span class="p">()</span>
<span class="nx">counter</span><span class="p">.</span><span class="nx">count</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>直感的でけっこう好みです。この方法だとStore定義を<code class="language-plaintext highlighter-rouge">useXxxx</code>と命名する意味が実感できますね。</p>
<p>以上が新しいVuexの使い方です。<br />
RFCにはこれ以外にも、Store同士の依存関係、ハイドレーション、型注釈等の解説もありました。</p>
<h3 id="感想">感想</h3>
<p>今までは、Vuexのルールや制約の中でどれだけ依存関係を整えられるか、責務を分離できるか、再利用したい部品を適切に再利用できるか、といったことを悩み続けてきました。その軌跡はこのブログ上にもいくつかの記事として残っています。</p>
<p>しかしこれからはComposition API と Composition Storeを使うことで、Store層は極限まで薄く最低限のものになり、Componentに持たせるロジックは切り出され、結果的に<strong>状態・View・ロジックがシンプルに分離された</strong>構造となりそうです。そしてそれらの依存関係はFluxのように循環するのではなく、Viewが状態やロジックに依存する形になりそうです。</p>
<p>これだけ聞くと、かつてのMVCのFat Contoller問題のような、Componentが依存で膨れ上がる可能性があるのでは……と思いましたがどうなんでしょう。Componentの切り方次第で良くも悪くもなりそうなので、今までとは違った切り口で設計する心の準備をしておこうと思います。</p>
<p>話は変わりますが、React向けの状態管理ライブラリのRecoilに<a href="https://recoiljs.org/docs/api-reference/core/Loadable" target="_blank">Loadable</a>という非同期処理の状態を扱う仕組みがあるのですが、これに近いことがVuexでもできると良いなと漠然と思っています。stateの初期値を非同期で取得する場面や、ユーザの入力をActionsを通じてServerへ反映する場面などの、非同期の状態の扱いやViewへの反映がお手軽になると嬉しいです。</p>
<h3 id="参考">参考</h3>
<ul>
<li><a href="https://github.com/vuejs/rfcs/pull/271" target="_blank">https://github.com/vuejs/rfcs/pull/271</a></li>
<li><a href="https://github.com/kiaking/rfcs/blob/vuex-5/active-rfcs/0000-vuex-5.md" target="_blank">https://github.com/kiaking/rfcs/blob/vuex-5/active-rfcs/0000-vuex-5.md</a></li>
<li><a href="https://github.com/vuejs/rfcs/discussions/270" target="_blank">https://github.com/vuejs/rfcs/discussions/270</a></li>
</ul>この記事はVuex5 RFC Proposalを参考にした内容です。正式リリース時には変更されている部分があるかもしれませんし、私自身も実際に触ってみて意見が変わる可能性があります。心理的安全を妨げる「対人リスク」を再定義して自分の行動原理と向き合う2021-04-22T00:00:00+00:002021-04-22T00:00:00+00:00https://aloerina01.github.io/blog/1<p>心理的安全という言葉の<a href="https://web.mit.edu/curhan/www/docs/Articles/15341_Readings/Group_Performance/Edmondson%20Psychological%20safety.pdf" target="_blank">出典</a>をたどると</p>
<blockquote>
<p>Team psychological safety is defined as a shared belief that the team is safe for interpersonal risk taking.</p>
</blockquote>
<p>とあるように、心理的に安全かどうかは「対人リスクのある行動を起こせるかどうか」と捉えることができるわけですが、では対人リスクとは何でしょうか。</p>
<p>心理的安全の研究者Amy Edmondson によれば、</p>
<ol>
<li><strong>IGNORANT - 無知だと思われる不安</strong></li>
<li><strong>INCOMPETENT - 無能だと思われる不安</strong></li>
<li><strong>INTRUSIVE - 差し出がましいと思われる不安</strong></li>
<li><strong>NEGATIVE - ネガティブだと思われる不安</strong></li>
</ol>
<p>の4つが職場環境における対人リスクであると定義されています。</p>
<p style="text-align:center">* * *</p>
<p>ところで、私たちのチームは少しずつ成熟してきていて、おかげで随分と対人リスクを感じないようになってきました。しかしそれでもなお行動しない・発言しない場面が自分の経験上あるので、その要因が何なのかを改めて考えてみようと思います。</p>
<p>例えばブレストの場で新しいアイデアを出すとき、<strong>自分の思考を人に見られるような不安</strong>を感じたことがあります。アイデアを出す時間なので邪魔をする人だとは思われないだろうし、日頃の関係性から無知無能だとも思われないだろうけれど、どこか言いにくい…という心境です。<br />
他の例だと、チームメンバーの行動で改善してほしい部分を見つけたとき、日頃から良好な関係性が築けていたとしても<strong>慎重に言葉を選ばないと…というプレッシャーや面倒臭さ</strong>からフィードバックを躊躇したことがあります。<br />
その他にも、問題を指摘することでその対応が<strong>自分の仕事として降り掛かってくる負担</strong>から発言を控えた場面など、例を挙げればいろいろ出てきます。</p>
<p>Edmondson の対人リスクという分類を知る以前、私はこれらを3つのカテゴリに分けて捉えていました。</p>
<ol>
<li><strong>個性を出すリスク</strong></li>
<li><strong>プロセス・成果・失敗を見せるリスク</strong></li>
<li><strong>フィードバックするリスク</strong></li>
</ol>
<p>Edmondson の対人リスクと比較しながら考えてみます。</p>
<p style="text-align:center">* * *</p>
<h4 id="個性を出すリスク">個性を出すリスク</h4>
<p>言い換えると自己開示するリスクとも言えます。自分の考え方・感じ方・価値観・ポリシー・アイデアなどを人に知られることへの心理的な抵抗により、行動を起こしにくくなることを表しています。端的に言うならば「<strong>内面を知られる不安</strong>」です。</p>
<p>この抵抗感は、IGNORANT / INCOMPETENT / INTRUSIVE / NEGATIVE だと思われるのでは…という不安が根底にあり、まさしくEdmondson の対人リスクであると捉えることができそうです。</p>
<p>一方で、無知無能などとは思われたりしない信頼に足る関係性であったとしても行動を起こしたくない場面があります。私は「自分が人からどう見られているか」をコントールしたい節があり、無知無能といった悪評だけでなく、優秀・斬新・面白いなどの好評であっても、それが私が望まない評価であればもらいたくないと思うことがありました。</p>
<p>このことから、Edmondson の対人リスクは「人が行動を起こさないすべての理由が網羅的に定義されたもの」と捉えるより、「対人リスクの代表例」くらいに捉えると良いのかもしれません。また対人リスクがどんな心理であれ、<strong>自分の印象を操作したいという気持ち</strong>が根底にあると知ることに意義があるのだと思います。</p>
<h4 id="プロセス成果失敗を見せるリスク">プロセス・成果・失敗を見せるリスク</h4>
<p>自分の働く様子をじっくり見られることや、その結果を誇張なく正しく伝えること、ひいては失敗したことを率直に伝えることへのリスクです。言い換えると「業務を評価されるリスク」でしょうか。個性を出すリスクと対比的に見るなら「<strong>行動を見られる不安</strong>」です。</p>
<p>これはEdmondson の対人リスクにかなり近いものだと思います。</p>
<p>ひとつ気になるのは、一部のエンジニアが時たま思う「書きかけのコードを見られたくない」という気持ちはプロセスを見せるリスクに含まれると思うのですが、Edmondson の対人リスクには分類できるのでしょうか…? 製作中のものを見られる気恥ずかしさの根源が何なのか、私にはまだ分かっていないです。</p>
<h4 id="フィードバックするリスク">フィードバックするリスク</h4>
<p>特にネガティブフィードバックをするリスクです。先例のように信頼しあった関係であってもネガティブフィードバックは気が重いものです。Edmondson の対人リスクのINTRUSIVE やNEGATIVE に通ずるところがあるでしょう。</p>
<p>ただそれだけではなく、ネガティブフィードバックはやや特殊な性質があるのではないでしょうか。INTRUSIVE やNEGATIVE に思われる不安と、<strong>利害要因</strong>とを天秤にかけた上で、行動を起こすかどうかを判断しているように感じていました。<br />
例えばエンジニアはコードレビューをします。これにはネガティブフィードバックが含まれています。沈痛な思いでコードレビューしている人もいると思いますが、そうであったとしてもネガティブフィードバックをすることの価値(コードレビューしないと何らかの形で自分が損をする、自分の望むものとかけ離れる、という気持ち)が優先され、リスクを乗り越え行動が生まれるのではないかと考えていました。</p>
<p>ちなみにEdmondson は「心理的安全」と「責任やモチベーション」は相関関係にないと言っていて、コードレビューの例に当てはめるなら、心理的安全がやや欠けていても責任やモチベーションにより行動が生まれる、ということで説明がつくのかもしれません。</p>
<p style="text-align:center">* * *</p>
<p>ここまで、自分が抱いていた対人リスクをEdmondson の対人リスクに当てはめて考え直してみました。私にとっての一番の気づきは<strong>対人リスクの元となる不安はなんであれ、自分の印象を操作したいという欲求が背景に潜んでいる</strong>ということです。「自分をどう見られたいと思っているか」「なぜそのように見られたい/見られなくないと思っているか」と印象操作について掘り下げることで自分の行動原理と向き合うことができそうなので、引き続き考えていこうと思います。</p>
<p>本日はここまで。</p>心理的安全という言葉の出典をたどるとDaily Scrum の3つの質問を再考する2021-01-15T00:00:00+00:002021-01-15T00:00:00+00:00https://aloerina01.github.io/blog/1<p>かつてスクラムガイドにも載っていましたが、Daily Scrum でよく使われる「3つの質問」というものがありました。大雑把に書くと以下の3つです。</p>
<div class="note">
<ul>
<li>昨日何をしたか</li>
<li>今日何をするか</li>
<li>障害や困っていることはあるか</li>
</ul>
</div>
<p>私達のチームも今までこれを実践してきましたが、作業報告・進捗報告を一方的にしているだけで、誰が聞いているのかも誰の役に立っているのかも分からないと感じることがしばしばありました。</p>
<p>その原因はいろいろあります。<br />
例えばその一つになり得るものを挙げると、当時私たちのチームは「1つの仕事を全員で片付ける」ということができていませんでした。フロントエンドエンジニアは開発案件のフロントエンドのみを対応していて、そうすると次第にフロントエンドエンジニアとバックエンドエンジニアとで進行する案件がズレてきます。その結果他の人の仕事への関心が薄れていったり、内容を聞いても理解できず他人事となったりしていました。</p>
<p>もちろんこういった一つ一つがチームの課題であって、これを改善することが根本的には必要です。だけれどもそれには時間がかかるし、組織的な都合や壁などもあります。そのすべてが解決されるまでの間ずっと Daily Scrum が役立たない時間になってしまうのは嫌ですよね。</p>
<p>そこで「<strong>互いの業務内容は40〜70%程度の理解でも、お互いの状況を適切に理解しあってスプリントゴールへ向けた再調整を実践する</strong>」ための3つの質問を再考してみました。</p>
<div class="revision">
<ul>
<li>昨日は何%くらいのパフォーマンスを発揮できたか</li>
<li>その要因は何だと感じたか</li>
<li>スプリントの計画に変更は必要そうか</li>
</ul>
</div>
<p>1つずつ意図を説明していきます。</p>
<h3 id="1昨日は何くらいのパフォーマンスを発揮できたか">1. 昨日は何%くらいのパフォーマンスを発揮できたか</h3>
<p>簡単に言えば自己採点です。「仕事が進んだかどうか」または「やったかどうか」ではなく、どれくらいのパフォーマンスを発揮できたかを伝え合います。</p>
<p>たとえば連日100%のパフォーマンスを発揮していると伝えていたがスプリント終了時にプランニングした内容が完了しなかった場合、そのプランニングには無理があった可能性があるでしょう。<br />
たとえばパフォーマンスが50%の日が続くメンバーがいる場合、スプリントゴールが達成されない可能性があるので何らかのリカバリーが必要だろうと気付けるかもしれません。</p>
<p>互いの仕事内容を詳細まで正確に理解しあっていなかったとしても、この質問であれば進行度合いをざっくりと把握し合えるのではないかと思います。</p>
<h3 id="2-その要因は何だと感じたか">2. その要因は何だと感じたか</h3>
<p>パフォーマンスが左右される要因は人によって違いますし、状況によっても違います。ミーティングが多くて作業時間が細切れになることが影響するかもしれないし、花粉症のせいで集中が途切れるかもしれないし、明日に控えたプロポーズのことで頭がいっぱいになっているかもしれません。</p>
<p>プライベートな要因すべてを赤裸々に語る必要はないですが、負荷やストレッサーを知り合うことでフォローし合える場面は確実に増えるでしょうし、互いがハイパフォーマンスを維持できる状況を理解しあうことで環境づくりに貢献し合えるはずです。この質問は Daily Scrum の回数を重ねるごとに価値を発揮することでしょう。</p>
<h3 id="3-スプリントの計画に変更は必要そうか">3. スプリントの計画に変更は必要そうか</h3>
<p>言い換えれば「このままのペースでスプリントゴールを達成できそうか」ということです。ただ、「達成できそうか」と聞かれると反射的・楽観的に「大丈夫」と答えたくなってしまうような気がするので、少しでも多くの可能性を考えやすくなればと思い「変更は必要そうか」という問いにしてみました。</p>
<p>パフォーマンスがいかほどかとその要因が何かを明らかにした後、それらを踏まえてスプリントの計画が達成できそうかを見つめ直すことができれば、Daily Scrum の目的は果たせるのではないでしょうか。</p>
<h3 id="おわりに">おわりに</h3>
<p>現時点では「再考」しただけで「実践」していません。試してみたら全然駄目かもしれませんが、近いうちに実践しレポートしてみようと思います。</p>かつてスクラムガイドにも載っていましたが、Daily Scrum でよく使われる「3つの質問」というものがありました。大雑把に書くと以下の3つです。私たちのリモートコミュニケーションをデータと共にふりかえる2020-12-23T00:00:00+00:002020-12-23T00:00:00+00:00https://aloerina01.github.io/blog/1<p>私たちのチームは11人のフロントエンドエンジニアで構成されていて、今年は皆在宅勤務をしていました。リモート環境に移行した直後からコミュニケーションの方法には悩まされ試行錯誤してきたので、ここらでふりかえってみようと思います。</p>
<p>今回のふりかえりでは、明示的に取り組んでいるコミュニケーションを紹介し(暗黙的にしているコミュニケーションは今回のふりかえりの対象外とし)、その内容について</p>
<ul>
<li>会話のラリーを目的とした双方向の場か ⇔ 情報伝達などを目的とした単方向の場か</li>
<li>比較的雑談が多いか ⇔ 比較的業務的な話題が多いか</li>
<li>全員集まることが少ない ⇔ 全員集まることが多い</li>
</ul>
<p>という3つの軸で主観的なポイント付けをしてみようと思います。</p>
<h3 id="weekly-sync">Weekly Sync</h3>
<ul>
<li>30分/週</li>
<li>近い将来にやる案件の共有・把握</li>
<li>直近のリリース内容の確認</li>
<li>チケットのステータス更新確認、Merge済みブランチの掃除等の事務ワーク</li>
</ul>
<p><img src="/assets/2020-12-23-1-weeklysync.jpg" alt="Weekly Sync" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="daily-sync">Daily Sync</h3>
<ul>
<li>チームメンバーの業務が比較的区切れる17:00~17:15開催</li>
<li>月、火、木の週3回
<ul>
<li>水曜はWeekly Syncがあるためスキップ、金曜は予定被りのためスキップ</li>
</ul>
</li>
<li>その日やったこと、困っていることの共有</li>
<li>余った時間で雑談(余りがち)</li>
</ul>
<p><img src="/assets/2020-12-23-1-dailysync.jpg" alt="Daily Sync" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="battleground">Battleground</h3>
<ul>
<li>1時間/週</li>
<li>技術相談をする場</li>
<li>Slack channelに話したいトピックを随時記入しており、それについて話す場</li>
<li>最近方向性をシフトして、ふりかえりと技術相談を交互開催するよう変更</li>
</ul>
<p><img src="/assets/2020-12-23-1-battleground.jpg" alt="Battleground" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="happy-hour">Happy Hour</h3>
<ul>
<li>30分/週</li>
<li>完全雑談時間</li>
<li>ランダムでDJ担当を決めてBGMを流す</li>
</ul>
<p><img src="/assets/2020-12-23-1-happyhour.jpg" alt="Happyhour" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="モブワーク">モブワーク</h3>
<ul>
<li>2時間/週</li>
<li>モブプロの時間として始めたが、今では「プログラミング」以外のことをよくする
<ul>
<li>モブレビュー、勉強会、臨時のふりかえりなど</li>
</ul>
</li>
<li>モブワークバックログをTrelloを使ってカンバン化
<ul>
<li>レーンは Idea, Ready, Doing, Done</li>
<li>モブワーク開始時にReadyに入っているものの中から選んで実施</li>
</ul>
</li>
</ul>
<p><img src="/assets/2020-12-23-1-mobwork.jpg" alt="Mobwork" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="daily勉強会廃止済み">Daily勉強会(廃止済み)</h3>
<ul>
<li>30分/週3回</li>
<li>TypeScript導入直後に勉強会をするためにスタート</li>
<li>1ヶ月くらい継続しTSの話題が一区切りした後は日替わりでいろんなネタを持ち寄り</li>
<li>更に1ヶ月くらい経過した頃ネタが尽きたので廃止</li>
<li>代わりに、勉強会したいネタが生まれたら臨時開催 or モブワークで実施する方針に</li>
</ul>
<p><img src="/assets/2020-12-23-1-dailystudy.jpg" alt="Daily勉強会" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="いきぬき会">いきぬき会</h3>
<ul>
<li>2週間に1回、業務後開催</li>
<li>だいたい2時間程度、ながれ解散</li>
<li>2週に1度プロダクトのリリースがあり、その後に開催することが多い</li>
<li>雑談、ゲーム、何でもOK</li>
<li>最近はボードゲームアリーナで遊ぶことが多め</li>
</ul>
<p><img src="/assets/2020-12-23-1-refresh.jpg" alt="いきぬき会" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="slack雑談channel">Slack雑談Channel</h3>
<ul>
<li>各自が雑談用Channelを持っている</li>
<li>社内Twitterとして運用している人もいるし、猫写真Botと化している人もいるし、放置の人もいる</li>
<li>雑談用Channelは全員作っているが、運用してもしなくてもいい、人のも見ても見なくてもいい</li>
<li>業務用のチームChannelもあるので、そちらで業務の話題の合間に雑談していることも多い
<ul>
<li>先日チームChannelでAmong Usの募集をしていたくらい雑</li>
</ul>
</li>
</ul>
<p><img src="/assets/2020-12-23-1-zatsuchannel.jpg" alt="雑談Channel" style="border:1px solid #e8e8e8;border-radius:20px;" loading="lazy" /></p>
<h3 id="まとめ">まとめ</h3>
<p>分布で見てみるとこんな感じになりました。円の大きさは「参加率」の大小です。</p>
<p><img src="/assets/2020-12-23-1-graph.jpg" alt="分布" loading="lazy" /></p>
<p>意図せず万遍なく分布されました。万遍ないことが良いことだとは限りませんが、今のところちょうどいい塩梅だと感じています。強いて言うなら、全員が集まる場ではなくチームメンバーのうち何人かが小さく関わる機会があればと思いますが、各自の雑談用Channel内での会話が盛んであったり、困ったときに「手が空いてる人zoomで相談にのってくれません?」といった会話が1日数回生まれていることなどから、やはりちょうどいい状態なのかもしれません。</p>
<p>今回は取り上げませんでしたが、四半期に1回開催している「ふりかえり総集編」やスポットで開催しているエクササイズなど細かいコミュニケーションイベントはあるので、むしろ過剰にならないようなブレーキも大切かもしれないと改めて感じました。</p>
<p>ちなみにこの分布は私の主観を反映しただけのものなので、チームメンバーにも同様にふりかえってもらって<strong>チームメンバー全員の「ちょうどいい塩梅」</strong>を探ってみても良さそうですね。来年チャレンジしてみたいです。</p>
<p>他にも、週あたりの「コミュニケーション時間」と「開発専念時間」を比較して実態と感覚があっているか、などもふりかえってみようと思いましたが、今回は手抜きでサボります。コミュニケーション時間はスキマ時間でもできることが多そうだけれど、開発専念時間はある程度まとめて確保したい、など時間の使い方にも違いがあると思うので、単純に総時間数だけで比較する難しさに打ちのめされました。</p>
<p>以上、私たちのチームのリモートコミュニケーションのふりかえりでした。皆さんのチームのアイデアも知りたいので、よければ<a href="https://twitter.com/aloerina_" target="_blank">@aloerina_</a>までコメントいただければと思います。</p>
<p>それでは良いお年を。</p>私たちのチームは11人のフロントエンドエンジニアで構成されていて、今年は皆在宅勤務をしていました。リモート環境に移行した直後からコミュニケーションの方法には悩まされ試行錯誤してきたので、ここらでふりかえってみようと思います。自律的なチームと謙虚なリーダーシップの関係、またはLINE DevDay2020のあとがき2020-12-18T00:00:00+00:002020-12-18T00:00:00+00:00https://aloerina01.github.io/blog/1<p>先日LINE DeveloperDay 2020にて『<strong>一人ひとりの「変えたい」を力に、11人で変化し続ける開発チームができるまで</strong>』と題して、私たちのチームの生々しい課題や取り組み、そして変化についてお話しました。</p>
<iframe width="640" height="360" src="https://www.youtube.com/embed/yKcEYmj4JR4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p style="font-size:0.9rem;text-align:center">セッション動画</p>
<script async="" class="speakerdeck-embed" data-id="ae8b0feb948743ee8b5ebc093d196c5d" data-ratio="1.77162629757785" src="//speakerdeck.com/assets/embed.js"></script>
<p style="font-size:0.9rem;text-align:center">日本語スライド</p>
<p></p>
<p>今回の登壇は、それまでに取り組んだり考えたりしてきた「マネジメント」を言語化する作業でした。そしてチームを観察し気づいた変化を言語化する作業でもありました。 <br />
今の私にできる最大限の力と時間を使って、頭の中に曖昧に散見していた思いをかき集め、言葉にはめ込み、論理で繋ぎ合わせて、40分というセッション枠に合うように削り出したものが、今回の発表内容となりました。</p>
<p style="font-size:0.9rem;text-align:center">
<img src="/assets/2020-12-18-1.jpg" alt="言語化の跡" loading="lazy" />
<span>言語化の跡</span></p>
<p>しかし自分の中にはまだ十分に言語化できていない部分も多く残っています。「自分の環境だから実現できた限定的な方法論」と「再現性のある技術」とをうまくふるい分けられず言及できなかった部分もあります。<br />
ここでは、あとがきと称してその部分を補完する(言い訳する)と共に、1冊の本を紹介しようと思います。</p>
<h3 id="謙虚なリーダーシップとの接点">謙虚なリーダーシップとの接点</h3>
<p>ここ1年ほど、私は私自身のリーダーシップを改善するよりも、チームメンバーが密かに持つリーダーシップを存分に発揮できる環境(チーム)づくりに関心がありました。日々の対話の中で、一人ひとりに違った得意分野があり深く考え抜かれた意見を持っていると感じていたので、互いが得意分野でチームをリードしあう状態をつくりたかったわけです。<br />
この「リードしあう」という行動を、セッション内では<strong>「変えたい」と思った人がチームメンバーに思いを伝え、最初の1歩を踏み出す行動</strong>と表現しました。</p>
<p>しかしこれが簡単ではないことを私は知っています。ですので<strong>チームメンバーの「変えたい」を受け入れ、共に変化を起こしていく行動</strong>が併せて必要だとお伝えしました。チームメンバー1人の「変えたい」を引き出すためには、チームメンバー全員がそれを受け入れる姿勢を示す必要があるということです。</p>
<p>この<strong>2つの自律的な行動</strong>をチームメンバーが自然とできるようになるために、私に何ができるかと考えながら読み漁った本の中の1冊が「<a href="https://amzn.to/2LyxTcO" target="_blank">謙虚なリーダーシップ - 1人のリーダーに依存しない組織をつくる</a>」という本でした。この本では、</p>
<blockquote>
<p>「よい関係」ができている場合には、相手に関してあるレベルの安心感、つまり、相手の反応について想像がつくために安心感を覚えることができる</p>
</blockquote>
<blockquote>
<p>「互いに信頼し合い、いっそうよい仕事をするために、あなたについてもっとよく知りたい」と思っていることを、言葉と行動で表す</p>
</blockquote>
<p>と述べています。<br />
先述した2つの自律的な行動をしやすくする関係性を私はセッションの中で「相互理解」と表現しましたが、本書では<strong>相互理解の先にある「安心感」</strong>に目を向けています。</p>
<p>また、</p>
<blockquote>
<p>たいていの場合、問題の根は「ノード」(つまり、個人)ではなく、相互作用(関係)にある</p>
</blockquote>
<blockquote>
<p>不測の事態や相互作用が急激に増えると、深刻な不調の兆しが多くの組織で見られるようにある</p>
</blockquote>
<p>という記述は、私がセッション内でお伝えした「相互理解があることで課題に自律的に対処できる」ということを、視点を変えて「<strong>相互作用の問題が増えると組織に課題が現れる</strong>」と説明しているのだと感じました。</p>
<p>そして適切な関係性を引き出すためのファシリテーションや支援スキルが、組織のあらゆるレベルで発揮される必要があると伝え、関係構築にまつわるスキルを<code class="language-plaintext highlighter-rouge">謙虚なリーダーシップの真髄</code>と表現しその中身を掘り下げています。</p>
<p>このように本書は私がうまく言葉にできなかった部分、考えきれていなかった部分に言及しています。さらに人と人との関係性を深堀りし、それを変えるプロセスとして<strong>パーソニゼーション</strong>という考え方を提示しています。その有無によりチームがどう変化したのかをいくつかの事例と共に紹介し、そしてチームに必要なふるまいである「謙虚なリーダーシップ」とはどういうものかと話を発展させていきます。</p>
<p>以降では、特に印象的な内容をピックアップして紹介します。</p>
<h3 id="相互理解を生み出すプロセス-パーソニゼーション">相互理解を生み出すプロセス =「パーソニゼーション」</h3>
<p>まずはパーソニゼーションの説明を引用します。</p>
<blockquote>
<p>「パーソニゼーション」とは、仕事仲間、チームメイト、上司、部下、同僚との仕事上の関係を、双方向がつくっていくプロセスである。ただし、相手のことを、そのとき担っている役割ではなく、ひとりの人間として考えようとする姿勢が土台になる。</p>
</blockquote>
<p>セッションでお伝えした「一人ひとりの違いについての相互理解」とは、互いを<code class="language-plaintext highlighter-rouge">ひとりの人間として考えようとする姿勢</code>を持ちながら双方向の関係性を築いていくことで得られるものだと言えるでしょう。</p>
<blockquote>
<p>「パーソニゼーション」は、会話の初めに、どちらかが個人的なことを尋ねる、あるいは話すときに始まる。一方が、もしくは両方が、相当な覚悟をもって会話に臨み、無視されたり拒絶されたり軽蔑されたりする危険を冒すことでもある。(中略)「パーソニゼーション」とは、本質的に、互恵的な双方向のプロセスなのである。</p>
</blockquote>
<p>私がセッション内で相互理解の始め方のひとつとして「自分から始めること」を提案したのは、<code class="language-plaintext highlighter-rouge">危険を冒すこと</code>を相手に委ねるのではなく、自分が背負うことを意味していました。<br />
自己開示をする心理的ハードルについてはセッション内でも触れましたが、もう少しストレートに言えば、自分から一歩踏み込んだ会話をすることで「痛々しく思われたり寒いと思われたりして傷つくかもしれない危険性」を誰かに負ってもらおうとするなということです(自己開示がとても苦手な自分に今でも強く言い聞かせています)。</p>
<p>「自分から始める」「参加しやすい雰囲気づくりから始める」「チームの状態の見極めから始める」ことを重ねながら危険を乗り越えた先に、双方向に成り立つ関係、つまり相互理解があるのだと思います。</p>
<h3 id="自己開示の心理的ハードル">自己開示の心理的ハードル</h3>
<blockquote>
<p>私たちは、相手に対して明らかにする個人的な、秘めたと言ってもいい感情や感想や意見を、絶え間なく、徐々に増やしていくなかで、相手との関係を深めていく。そして、私たちが明らかにしたものに対し、今度は相手がどれくらい、みずからのことを明らかにするかによって、私たちが明らかにしたものを相手がどの程度、受け容れているかを測る。明らかにすることと受け容れることの、次々と変わる程度が、最終的に、両者が心地よいと思う親密さのレベルを決める。</p>
</blockquote>
<blockquote>
<p>率直さの程度の変化に応じて相手の反応がどう変わるかを測り、心地よさ ―両者がともに相手を信頼し、互いに本音で率直に話していることを心から信じられるレベルの心地よさ― を探しながら、「パーソニゼーション」の境界を互いに見出すことなのだ。</p>
</blockquote>
<p>これらの記述は、自己開示が極端に苦手で仕事仲間に自分のプライベートな部分や素の表情を知られることを嫌っていた私の行動を、丸裸にするものでした。そして同時に、探り探りなコミュニケーションをしているのは私だけではない、むしろ多くの人がそうなのだと再認識させてくれるものでした。</p>
<p>それに気づいてからは、自己開示の心理的ハードルが自分だけにあるものではなく、程度の差こそあれ誰にでもあり得るのだと考えるようになりました。</p>
<h3 id="溝の言語化">「溝」の言語化</h3>
<blockquote>
<p>チーム内に信頼を育むためには、「溝」を埋めることに注意を傾ける必要がある。溝とは、能力または自信がないことによって、あるいは、社会的欲求が満たされないためにパフォーマンスが下がることによって生じる、物理的・感情的な距離のことだ。</p>
</blockquote>
<p>こういった状況に陥ったことはないでしょうか、あるいは周囲で目撃したことはないでしょうか。思い当たる節がありすぎた私には、これを乗り越えたストーリーはもちろん、そこから得られる学びがとても沁みました。</p>
<p>長くなってきたので引用はこのあたりにしますが、このように、本書からは「人と人との関係性」という目に見えない曖昧なものの全体像と、それを前進させるための論理的なアプローチが詰まっていました。私が登壇を通じて成し遂げたかったことはまさにこういう話です。</p>
<p>いっそ私のセッションは聞かずにこの本を読むだけでも十分でしょうし、私のセッションを聞いてよくわからないと感じた方やもっと踏み込んだことを知りたいと思った方には、染み入る一冊となることと思います。ぜひ手にとっていただければと思います。</p>
<p>以上、あとがきに代えて。</p>先日LINE DeveloperDay 2020にて『一人ひとりの「変えたい」を力に、11人で変化し続ける開発チームができるまで』と題して、私たちのチームの生々しい課題や取り組み、そして変化についてお話しました。