こまぶろ

技術のこととか仕事のこととか。

エンジニアとして本格的に一歩を踏み出した1年間:毎月の読書で2018年を振り返る

この記事は、 write-blog-every-week Advent Calendar 2018 24日目の記事です。

昨日の記事は、KIDANI Akito(@kdnakt)さんでした。

kdnakt.hatenablog.com


2017年4月に新卒・未経験で就職した僕にとって、2018年は、エンジニアとして本格的に一歩を踏み出した年になった。仕事で悩んだり、GitHubに草を生やしたり、ブログを書いたり、今までになく活動的な1年だった。中でも、4月下旬から始めたブログは、

  • きっかけの存在でもあるkakakakakkuさん
  • write-blog-every-week Slackのみなさん

の支えもあって、今週に到るまで毎週1回の更新を保つことができており、生活の一部になりつつある。休日ってブログ書くためにあるんでしたよね。

しかし、今回の記事ではブログを中心に据えることはしない。Advent Calendarの記事ということもあり、ブログを中心に振り返っても良かったのだけど、ブログを書くということについてはこのAdvent Calendarの他のみなさんの記事がすでに十分な知見を提供している。また、今年の1月から4月はブログを書いていなかったので、1年の振り返りとしては相応しくないと思う。

というわけで、今回は2018年の1月からの12ヶ月について、その月に読んだ本の中で印象に残っている本を少しずつ紹介しながら、振り返ってみることにした。いくつかの本については、公開済みの記事を引くに留めていることをご了承願いたい。

各月の書籍リストは下記の通り。

1月 ショーペンハウアー『幸福について』

幸福について―人生論 (新潮文庫)

幸福について―人生論 (新潮文庫)

前年11月から参画したプロジェクトでの仕事にも慣れ、正月休みもあって(職業人としては)弛んでいた時期。「技術書を読まないと」という意識は持ちながらも、勢いに任せて文学作品を読み漁っていた。

ショーペンハウアーのこの書籍は、「それ、本気で言ってます?」という内容も多く、(もとより哲学書は真に受けて生活するようなものではないだろうが)そのまま従えるようなものではない。しかし、端々にギクリとさせられる言葉があり、日常の自分の生活を一歩離れたところから吟味するきっかけを与えてくれる。ショーペンハウアーというと取り付きづらく感じるが、この書籍は下記の文章のように卑近な話題も扱っている。

さて他方において、人間が社交的になるのは、孤独に耐えられず、孤独のなかで自分自身に耐えられないからである。社交を求めるのも、異郷に赴いたり旅に出たりするのも、内面の空虚と倦怠とに駆られるためである。そういう人の精神には、独自な運動をみずから掴むだけの原動力が不足している。だから酒を呑んでその原動力を高めようとする。こうした方法でついには本当の呑んべえになってしまう者が多い。(217ページ)

訳者解説も、短いながら面白い。ピンときた人はぜひ手に取っていただきたい。

幸福は人間の一大迷妄である。蜃気楼である。だがそうは悟れるものでない。この悟れない人間を悟れないままに、幸福の夢を追わせつつ、救済しようというのである。人生はこの意味で、そのまま喜劇である。戯画である。ユーモアである。したがってこれを導く人生論も諷刺的、ユーモア的たらざるをえないではないか。著者の説く一大哲理の背後に、ペロリと出した著者の舌を見のがさないでいただきたい。(「解説」363ページ)

2月 広木大地『エンジニアリング組織論への招待』

こういう書籍があり得るのか、と衝撃を受けた一冊。ある意味では、この本を読んでから今年は始まった。

人文系の大学院を出てエンジニアになった僕は、学生時代の関心事と仕事での関心事が結びつくとは思っていなかった。そんな中で手に取ったこの本には、ソフトウェアの世界の知と、その他の分野の知とが結びつけられるということを教えられた。この本を読んでから、もともと薄っすらと持っていた「組織」*1というものへの関心が、実際の行動(読書や思索)の形を取るようになっていったと思う。

著者の広木さんが、ゆのん(@yunon_phys)さんと一緒にやっているポッドキャスト「EM.FM」も、広木さんの独特のセンスと広範な知識が遺憾無く披露されていて実に面白い。

anchor.fm

このポッドキャストが生まれるきっかけとなった「Engineering Manager Meetup」のOSTの場でホワイトボードを書いていたのが僕だった。「エンジニアリングマネージャーが不人気なのってポッドキャストがないからじゃね」という(確か広木さんの)発言から数日でポッドキャストが始まり、「ゆのんさんの行動力すげえ」と驚嘆したのを覚えている。

3月 市谷聡啓・新井剛『カイゼン・ジャーニー』

間違いなく今年1年を規定した書籍の1つ*2

社会人1年目が終わろうとしており、会社にもすっかり幻滅していた時期に手に取ったこの書籍は、アジャイルというものへの傾倒を決定的にしたとともに、「まず自分が行動する」という今でもしばしば忘れがちになる規範を与えてくれた。

また、著者の市谷さんと新井さんを中心に、この『カイゼン・ジャーニー』という書籍を通じて出会ったたくさんの方々には、彼らの社内外での活動から刺激をもらったり、仕事での悩みを相談させてもらったりと、大変お世話になっている。他の業界にはおそらく少ないであろう、「社外のコミュニティ」というものの素晴らしさを教えてもらった。

エンジニアになって良かったと思っている理由の一つは、コミュニティの存在だ。業務で利用しているOSSのコミュニティはもちろん、日々参加させていただいている勉強会や、ブログを書いたりポッドキャストをやったり同人誌を書いたりという様々なコミュニティが自分の生活を支えている。自分も何がしかの形で貢献していきたいと思う。

4月 Martin Fowler『リファクタリング

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

ようやく技術書らしい技術書。2017年11月に『テスト駆動開発』を読み、「TDDだ!」となってみたものの、実践する機会がなかなかないまま、コードを書く仕事からも離れつつあった時期に読んで、「プログラミングがしたい!」と思わされた本。

Javaのサンプルコードを添えながら、コードの振る舞いを変えずに構造を改善する手法が数多く紹介している。良いコードがわからなければ、悪いコードを見てもそれがどう悪いかがわからない(Code Smellを嗅ぎとれない)。また、壊さずに改善する手法がわからなければ、悪いコードを見つけても対処できない。この書籍は、以上の2点を実例付きで教えてくれる書籍だ。コードが改善されていく様は一種のエンターテインメントでさえある

なお、最近出た原書の第2版では、サンプルコードはJavaScriptになっている。僕はまだ手に取っていないので、古川陽介さんと増田亨さんが言及していたツイートを紹介しておく。

Refactoring: Improving the Design of Existing Code (2nd Edition) (Addison-Wesley Signature Series (Fowler))

Refactoring: Improving the Design of Existing Code (2nd Edition) (Addison-Wesley Signature Series (Fowler))

5月 アビー・コバート『今日からはじめる情報設計』

今日からはじめる情報設計 -センスメイキングするための7ステップ

5月は新しいプロジェクトに配属された月であり、またブログを本格的に書き始めた月でもあった。プロジェクトで使う技術、ブログのネタにする技術を試すのにプライベートの時間を多く割いていたので、あまり多く本を読んでいなかったなかで、目を通していたのがこの書籍。

新しいことを一気に始めた時期で、仕事でもうまく物事が整理できずに苦しんでいたときに、帯の「混乱よ、さようなら」というフレーズに惹かれて、すがるように手に取った。正直、最初に読んだときは、期待に反してあまりピンとこなかったのだけど、今回改めてパラパラとめくってみると、役に立ちそうなことがたくさん書いてある。今回はその中から、「言語的不安定度を減らす」と題する節を紹介する。

 私たちは、使うべき言葉に対して自信があるときもあれば、自信がないときもあります。
 言語的不安定度(linguistic insecurity)とは、自分の言葉が、自分たちの文脈における標準やスタイルに合っていないのではないか、という一般的に見られる不安です。
 協力して作業を進めるために、それに関わるすべての人が理解できるような言葉を使う必要があるのです。(95ページ)

プロジェクトチーム内で言葉の意味を揃えることの重要性は、様々なところで語られている。そんな中で、この書籍が主張していることが面白いのは、自分の言葉の、自分が属するコンテキストの標準へのミスマッチに対する「不安」に着目している点だ。言語が混乱していると、情報伝達の効率が悪化するだけでなく、人に不安を与えることにもなるというのは、チーム作りをする際にも意識しておきたい。

6月 Mary Lynn Manns・Linda Rising『Fearless Change』

Fearless Change アジャイルに効く アイデアを組織に広めるための48のパターン

Fearless Change アジャイルに効く アイデアを組織に広めるための48のパターン

omoiyari.fmで熱く語られていて手に取った本。3月ごろからすっかり「アジャイルかぶれ」になり、「会社にアジャイルの手法を広めてやるぞ!」と意気込んで読んだ。まとまった文量を割いたパターン・ランゲージの紹介に初めて接したのもこの本だった。

この書籍の内容を十分に活かせているとは言えないが、何度も思い出す一節がある。それは、パターン17「やってみる(Just do it)」の冒頭で紹介されている。「会社を救う方法があるのに上司がやらせてくれない」と訴える人に対する、セス・ゴーディンの言葉だ。孫引きになるが、引用する。

 あなたが捜し求めているものは保険だ。もし計画がうまく行かなかった場合に、周囲の非難からあなたを守ってくれる保険を求めているのだ。あなたは誰かが『新製品プロジェクトを立ち上げてもいいよ』『コスト削減計画を実行してもいいよ』と、背中を押してくれるのを待っているのではないか。そうやって承認してもらうことで、失敗したときのリスクから逃れようとしているのだろう。でもね、ことはそんなに望み通りには運ばないよ。
 やってみなさい。 誰かに承認してもらうのを待つということは、失敗したら尻拭いをしてもらおうと考えているということだ。組織の上層部の人たちは、あなたを信頼し、任せることによって背負うリスクなど十分承知の上だ。もし上司が承認したあなたの計画が失敗に終わったら、苦境に陥るのはあなたではなく、上司なのだ。(163ページ)

なお、パターン・ランゲージというものについてこの書籍が取っている立場については、『組織パターン』のJim Coplienから疑義も提示されているということが、omoiyari.fm #40で語られていた。この点については、もうちょっと勉強したいと思っている。

7月 山田ズーニー『あなたの話はなぜ「通じない」のか』

あなたの話はなぜ「通じない」のか (ちくま文庫)

あなたの話はなぜ「通じない」のか (ちくま文庫)

感情的に、今年一番刺さった本。プロジェクトで思うように周囲と連携できず、アジャイル普及という意味でも壁にぶつかって苦しんでいたときに手に取った。この本については既に長大な記事を書いているのでそちらの参照を乞う。

ky-yk-d.hatenablog.com

8月 プラトンプロタゴラス

プロタゴラス―ソフィストたち (岩波文庫)

プロタゴラス―ソフィストたち (岩波文庫)

仕事については気持ちが少し落ち着き、仕事に直結するものではない書籍を読みたくなっていた時期。Growthfactionの方々の活動に触れて、「価値観」というテーマに対する関心が強まった時期でもあった。

初読は2015年。当時、大学院でのゼミでこれに関する題材を扱っていて、それをきっかけに読んだ。その時に、内容を非常に面白く感じ、改めて読み直したのが今年の8月だった。この本についてはブログで直接テーマにはしていないが、下記の記事の脚注で言及していた。

なぜ、人は「大事だ」と思っていることのための行動をとることができず、別の欲求に負けてしまうのか?このテーマを扱っている書籍として、プラトンの『プロタゴラス』があったと思う。

「充実とは価値観が満たされた状態である」? - こまどブログ

扱っているテーマは「徳は教えられるか」という、一見すると現代の我々にはあまり縁がなさそうなものなのだが、ソクラテスプロタゴラスの対話の展開は実にエキサイティングだし、語られる内容も古びていない。以下で引用する岩波文庫版の訳者解説で言及されている「知る」ということへの態度が、自分の怠惰さへの批判に感じられてならない

「悪いとは知りながら……」という言い方には、「知る」という事について甘えがある。ソクラテスのいわゆるパラドクスは、ほんとうに知っているのなら絶対に行なわないはずではないかと、この甘えをきびしく禁止するのである。(「解説」200ページ)

9月 ジェフリー・フェファー『悪いヤツほど出世する』

悪いヤツほど出世する (日経ビジネス人文庫)

悪いヤツほど出世する (日経ビジネス人文庫)

マネジメントの方面への関心が高まり、気分良く組織論やリーダーシップ系の本を読んでいた中で手に取り、反省させられた本。こちらも過去記事の参照を乞う。

ky-yk-d.hatenablog.com

10月 スティーヴン・ガイズ『小さな習慣』

小さな習慣

小さな習慣

kakakakakkuさんがブログで紹介していて読んだ本。9月末にwrite-blog-every-week Slackに参加して、習慣というものについて改めて考えていた時期。

kakakakakku.hatenablog.com

僕は知らなかったのだけど、amazonで60件のレビューがあり、Google検索でもたくさん書評・感想が見つかる、広く読まれている本のようだ。「小さすぎて失敗すらできない習慣」を身につけることを勧める書籍で、その理由づけを(可愛らしい装丁から受け取るイメージに反して)かなり念入りにしている。もちろん、実践の仕方も説明されているし、巻末では「小さな習慣」を身につけるための助けとなるアプリも紹介されている。

Momentum 習慣トラッキング

Momentum 習慣トラッキング

  • Mathias Maehlum
  • 仕事効率化
  • 無料

僕もこの本を読んでから上記のアプリを入れて少しずつ取り入れている。書籍の中でも強調されているように、「これくらいならやってやってもいいか」と思えるほどの小さな習慣は達成しやすいし、達成することで快感を得ることもできる。また、副産物として、アプリの「〇〇日連続達成です!」という表示によって、思ったよりも早く月日が過ぎていることに気づける@year_progressをフォローするのに似た意味合いがあると思う。

11月 クリストファー・アレグザンダー『時を超えた建設の道』

時を超えた建設の道

時を超えた建設の道

「パターン・ランゲージ」の原典の1つ。

GoFデザインパターン、『Fearless Change』、ドメイン駆動設計のパターン、『組織パターン』など様々なところで接する「パターン・ランゲージ」というものが、建築家クリストファー・アレグザンダーにその由来を等しく求めながらも、それぞれに言っていることが異なっているように感じ、もやもやしていた。

先に読んでいた『パターン、Wiki、XP』で、アレグザンダーの思想がそれ自体として複雑な、深みを持ったものだということを学び、これはどうしても原典に当たらないといけないと感じ、手に取ることにした。そのものずばりの『パタン・ランゲージ』という著書もあるが、そちらは原題を『A Pattern Language』と言って、「パターン・ランゲージ」の一つの具体化という意味合いが強いということだったので、理論編に当たる『時を超えた建設の道』を手に取った。

これはとても面白い本で、付箋をベタベタ貼りながら読んだ。まだ、消化しきれていないのだが、「あの本でのパターン・ランゲージについての見解は、アレグザンダーのこういう側面を取り出したものだな」といった形で、原典との距離で様々な論者のパターン・ランゲージ観を比較できるようになったのはよかった。原典が正しい唯一のものだ、という立場を取るつもりはないが、他の全てがそこから出たところの源流を知ることは意義があることだと思う。

12月 Robert C. Martin『Clean Architecture』

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計

プロジェクトで設計に携わることになり、少しでもヒントを得られればと手に取った。また、並行でドメイン駆動設計の勉強をしていて、記事などでこの『Clean Architecture』に言及されていることも多かったので、読んでおかないと、と思った。

序文にある「アーキテクチャのルールはどれも同じである!」というフレーズが表しているように、この本では様々な時代における著者のソフトウェア開発の経験から抽出された原則の数々が語られる。記事や書籍で当たり前のように引用される「依存関係逆転の原則」などの設計の原則について、紙幅を割いて説明している書籍はありがたい。また、この業界に入って間もない身には、今と異なる技術的環境の中で開発がどのように行われていたのかを知ることができるのも面白い*3

ざっと読んでみた限りでは、なんだかずっと同じことを様々なレベルで、違う形で言っている本のように感じる。「結局こういうことだよね」と、ざっくり要約をしてしまいたくなるのだが、これは読み手である僕が差異を的確に捉えられていないだけなのだろうと思う。一回読んだだけでも十分に得られるもののある書籍だが、時間を空けて何度も読み返すに足る書籍でもあると思う。

2019年に向けて

こうして振り返ってみると、充実した1年間だったと改めて思う。色んな学びがあり、出会いがあった。来年の今頃どうなっているかが我ながら楽しみになる。

一方で、やるやる言いながらやらなかったこともたくさんある。技術ブログを毎週書く、振り返りをする、登壇する、などもそうだ。8月の記事に書いたことはほとんど嘘になってしまった。気合入れて宣言したことはだいたいやらないというのが自分の弱点だとよくわかった。

また、今回はすごく本を読んだ体の記事になったが、読みたいと思っていたのに結局読まなかった本もたくさんある。軽い本に逃げてしまった場面も多かった。今年読めなかった本の一部を下に示して来年の自分への宿題としたい。


write-blog-every-week Advent Calendar 2018、明日(最終日!)の担当は、今回の Advent Calendar の発起人・よしたく (@yoshitaku_jp)さんです!

adventar.org

*1:この本を手に取ったのも、タイトルの「組織論」というフレーズに惹かれたからだった。

*2:発売は2月だが、物語調であることを敬遠して3月にようやく手に取った。

*3:付録Aは「アーキテクチャ考古学」である。

【Angular】HTTP通信のテストでのインジェクションのエラーの解消

Angular*1のHTTP通信部分(Serviceクラス)のテスト*2を書く際に、派手につまずいたので対応方法と経緯をメモ。

テスト対象の実装

HTTP通信には、AngularのHttpClientを用いている。

実装側のコードにおいては、公式ドキュメントにあるように、通信を使用するModuleクラス*3HttpClientModuleをインポートしたうえで、ServiceクラスにHttpClientをインジェクトする。これでHTTP通信が利用できるようになる。

これのテストコードを書きたい。公式ドキュメントには、モックを用いたテストの方法が書いてあるが、今回は実際のAPI(サーバーサイドの実装)をテストしたいという意味合いもあったので、モックを利用しないテストを書く。

対応方法

結論から先に書くと、テスト側のコードにおいては、下記のように、HttpClientModuleをインポートすればよい。

beforeEach(() => TestBed.configureTestingModule({
  imports: [HttpClientModule]
}));

以上のように記載することで、テスト実行時に正常にHTTP通信を実行することができる。

対応までの経緯

まず、何も考えずにテストケース(itの部分)を記載する。すると、下記のようなエラーになる。

Error: StaticInjectorError(DynamicTestModule)[ConnpassService -> HttpClient]: 
  StaticInjectorError(Platform: core)[ConnpassService -> HttpClient]: 
    NullInjectorError: No provider for HttpClient!

HttpClientのインジェクトに失敗したと言われる。確かに、実装側のServiceクラスは、HttpClientをインジェクトされている。そこで、下記のように書きたくなった。

  beforeEach(() => TestBed.configureTestingModule({
    providers: [HttpClient]
  }));

実行すると、下記のようなエラーとなる。

Error: StaticInjectorError(DynamicTestModule)[HttpClient -> HttpHandler]: 
  StaticInjectorError(Platform: core)[HttpClient -> HttpHandler]: 
    NullInjectorError: No provider for HttpHandler!

インジェクションに失敗しているらしい。「HttpHandlerがないと怒られているのかー」と考え、providersに追加してみる。

beforeEach(() => TestBed.configureTestingModule({
  providers: [HttpClient, HttpHandler]
}));

テストを再実行すると、下記のようなエラーになった。

Expected TypeError: _this.handler.handle is not a function to be null.

このエラーメッセージは苦しい。Googleで検索してもなかなかズバリ答えが見つけられなかった。

そもそも、HttpClientは明示的に実装側でインジェクトしているものなのに対して、HttpHandlerはそうではない。エラーメッセージを見て、何も考えずにprovidersに追加してしまったが、モックを利用しているわけでもないのに実装側で意識していないことをテスト側で意識しなければならないのはどこかがおかしいと思うべきだった。

試行錯誤を繰り返した結果、先述のようにimportsHttpClientModuleを記載したことでエラーが解消した。実装側で、

  • HttpClientModuleをインポート
  • HttpClientをインジェクト

という2段階を踏んでいるのだから、真っ先にHttpClientModuleへの依存を疑うべき事案だった。

感想

依存しているモジュールをimportsに追加するというのは、Angularの仕組み、TestBedクラスの仕組みを理解していればすぐにわかることなのだろう。有識者に聞けばすぐに答えが返ってくると思われるので、Angular Japan User GroupのSlackも活用していきたい。

今回、テストについての情報をGoogleを駆使して検索してみて、うまく答えにたどり着けなかった。エラーメッセージで検索をするのが常套手段だが、英語の記事を含めてあまり的確な情報を獲得することができなかったので、記事として書いておくことにした。

※記事の内容の誤り、もっといい対応方法等があれば、ぜひご指摘ください。

*1:Angularのバージョンは、7.0.4。

*2:Angular CLIで作成したプロジェクトにデフォルトで設定されるJasmine + Karmaによるテスト。

*3:AppModuleが一般的とドキュメントに記載されている。

Angularで「ネストされたルート」を実装する(シンプルな実装 / モジュール切り出し / 遅延ロード)

この記事は write-blog-every-week Advent Calendar 2018 11日目の記事です。

前日の記事は、nitt-san(@nitt_san)さんの「インプットからアウトプットへ -2017年〜2018年の自分を振り返る-」でした。

nitt-san.hatenablog.com

Angular のルーティング機能を試したい

以前、Vue.jsを勉強していた際に、Vue Routerの「ネストされたルート」を扱う方法を試した。

ky-yk-d.hatenablog.com

Vue.jsにおける「ネストされたルート」は、Vue Routerの公式ガイドにも記載されている名称だ。

実際のアプリケーションの UI では通常複数のレベルの階層的にネストしたコンポーネントで構成されます。ネストされたコンポーネントの特定の構造に対して URL のセグメントを対応させることはよくあります。

今回は、Angularでこれを実現してみる*1。具体的には、

1.ルートモジュール単体で実装する
2.フィーチャーモジュールとそのルーティングモジュールを切り出す(通常ロード)
3.URLアクセス時に遅延ロードするように修正する

の三段階で実装していく。1の段階で既に上の記事で書いた「ネストされたルート」自体は実現できているのだが、その先に一歩進んで、フィーチャーモジュールの切り出しと遅延ロードも実装する。フィーチャーモジュールの切り出しはアプリの規模が大きくなると不可欠だし、遅延ロードもそれと関連した重要な機能だ。公式ドキュメントでも、「フィーチャーモジュールの遅延ロード」という項目が立っている。

サンプルコードは下記リポジトリを参照。各段階の事後の状態をぞれぞれ、

1.beforeブランチ
2.normal-loadブランチ
3.lazy-loadブランチ

として切ってある。

https://github.com/ky-yk-d/router-samplegithub.com

単一モジュールでの実装

今回は、最もシンプルなネスト構造を持つアプリケーションとして、下に示すようなSPAを実装する。最初に、これを単純にルートモジュールとルートのルーティングモジュールに記述してこのアプリを実装する(第1段階)。その後、このアプリケーションを機能上は変更せずに、リファクタリング(第2段階)および遅延ロード化(第3段階)をおこなっていく。

f:id:ky_yk_d:20181210231309g:plain

プロジェクトの作成〜コンポーネントの作成

Angular CLIを利用してプロジェクトの雛形とコンポーネントを作成する。

ng new router-sample
# ルーティングを利用するか聞かれるので"y"を選択
# スタイルシートの形式は何を選んでもよい
cd router-sample
ng generate component home # AppComponentの直下(1)
ng generate component feature # AppComponentの直下(2)
ng generate component feature/main # FeatureComponentの子要素(1)
ng generate component feature/sub #FeatureComponentの子要素(2)

以上を実行すると、/src/app配下は下記のように構成になる。

.
├── app-routing.module.ts
├── app.component.css
├── app.component.html
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── feature
│   ├── feature.component.css
│   ├── feature.component.html
│   ├── feature.component.spec.ts
│   ├── feature.component.ts
│   ├── main
│   │   ├── main.component.css
│   │   ├── main.component.html
│   │   ├── main.component.spec.ts
│   │   └── main.component.ts
│   └── sub
│       ├── sub.component.css
│       ├── sub.component.html
│       ├── sub.component.spec.ts
│       └── sub.component.ts
└── home
    ├── home.component.css
    ├── home.component.html
    ├── home.component.spec.ts
    └── home.component.ts

以上で、今回のアプリケーションに必要なコンポーネントは揃っている*2。今回のサンプルアプリでは、ネストの構造がわかりやすいように少しだけHTMLを編集しているが、本質的ではないので説明は省略する。

AppRoutingModuleを修正する

次に、AppRoutingModule(/src/app/app-routing.module.ts)を修正していく。このファイルは、ng newコマンド実行時に「ルーティングを使用する」を選択すると自動で作成されるが、自分で作っても良い。

/* import文省略 */
const routes: Routes = [
/* 追加する部分はここから */
  {path: '', component: HomeComponent}, 
  {path: 'feature', component: FeatureComponent,
    children: [
      {path: '', component: MainComponent},
      {path: 'sub', component: SubComponent}
    ]
  }
/* ここまで */
];

@NgModule({
  imports: [RouterModule.forRoot(routes)], // forRoot() を利用していることに注目
  exports: [RouterModule]
})
export class AppRoutingModule { }

forRoot()に渡しているroutes変数に、複数の要素を付加していく。path属性で指定したURLにアクセスすると、component属性で指定したコンポーネントが表示される。そして、ネストされたルートはchildren要素で指定すればよい。ここでは、FeatureComponentの内側のrouter-outletタグに、/featureにアクセスした場合にはMainComponentが、/feature/subにアクセスした場合にはSubComponentが表示されるように設定している。

ここまでで、実装ができたはずだ。改めて、このブランチのURLを貼っておく。

フィーチャーモジュールの切り出し(通常のロード)

ここまでで、機能としては実現できている。しかし、ルートモジュールであるAppModuleが個々のコンポーネントを全て知っている状態になっているのが気になる。今回のサンプルコード程度のコンポーネント数であれば問題はないが、長期的には管理しづらくなってしまう。そこで、Angularのモジュールの機能を用いる。モジュールとは、コンポーネントやサービスなどのファイルを束ねるためのものだ。

ちなみに、AppModuleも名前が示しているようにモジュールであり、これを/src/main.tsで下記のように指定することで、Angularアプリケーションが立ち上がった際に読み込まれるようになっている。

/* 略 */
platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

原則として、AppModuleで読み込んでいるモジュールがそのアプリケーションで使えるモジュールとなる*3。逆に言えば、AppModuleは下位にあるフィーチャーモジュールを読み込むことさえすれば、あとの管理は(ルーティングを含めて)そのフィーチャーモジュールに委譲することができるというわけだ。

Angular CLI を用いたモジュールの作成

さて、モジュールを作成していく。ここでもAngular CLIを利用する。

ng generate module feature --routing

上記のコマンドにより、Angular CLI で feature のモジュールを作成する。--routing オプションを付与することで、下記の2つのモジュールが生成される。

  • /feature/feature.module.ts
  • /feature/feature-routing.module.ts

github.com

FeatureRoutingModuleへのルーティング記述の移植

AppRoutingModuleに記載していたルーティングの記述を、FeatureRoutingModule(/feature/feature-routing.module.ts)に移植していく。ここはカット&ペーストしてしまえばよい。

/* import文省略 */
const routes: Routes = [
/* 移植したのはここから */
  {path: 'feature', component: FeatureComponent,
  children: [
    {path: '', component: MainComponent},
    {path: 'sub', component: SubComponent}
  ]}
/* ここまで */
];
 @NgModule({
  imports: [RouterModule.forChild(routes)], // AppRoutingModuleではforRoot()だったのがforChild()であることに注目
  exports: [RouterModule]
})
export class FeatureRoutingModule { }

FeatureModuleにコンポーネントを移植する

ルーティングの設定は以上で完了だ。しかし、このままではアプリケーションは機能しない。AppModuleでimportされ、declarationsに加えられていたフィーチャーコンポーネント(Feature/Main/Sub)を、フィーチャーモジュールに移植してやらないといけない。また、せっかく作ったFeatureRoutingModuleをFeatureModuleでimportしていることも確認しておく。

/src/app/feature/feature.module.ts

/* import文省略 */
@NgModule({
  declarations: [
    FeatureComponent, // AppModuleから移植
    MainComponent, // AppModuleから移植
    SubComponent // AppModuleから移植
  ],
  imports: [
    CommonModule,
    FeatureRoutingModule, // ルーティングモジュールをimportしている
  ]
})
export class FeatureModule { }

これで、フィーチャーのコンポーネントについての情報はルートのルーティングモジュールからは削除できる。その代わりに、FeatureModuleをAppModuleでimportすることで、間接的にFeatureRoutingModuleを利用できるようにする。

/* import文省略 */
@NgModule({
  declarations: [
    AppComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule, 
    FeatureModule // これを追加する
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

これで、ルートであるAppModuleとAppRoutingModuleからはフィーチャーのコンポーネントやルーティングについての知識が消え、FeatureModuleに委譲することができた。フィーチャーのコンポーネントを読み込むのも、それを特定のURLに割り当てるのも、FeatureModuleの役割ということになる。

遅延ロードへの変更

さて、最後に、遅延ロードへの変更を行う。遅延ロードとは、読んで字のごとく、フィーチャーのコンポーネント(やサービスなど、モジュールに含まれるもの)の読み込みを必要になったタイミングまで遅らせることだ。先に読み凍んでおくことでスムーズな画面の切り替えが可能になるのがSPAの良さだが、あまり使われないのに重い画面などがある場合には却って初回のロードが長くなってしまう。遅延ロードを利用することで、読み込みのタイミングをずらすことができる。

AppRoutingModuleにルーティングを再び追加する

遅延ロードは、フィーチャーモジュールの読み込みを、URLへのアクセスのタイミングまで遅らせることによって実現する。そうであるとすれば、第二段階でしたように、/featureというパス自体の情報をFeatureModule(より正確に言えば、それが読み込んでいるFeatureRoutingModule)に留めておくわけにはいかない。

app-routing.module.tsに再度パスを追加し、Componentは記載せずにloadChildrenを記載する。読み込みの対象となるフィーチャーモジュールを、[ファイル名(拡張子不要)]#[クラス名]という指定する。ファイルの冒頭でimportする必要はない。

const routes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'feature', loadChildren: './feature/feature.module#FeatureModule'} // パスを再び記載する
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

FeatureRoutingModuleからURLの情報を削除する

また、/featureというURLの情報はAppRoutingModule側に移してしまったので、FeatureRoutingModuleにはその情報は余計だ。削除する。

const routes: Routes = [
  {path: '', component: FeatureComponent,  // path: 'feature' だったところを path : '' に修正
  children: [
    {path: '', component: MainComponent},
    {path: 'sub', component: SubComponent}
  ]}
];
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class FeatureRoutingModule { }

FeatureModuleのAppModuleでの読み込みを削除する

最後に、AppModuleでFeatureModuleを読み込むのをやめる。すでに、AppRoutingModuleで遅延してロードするモジュールとしてloadChildren: './feature/feature.module#FeatureModule'と指定しているのだから、AppModuleから先に読み込んでしまってはいけない。

@NgModule({
  declarations: [
     AppComponent,
     HomeComponent
  ],
  imports: [
    BrowserModule,
// ここでFeatureModuleをimportしていた
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]

これで、遅延ロードに変更することができた。遅延ロードができているかどうかを確認したい方は、フィーチャーモジュールのコードのどこかにconsole.log()か何かを仕込んでみるだけでも確認ができる。

まとめ

  • Angular で「ネストされたルート」を実装した
  • ルートモジュールからフィーチャーモジュールを切り出した
  • フィーチャーモジュールを遅延ロードするように変更した

ルーティングを思い通りに実装できると、SPAの骨格を作ることができると思う。まず骨格を作った上で、個々のコンポーネントやサービスを充実させていくのがひとつの道筋になるのではないだろうか。Angularはまだ勉強し始めたばかりなのだが、これから他の機能も試していきたい。


write-blog-every-week Advent Calendar 2018 、明日の記事の担当は、KIDANI Akito@kdnakt さんです!*4

kdnakt.hatenablog.com

*1:筆者はAngularの入門者であることをあらかじめご了承願いたい。もし記述に誤りを見つけた方がいれば、コメントやTwitter、GitHubでご連絡をいただけるとありがたい。

*2:ng generateコマンドでコンポーネントを作成すると、自動的にapp.module.tsが更新され、新規作成したコンポーネントをimport文で読み込み、declarationsに追加してくれる。手動でコンポーネントを作る場合は、モジュールに追加するのを忘れてはならない。

*3:遅延ロードはその例外という位置付けになる。

*4:公開されたのでリンクを貼った。

後追いじゃない「成長」が欲しい

この記事は、#セイチョウ・ジャーニー Advent Calendar 9日目の記事です。

前日の記事は、べこ(@becolomochi)さんの「仕事を通して成長について考えてみた」でした。

note.mu

「成長とは習慣の改善である」?

2018年10月8日に開催された「技術書典5」において、「Growthfaction」というサークルから『セイチョウ・ジャーニー』が頒布された。

booth.pm

僕はこのサークルのメンバーではないが、知人が複数関わっていることから、「付録A みんなのセイチョウ・ジャーニー」に寄稿をさせていただいた。指定のテーマである「あなたにとっての成長とは」という問いに対して、下記のように書いた。

悪い習慣を捨てて、良い習慣を身に付けること。そして、身に付けた良い習慣をより優れた習慣にすることです*1

寄稿をしてから、このテーマについては折に触れて再考する機会があった。その過程で、なぜ上記のような内容で寄稿をしたのかを顧みることにもなったので、(寄稿した文章より長いが)補遺としてまとめておきたい。

先に全体の趣旨を述べておく。習慣という言葉を使ったのは、成長というものを、時代の流れ、状況の変化に翻弄されるようなものとは切り離して考えたかったからだ。僕は、1年、3年もすれば消費期限が切れてしまうようなスキルを身に付けることを、成長とは捉えていない。成長というのは、もっと持続的で連続的なものだと思っている。そうでなければ、成長するというのは外界への反応でしかなくなってしまう。そうではない成長のあり方として、習慣というものを掲げたのだ。

「後追いの成長」の辛さ

よく、「エンジニアは技術を学び続けなければいけなくて辛いからマネージャーに……」という言葉が批判される。これ自体は藁人形論法のようにも思えるのだが、エンジニアが技術にキャッチアップすることが不可欠な職種であり、それを苦しく思う人がいるのは恐らく事実だ。上の発言をする人が苦しんでいるのは、技術が日進月歩であり、常にそれにキャッチアップしていかなければ、仕事ができなくなってしまうという切迫感があるからだろう。

もちろん、マネージャーも学び続けなければならない。マネージャーが扱う個々の人、組織はそれぞれに固有のものを持っており、誰一人(どれひとつ)として同じものはない。過去に上手くいった対応方法を他の場面に適用するだけで全てが解決するような仕事ではない。

しかし一方で、人や組織の固有性は、常に新しいものが生まれてきているというよりは、いくつかの山の存在する分布のなかでのバリエーションというイメージが近い。だから、当然全ての人や組織に当てはまる解決策を完璧に身につけることはできないのだけれども、ある程度の典型例への対応方法を身につけ、そこからの「ずれ」へのアジャストをより精緻に行なえるように状況の認識力と対応の引き出しを増やしていくというアプローチが取れそうだ。

人や組織に対応する仕事の場合は、それまでに身につけていたものが全く適用できなくなるような地殻変動はあまりイメージできない。もちろん人のライフスタイルや組織のあり方、社会通念の変化で時代遅れとなる方法は存在するが、人間という生き物のあり方はそうそう大きく変わるものではないから、人間についての知見の消費期限は短くない。

これに対して、新たな人工物が生まれるスピードは速い。技術は日進月歩だ。ある日突然ではないにせよ、じわりじわりと世界が変わっていき、数年の間で全くゲームのルールが変わってしまうというのはありうる事象だろう。だから、新しいものについていかないといけないように感じる。未来の技術をあらかじめ学んでおくことはできないから、学びは常に後追い的なものになる。その学びに持続性はない。技術者としての学びは、変わりゆく状況にその都度対応するものになる。それは成長と言えるのだろうか。

未来の自分に何を渡せるか

未来の自分の代わりに未来の技術を学ぶことはできない。未来の自分が時代の変化についていってくれるかどうかはわからない。では、「未来の自分のために何ができるか」を問えばよいのか。未来の自分のために現在の自分が何かをしてあげるという発想もそれはそれで辛い。とはいえ、未来なんて知ったことはないと開き直れるの人はそもそも悩まない。

現在の自分にできるのは、未来の自分が新しいことを学ぶための素地を整えておくことだけだ。それは一段階、メタなレベルの能力ということになる。メタというのは、学ぶための学び、スキルのためのスキル、能力のための能力ということだ。素地の整え方としては、比較的消費期限の長い知識を身につけておくことがひとつ考えられる。

エンジニアであれば、基盤となるような技術について学んでおくことは有意義だろう。変化の激しいと言われるWeb(特にフロント)技術とはいえ、結局はTCP/IPの枠組みの中での変動ですよね、という話を知人としたことがあったし、NoSQLがSQLやリレーショナルデータベースを駆逐したわけでもない(そもそもNoSQLは"Not Only SQL"だとよく指摘されている)。あるいは、設計や開発手法などの抽象化された事柄を学ぶのも役立つだろう。

やや脱線するが、自分が好んで学ぶのはこういった部分だ。あまり意識したことはなかったが、「すぐに消費期限が切れそうなものは学びたくない」という心理が働いていたかもしれない。「オブジェクト指向」や「パターン」といった抽象的なものを学ぶことはもちろん無駄にはならないだろうし、上手く学べば優れた戦略となるだろう。戒めなければならないのは、現在すでに存在している具体的なものの学習から逃げるための方便として使ってはならないということだ。必要なら具体的なものを学ばなければならないし、新しい言語やツールを学ぶことは大切だ。それは次に述べることにも関連している。

後追いにならない成長としての「習慣の改善」

未来の自分に渡せるものは知識だけではない。ここで「習慣」というものが出てくる。習慣は定義上、持続性のあるものだ。基礎的な知識もまた忘却を免れないのに対して、習慣はそれが習慣である限り持続する。習慣を通じて自己のうちに一貫性を見出すことができるし、一貫性を見出すことでその改善という連続的な進歩を感じることもできる。

良い習慣を身につけ、それを維持・改善するのは、現在の自分が未来の自分のためにできることだ。そして、未来の自分はその良い習慣を受け取り、そこから果実を得ながら更に習慣を改善することができる。習慣化することによって行動にかかる労力は低下するから、さらに優れた、本来であれば多くの労力を必要とする行動にも出やすくなる。

「新しい技術を学ぶ」ということの意義も、習慣ということを考えるとより大きく評価できる。現在において新しい技術を学ぶことは、その技術についての知識や、学ぶ過程で得られる周辺知識を与えてくれるだけでない。もし、そこで学んだ技術を実際の業務などに活かすことができず、使わないままに忘れてしまったとしても、新しい技術を学ぶ習慣さえ身につけていれば、学びは(歩どまり率は悪くても)蓄積されていくし、未来の自分が新しい技術を学ぶことを楽にしてくれる。

また、良い習慣に基づいて行われる思考や行動は、現在の自己に与えられた課題に対する応答としても優れているものでありうる。ここで念頭に置いているのは、ものごとの受け止め方や、コードの書き方などだ。人に何か否定的なことを言われたときに反射的に感情で応じるのではなく一旦飲み込むとか、コードを書くときに保守する人間のことを考えるとか、そういった行動は、現在において役に立つものである。こういった思考・行動を習慣化することができれば、「未来のために現在を消費する」というだけでなく、現在をより良く過ごすことにも繋がる。

まとめに代えて

以上、「成長は習慣の改善である」という定式化の背景を成す考えを示してみた。まとめに代えて、この記事のテーマと密接に関わる二冊の本を紹介して終えることとする。

このような発想に立ったときに、どのような習慣を身につけば良いかということについては、『七つの習慣』がやはり最も著名で手に取りやすい教材となる。帯に著名人の名前がずらりと並んでいるなど、売られ方が実に「自己啓発本」らしくて鼻につくのだが、中身はさすがに優れている。P/PCバランスや「重要だが緊急ではないこと」、「Win-Win or No Deal」といったシンプルだが有用なアイデアも多く得ることができる。

完訳 7つの習慣 人格主義の回復

完訳 7つの習慣 人格主義の回復

また、現代人の、とりわけ職業人にとってそのまま役立つかどうかはわからないが、考え方の枠組み、議論の進め方のお手本としては、古典中の古典であり、『七つの習慣』の思想的源流の一つであるアリストテレス『ニコマコス倫理学』を挙げておきたい。古代ギリシア哲学というとハードルが高いように思うかもしれないが、幸福と徳、それと習慣との関係が卑近な例も用いられながら議論されている。複数の訳本が存在するが、下に掲げた光文社古典新訳文庫の訳は新しいこともあり平易で読みやすく、訳注や解説も充実しているのでおすすめだ。

ニコマコス倫理学(上) (光文社古典新訳文庫)

ニコマコス倫理学(上) (光文社古典新訳文庫)

明日の記事は、このすみ(@konosumi)さんです*2

www.konosumi.net

*1:『セイチョウ・ジャーニー』93ページ。

*2:公開されたのでリンクを貼った。

ドラッカーの『経営者の条件』を読んだ

P. F. ドラッカーの『ドラッカー名著集1 経営者の条件』を読んだ。

ドラッカー名著集1 経営者の条件

ドラッカー名著集1 経営者の条件

 

読んだ、と書いたが、読んだのは記録によると2017年4月29日だ*1。この記事のベースは読んだときに書き留めていたメモであり、公開するつもりはなかった。しかし、下記のブログで紹介されていたことから、誰かの役に立つこともあるかもしれないと考え、公開することにした。 

nitt-san.hatenablog.com

ほぼ本文を切り貼りしただけのメモだったため、公開に際して、コメントを拡充し、引用の体裁を整えた。

組織全体の業績に責任を持とうとする者こそマネジメントである

肩書や地位がいかに高くとも、権限に焦点を合わせる者は自らが単に誰かの部下であることを告白しているにすぎない。これに対し、いかに若い新入りであろうと、貢献に焦点を合わせ成果に責任をもつ者は、最も厳格な意味においてトップマネジメントの一員である。組織全体の業績に責任をもとうとしているからである。(79)

入社1ヶ月の時期にこの本を読んでこの一節をメモっているのは我ながらいじらしい。あるいは、入社1ヶ月という時期だからこそ大真面目にメモすることができたとも言えるかもしれない。自分はすごいことができるわけじゃないんだ、ということを1年半を通して痛感させられ、(正当だとは思うが)一定程度の無力感を抱えるようになった今この一節を読むと、複雑な気持ちになる。

知識の全領域に自らの知識を位置付けるゼネラリスト

ゼネラリストについての意味ある唯一の定義は、「自らの知識を知識の全領域に正しく位置づけられる人」である。いくつかの複数の専門領域について知識をもつ専門家もいる。だがたとえ複数の専門領域をもっていてもゼネラリストとはいえない。単に、いくつかの専門領域のスペシャリストであるにすぎない。たとえ三つの領域に通じていても、一つにしか通じていない人と同じように偏狭でありうる。 しかし自らの貢献に責任をもつ者は、その狭い専門分野を全体に関係づけることができる。もちろんたくさんの知識分野を統合するなどということは決してできない。だが彼らは、自らの仕事の成果を生かしてもらうには、ほかの人のニーズや方向、限界や認識を知らなければならないことを理解する。(91)

当時の自分は、何を思ってこの一節をメモしたのだろうか。未経験でソフトウェア業界に入って、当初から「自分はスペシャリストにはなれない」、「でもゼネラリストにならなれる」、と考えていたのだろうか。

 この1年半の間のうちの多くの時期で、自分の頭を支配していた問いがある。それは、「技術で生きるか、マネジメントで生きるか」というものだ。「ゼネラリストでなければ」という命題でもって、この問い自体を消滅させてしまうことはできないが、マネジメントで生きていくなら技術は要らないとか、逆に技術で生きていくからマネジメントは要らないとか、そういう話はできないな、と改めて思う。

また、以前、勉強会で川口恭伸さんが紹介していた、MITの石井裕さんの言葉を思い出した。生半可な「ゼネラリスト」ではなく、MITメディアラボ教授という文句なしのスペシャリストの言葉は重い。

一人の人間がすべてでなきゃいけない。 すなわち、ひとつのラベルを貼って、レッテルを貼って、 あなたは技術者、あなたはCognitive Science(認知科学)、あなたはSociology、 といった時代ではもうなくなっている。 逆に解かなきゃいけない問題がこれだけ複雑になって、 人間、その信義、そのsociety、commitと、 これだけ複雑に絡んでいるときに、それをデザインするときに、ひとつの学問だけでやっていく時代はもう終わっている。

石井裕先生の2005年の講演のときにとったメモ - kawaguti’s diary 

「あなたに何を期待すればいいですか」と問う

上司が部下に何かをいおうと努力するほど、かえって部下が聞き違える危険は大きくなる。部下は、上司がいうことではなく、自らが聞きたいことを聞き取る。 ところが仕事において貢献する者は、部下たちが貢献すべきことを要求する。「組織、および上司である私は、あなたに対しどのような貢献の責任を期待すべきか」「あなたに期待すべきことは何か」「あなたの知識や能力を最もよく活用できる道は何か」を聞く。こうして初めてコミュニーケーションが可能となり容易となる。その結果、まず部下が、「自分はどのような貢献を期待されるべきか」を考えるようになる。そこで初めて、上司の側に、部下の考える貢献についてその有効性を判断する権限と責任が生じる。(93)

上司に対して、「自分に何を期待すべきか」を伝えようという話が、ドラッカーの別の本でもされていたように思う。それが強く印象に残っていて、半年前まではかなり上司に「自分はこう貢献できると思う」と伝えようとしていた気がする(うまく定式化も論拠づけもできていなかったが)。

数ヶ月前に、プロジェクトの中で、自分なりにボトルネックを探したつもりになって色々と動いてみていた時期に、上司から「お前に期待しているのはそこじゃない」という明確なメッセージをもらった。あのときはかなり落ち込み、上司に対しても不満を覚えたが、事あるごとに話に付き合ってもらって少しは状況が見えてきた今となってみれば、あれは上司にとって「部下の考える貢献についてその有効性を判断する権限と責任」を果たした行為だったんだろうと思う。

上司の強みを生かし、自分を活用させよう

企業、政府機関、その他あらゆる組織において、「上司にどう対処するか」で悩まない者はいない。実のところ答えは簡単である。成果をあげる者ならばみな知っていることである。上司の強みを生かすことである。これは世間の常識である。現実は企業ドラマとは違う。部下が無能な上司を倒し、乗り越えて地位を得るなどということは起こらない。上司が昇進できなければ 部下はその上司の後ろで立ち往生するだけである。たとえ上司が無能や失敗のために更迭されても、有能な次席があとを継ぐことはない。外から来る者があとを継ぐ。そのうえその新しい上司は息のかかった有能な若者を連れてくる。したがって優秀な上司、昇進の早い上司をもつことほど部下にとって助けとなるものはない。しかも上司の強みを生かすことは部下自身が成果をあげる鍵である。上司に認められ、活用されることによって、初めて自らの貢献に焦点を合わせることが可能となる。自らが信じることの実現が可能になる。

あまり大きくない所帯に勤めていて、かつまだ最初の昇進すら経験していないので、ピンとくるわけではないが、この指摘は重要なのだろうと思う。自分の上司の強みが何か、というのは普段あまり考えることはない。自分が、自分が、というのが先に来てしまっていて、上司もまた一人の組織人であることを忘れていたかもしれない。

やらないことリストこそが大事

状況からの圧力は、未来をより過去を、機会よりも危機を、外部よりも内部を、重大なものよりも切迫したものを優先する。実は、本当に行うべきことは優先順位の決定ではない。優先順位の決定は比較的容易である。集中できる者があまりに少ないのは、劣後順位の決定、すなわち取り組むべきでない仕事の決定とその決定の遵守が至難だからである。延期とは断念を意味することを誰もが知っている。延期した計画を後日取り上げることほど好ましからざるものはない。後日取りあげてももはやタイミングは狂っている。タイミングはあらゆるものの成功にとって最も重要な要因である。(149)

青字の箇所が、メモを取った当時の強調で、赤字の箇所が今回つけた強調である。赤字の箇所は、アジャイルの文脈でよく言われる「やらないことリスト」を遵守することの重要さと難しさを指摘している。

青地のものについては、以前紹介した『Clean Coder』の一節と通ずるところがある。下記の引用は、やや強い主張ではあるものの、大事なことを言っているといつも思っている。

緊急時になれば、自分が何を信じているのかがわかる。規律を守っていれば、その規律を本当に信じていると言うことだ。逆に言うと、緊急時に普段の行動を変えてしまえば、その行動を信じていないと言うことだ。平常時にTDDの規律を守り、緊急時にそれを守らないとすれば、TDDの効果を心から信じていないということだ。平常時にコードをクリーンに保ち、緊急時に乱雑にするのであれば、乱雑が速度を落とすことを信じていないのだ。平常時にペアを組まず、緊急時にペアを組むのであれば、ペアのほうが効率的だと信じているのだ。緊急時に安心して守れるような規律を選ぼう。そして、それを常に守ろう。規律を守ることが緊急時から逃れる最善の方法である。ピンチに陥っても行動を変えてはいけない。規律が最善の方法であれば、緊急時になっても守るべきである。(156)

Clean Coder を読んだ - こまどブログ

読んだときの感想と再読に向けて

さすがにドラッカー先生で、正しそうな洞察に満ちている。

それが本当に正しいかどうかは、現実を見ることによってしかわからないだろう。

これは以前の感想。1年半という短い時間ではあるものの、多少なりとも「現実を見る」ことをした今の自分には、果たしてドラッカーのこの本はどう読めるだろうか。時間があればゆっくり読み直したい。

 

*1:入社後1ヶ月も経っていない時期。