最近の変更

以下は、サイトの最近の更新の一覧です。この情報はRSSフィードとしても入手でき、新しい記事はTwitterMastodonで発表しています。

このページでは、新しい記事と既存の記事への追加の両方をリストしています。記事を分割して公開することが多いため、このページの多くのエントリは最近公開された記事への新しい分割となり、このような発表はインデントされ、ホームページの最近の変更セクションには表示されません。


フォトストリーム 130

2024年4月21日(日) 18:21 EDT

カリフォルニア州ビッグサー


レガシー置き換えにおけるデータレプリケーションの利用

2024年4月10日(水) 11:00 EDT

Alessio FerriTom Coggraveは、データレプリケーションをどのように使用できるかを検討することで、メインフレームシステムにシームを導入することに関する記事を完成させました。うまくやれば、置き換え作業を迅速に開始できますが、新しいシステムをレガシースキーマに結合することに注意する必要があります。

詳細…


メインフレームのバッチパイプラインにおけるシームの作成

2024年4月4日(木) 09:39 EDT

メインフレームの処理は、データファイルを消費および作成するバッチプロセスのパイプラインに編成されることがよくあります。Alessio FerriTom Coggraveは、これらのパイプラインにシームを導入するために発見したいくつかの方法を示し、処理を代替プラットフォームのステップで置き換えることができるようにしました。

詳細…


メインフレームの外部インターフェースにおけるシームの発見

2024年4月2日(火) 09:46 EDT

Alessio FerriTom Coggraveは、データベースを粗粒度のシームとして扱うことで、アプリケーションの内部シームの分析に進みます。彼らは、データベースのリーダーとライターにシームを導入する方法を説明します。

詳細…


LinkedInに参加

2024年3月28日(木) 12:26 EDT

Twitterのイーロン・マスク化が進むにつれて、新しい専門的な資料を把握するためにLinkedInを利用する人が増えているという声をよく聞くようになりました。そこで、数週間前に、LinkedInアカウントを設定しました。これにより、人々がそのプラットフォームで私をフォローできるようになります。

私はこれまでLinkedInを避けてきました。つながりの雰囲気がどうも気に入らなかったのです。ただでさえ、つながりたいという人からのスパムが多すぎます。しかし、LinkedInは「クリエイターモード」を追加しました。これにより、双方向のつながりではなく、投稿のために誰かをフォローすることが推奨されます。今のところ、うまく機能しているようなので、ここでのすべての更新をそのアカウントにも投稿することにしました。ただし、私はまだつながりを避けているので、一緒に実質的な仕事をしたことがない限り、つながりリクエストは送信しないでください。

私はまだX(Twitter)に投稿していますが、着実に悪化しているので、私の注意は減っています。そこで私をフォローしている場合は、可能であれば他のフィードのいずれかに切り替えることをお勧めします。

私は自分のフィードについてはLinkedInがあまり好きではありません。制御があまりできないからです。サイトの提案は決して好きではありません。人々のシンプルなフィードの方が好きです。残念ながら、LinkedInにはリストがなく、誰かがいいねしたものをすべて単一の接続フィードにプッシュします。これにより、投稿が多すぎて、あまり注意を払わなくなります。


さようなら、ジョン・コーディバック

2024年3月27日(水) 12:48 EDT

大切な同僚であり友人であったジョン・コーディバックが先週、64歳で亡くなりました。

詳細…


メインフレームの外部インターフェースにおけるシームの発見

2024年3月27日(水) 10:36 EDT

Alessio FerriTom Coggraveは、2つの外部インターフェース領域で調査したシームの詳細を説明し始めます。ファイルのバッチ入力は、処理パイプラインの出力を比較しながら新しい実装にコピーされます。APIアクセスポイントはプロキシでカバーでき、トラフィックは徐々に新しい実装に転送できます。

詳細…


段階的な近代化のためのメインフレームのシームの発見

2024年3月26日(火) 09:32 EDT

メインフレームシステムは、世界のコンピューティングワークロードの多くを処理し続けていますが、増大するビジネスニーズをサポートする新しい機能を追加することが難しいことがよくあります。さらに、それらを拡張するのが遅くなるアーキテクチャ上の課題は、それらを置き換えるのも困難にします。関連するリスクを軽減するために、レガシー機能を最新テクノロジーの実装で徐々に置き換える、段階的なレガシー置き換えアプローチを使用します。この戦略では、メインフレームシステムにシームを導入する必要があります。これは、ロジックフローを新しいサービスに迂回させることができるポイントです。最近のプロジェクトで、Alessio FerriTom Coggraveは、長期間使用されているメインフレームシステムにこれらのシームを導入するためのいくつかのアプローチを調査しました。

詳細…


定性的なメトリクスをキャプチャする方法

2024年3月19日(火) 09:33 EDT

Abi NodaTim Cochranは、効果的にキャプチャする方法を概説することで、定性的なメトリクスに関する記事を完成させました。彼らは、人々が調査に回答するときに通過するメンタルステップについて話し、開発者のエクスペリエンスを評価するときに始めるためのテンプレートを提供します。最後のセクションでは、定性的および定量的なメトリクスがどのように連携するかについて説明します。多くの場合、最初に定性的なメトリクスを使用してベースラインを確立し、焦点を当てる場所を決定し、次に定量的なメトリクスを使用して特定の領域を掘り下げます。

詳細…


リファクタリングの冒頭の章のコードサンプル

2024年3月15日(金) 11:04 EDT

時々、人々がリファクタリングの冒頭の章で使用したコードのコピーを求めてくるので、自分で進めることができます。私はこのコードを提供しない理由がありました。具体的には怠惰です。幸いなことに、エミリー・バッシェはより献身的であり、彼女はgithubリポジトリ - Theatrical Players Refactoring Kata - をコードとともに設定し、リファクタリングを行うのに妥当なテストを十分に含めています。

ただし、リポジトリはこれにとどまらず、C、Java、Rust、Pythonなど、12の言語で同様のサンプルコードが含まれています。

彼女は最近、YouTubeチャンネルへの動画を投稿しました。その動画では、その章を読んでいるときにこのコードを使用することを推奨する理由を概説しています。彼女のチャンネルには、優れたコードテクニックに関する動画がたくさん含まれており、彼女の作品をサポートするPatreonがあります。


定性的なメトリクスの利点

2024年3月13日(水) 10:36 EDT

Abi NodaTim Cochranは、開発チームの生産性を評価するために定性的なメトリクスを使用することに関する議論を続けます。この回では、定性的なメトリクスを態度メトリクスと行動メトリクスに分類します。また、定性的なメトリクスを使用すると、測定できないものを測定したり、欠落している可視性を提供したり、定量的なデータに必要なコンテキストを提供したりできることがわかります。

詳細…


人間を介した開発者の生産性の測定

2024年3月12日(火) 09:36 EDT

開発者の生産性を測定することは難しい課題です。開発サイクル時間とスループットに焦点を当てた従来のメトリクスには限界があり、他にどこに目を向けるべきかについての明確な答えはありません。定性的なメトリクスは、開発者自身から得られたデータを使用して、開発者の生産性を測定および理解するための強力な方法を提供します。Abi NodaTim Cochranは、定性的なメトリクスとは何かを説明することから議論を開始し、主観的または信頼できないという理由でそれらを拒否すべきではない理由を説明します。

詳細…


毎日ペアをローテーションしたらどうなるか?

2024年3月6日(水) 10:33 EST

ペアプログラミングの場合、ペアを頻繁にローテーションすることが重要ですが、ペアプログラミングを行う多くの組織はそれを躊躇しています。Gabriel RobainaKieran Murphyは、「毎日ペアをローテーションしたらどうなるか?」という質問をし、毎日のペアローテーションの演習を通じて3つのチームと協力しました。彼らは、ペアリングの利点と課題、およびそれらを解決する方法をチームが振り返るのに役立つ軽量な方法論を開発しました。最初の懸念は克服され、チームは頻繁にペアをローテーションすることの利点を発見しました。彼らは、ペアの交換を頻繁に行うと、ペアリングの利点が大幅に向上することを学びました。彼らの記事は、彼らが開発した方法論、観察結果、参加チームメンバーが共有した共通の懸念と洞察を共有しています。

詳細…


レガシー置き換えのパターン:イベントインターセプション

2024年3月5日(火) 10:03 EST

レガシーシステムを徐々に置き換える場合、レガシーシステムとその代替システムが相互作用する必要があるケースがたくさんあります。これらのレガシーシステムは変更が難しく、コストもかかることが多いため、レガシーシステムへの影響を最小限に抑えながら、代替システムの要素を統合できるメカニズムが必要です。Ian Cartwright、Rob Horn、James Lewisは、状態変化イベントでイベントインターセプションをどのように使用して、それらを代替システムに転送できるかを説明します。

詳細…


Bliki: 定期的な対面

2024年2月27日(火) 09:17 EST

コミュニケーション技術の進歩により、リモートファーストスタイルで作業するチームが増加しており、この傾向は新型コロナウイルス感染症のパンデミックによる強制的な隔離によって後押しされました。しかし、リモートで作業するチームでも対面での集まりから恩恵を受けることができ、数か月ごとに実施する必要があります。

リモートファーストのチームでは、全員が個別の場所にいて、電子メール、チャット、ビデオ、その他のコミュニケーションツールで完全にコミュニケーションをとります。明確な利点があります。世界中からチームにメンバーを募集でき、介護責任のある人を巻き込むことができます。イライラの募る通勤の無駄な時間を、生産的な時間や回復時間に充てることができます。

しかし、人々がどれほどリモートワークが得意であっても、最新のコラボレーションツールがどれほど優れていても、チームの他のメンバーと同じ場所にいることに勝るものはありません。人間の相互作用は、対面で行われると常に豊かになります。ビデオ通話は、適切な人間関係を構築する雑談の時間がほとんどなく、取引的なものになりがちです。そのような深い絆がないと、誤解が深刻な人間関係の困難に発展し、全員が直接話すことができれば効果的に解決できるはずの状況にチームが巻き込まれてしまう可能性があります。

リモートファーストの仕事で効果的な人によく見られるパターンは、定期的な対面会議を確実に行うことです。これらの会議では、一緒に作業した方が効果的に行える作業要素をスケジュールします。リモートワークは、1人で集中する必要があるタスクに効果的であり、最新のツールを使用すると、リモートペアリングを実行できます。しかし、多くの人々からのインプットと迅速なフィードバックが必要なタスクは、全員が同じ部屋にいるときの方がはるかに簡単です。ビデオ会議システムでは、そのような深い対話を作成することはできません。他の人が何をしているかを確認するためにコンピューター画面を見つめるのは疲れることであり、休憩のために一緒にコーヒーを飲みに行く機会はありません。製品戦略に関する議論、システムアーキテクチャの探求、新しい分野の探求 - これらはチームが集合した際の一般的なタスクです。

人々が効果的に協力するためには、互いを信頼し、互いにどれほど頼ることができるかを認識する必要があります。信頼はオンラインでは育むのが難しく、同じ部屋にいるときに発生する可能性のある社会的合図はありません。したがって、対面での集まりの最も価値のある部分は、スケジュールされた作業ではなく、コーヒーを飲みながらの雑談や、昼食を囲んでの歓談です。仕事とは関係のない非公式な会話は、仕事の相互作用をより効果的にする人間関係を築きます。

これらのガイドラインは、対面での会議の内容がどのようなものであるべきかを示唆しています。一緒に働くことは、それ自体が価値があるだけでなく、チームの結束を深める上で重要な要素です。そのため、私たちは1日をかけて、一緒にいることで得られる低レイテンシーのコミュニケーションからメリットを享受できるタスクに焦点を当てるべきです。そして、休憩、雑談、オフィス外に出る機会には、少し多すぎるかなと感じるくらいの時間を確保するべきです。私自身が嫌いなこともあり、「チームビルディング」のような人工的な活動は避けるでしょう。このような集まりを企画する人は、参加者全員がその後活気づき、数週間後の業務でより効果を発揮できるようになることを重視しています。

リモートチームは、遠く離れた場所にメンバーがいて、何時間も移動しなければならないという状況も珍しくありません。このようなチームの場合、私は2~3ヶ月ごとに1週間集まることを目安にしています。チームが熟練してくれば、集まる頻度を減らすことも検討できますが、少なくとも年に2回は対面での会議を開催していないチームは心配です。チーム全員が同じ都市にいるものの、通勤時間を減らすためにリモートファーストのスタイルを採用している場合は、より短い集まりをより頻繁に開催することができます。

このような集まりは、オフィススペースの構成を見直すきっかけになるかもしれません。パンデミック以降、オフィスの利用頻度が大幅に低下していることはよく知られています。オフィスは、日々の作業場ではなく、このような不定期なチームの集まりの場所になる可能性が高いでしょう。そのため、柔軟で快適なチームの集まりのスペースが必要になります。

一部の組織は、このようなチームの集まりのための移動費や宿泊費に難色を示すかもしれませんが、これはチームの効率を高めるための投資と考えるべきです。これらの対面での会議を怠ると、チームは行き詰まり、間違った方向に進み、対立に悩まされ、人々のモチベーションが低下します。これに比べれば、飛行機やホテルの費用を節約するのは、全く意味がないことです。

関連資料

リモートファーストはリモートワークの一形態です。リモートワークのさまざまなスタイルとそのトレードオフについては、「リモートワークと共同オフィスワークの比較」で詳しく説明しています。

Thoughtworksでは、約20年前にオフショア開発センターを始めたときから、リモートチームにとって定期的な対面での集まりが重要であることを学びました。これらの経験から、「オフショア開発でのアジャイルソフトウェアプロセス」で説明する実践方法が生まれました。

リモートワーク、特にタイムゾーンをまたぐ場合は、非同期的なコラボレーションのパターンがより重要になります。私の同僚であるプロダクトマネージャーのSumeet Mogheは、彼の著書「The Async-First Playbook」で、この方法を詳しく解説しています。

ソフトウェア製品会社であるAtlassianは、最近リモートワークに完全に移行し、その経験に関するレポートを発表しました。彼らは、チームが年に3回程度対面で集まるのが賢明であることを学びました。Claire Lewは2018年にリモートファーストチームを調査し、回答者の4分の1が「年に数回」リトリートを実施していると述べています。37Signalsは、ほぼ20年間リモートファーストの会社として運営されており、年に2回ミートアップをスケジュールしています。

謝辞

Alejandro Batanero, Andrew Thal, Chris Ford, Heiko Gerin, Kief Morris, Kuldeep Singh, Matt Newman, Michael Chaffee, Naval Prabhakar, Rafael Detoni, and Ramki Sitaramanが、社内メーリングリストでこの投稿の草稿について議論しました。


LLMアプリケーション開発のエンジニアリングプラクティス

2024年2月13日 火曜日 12:22 EST

LLMエンジニアリングには、プロンプト設計やプロンプトエンジニアリング以上のものが含まれます。ここでは、David TanJessie Wangが、テストやリファクタリングなどの通常のエンジニアリングプラクティスが、プロトタイプLLMアプリケーションを迅速かつ確実に提供するのにどのように役立ったかを振り返っています

詳細…


オンボーディングのボトルネック:最終回

2024年1月31日 水曜日 11:57 EST

TimとPremが、効果的なオンボーディングに関する記事を締めくくります。彼らは、ペアプログラミングの価値、個人の環境のセットアップ、およびプロセスから摩擦を取り除くことについて議論します。

詳細…


オンボーディングのボトルネック:優れたオンボーディングのためのさらなるステップ

2024年1月30日 火曜日 09:33 EST

TimとPremが、効果的なオンボーディングプロセスのためのステップについて引き続き概説します。彼らは、新入社員を企業文化に含めること、オファー後の対応と初日の体験を成功させること、およびセルフサービス型ナレッジマネジメントへの投資について語っています。

詳細…


補完によるEmacsエクスペリエンスの向上

2024年1月25日 木曜日 13:20 EST

私は長年Emacsを使用しており、ウェブサイトの執筆、書籍の執筆、そしてほとんどのプログラミングに使用しています。(例外は、Java用のIntellJ IDEAとR用のRStudioです。)そのため、ここ数年でEmacsの機能が向上し、進化の袋小路ではないと感じられるようになったことを嬉しく思っています。Emacsのエクスペリエンスを大きく向上させたものの1つは、補完リストに正規表現を使用することです。

多くのEmacsコマンドは、選択する項目のリストを生成します。ファイルを(開いて)アクセスしたい場合、ファイルを見つけるためのキーコンビネーションを入力すると、Emacsはミニバッファー(コマンドとやり取りするための特別な領域)に候補ファイルのリストを表示します。これらのファイルリストは非常に長くなる可能性があり、特に現在のプロジェクトのすべてのファイルを要求した場合は顕著です。

目的のファイルを指定するために、リストをフィルタリングするテキストを入力できます。たとえば、articles/simple/2024-emacs-completion.mdというファイルを開きたい場合は、emacsと入力する可能性があります。そのファイルだけを取得する必要はなく、十分な小さなリストにフィルタリングするだけで十分な場合がよくあります。

私が最も役立つと思う正規表現ビルダーの特定のスタイルがあり、それは正規表現をスペースで区切るものです。これにより、articles emacsと入力して、ファイルパスに「articles」と「emacs」が含まれるすべてのファイルパスのリストを取得できます。これは基本的に、文字列「articles emacs」を正規表現\\(articles\\).*\\(emacs\\)に変換します。さらに良いことに、このようなマッチャーを使用すると、正規表現を任意の順序で入力できるため、「emacs articles」も一致します。このように、最初の正規表現でフィルタリングされたリストが表示されたら、2番目の正規表現を使用して、最初の検索よりも前の区別する正規表現であっても、目的のものを選択できます。

このような補完マッチャーをインストールすると、Emacsの使用に大きな影響がありました。コマンドとやり取りするときに、大きなリストを簡単にフィルタリングできるようになったからです。最も重要な変更点の1つは、すべてのインタラクティブなEmacs関数のリストを表示するキーコンボであるM-xの使用方法です。リストをフィルタリングする正規表現マッチャーを使用すると、数回のキーストロークで名前を使用してEmacsコマンドを呼び出すことができます。これにより、キーボードショートカットを覚えておく必要がありません。これにより、M-xを介してあまり頻繁に使用しないコマンドを呼び出すことができます。開いているバッファーを頻繁にリスト表示することはないため、そのキーコンビネーションを覚えようとするのではなく、M-x ibと入力すると、ibufferがすぐに表示されます。これは、M-xに使用するコマンド(counsel-M-x)が、正規表現の最初の文字として「^」を挿入し、最初の正規表現を行の先頭に固定することによって助けられます。すべての自作関数にmf-というプレフィックスを付けているため、長い名前でも自分の関数を簡単に見つけることができます。URLからドメインを削除するコマンドを作成しました。それをmf-url-remove-domainと呼び、M-x mf urlで呼び出すことができます。

Emacsには、このようなマッチングを行うパッケージが多数あり、非常に混乱する可能性があります。最近使用しているのはIvyです。デフォルトではスペースで区切られた正規表現マッチャーを使用しますが、順序をサポートしていません。私が好きなように構成するには、次のようにします。

(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order)))

Ivyは、このような選択を強化するさまざまなコマンドを含むcounselというパッケージの一部です。

Ivyは、このようなことを行う唯一のツールではありません。実際、Emacsの補完ツールの世界は非常に混乱しており、重複や相互作用が多く、理解できないことがたくさんあります。この分野のツールには、HelmcompanyVertico、およびConsultなどがあります。Mastering Emacsには、ミニバッファー補完の理解に関する記事がありますが、そこで説明されているメカニズムがIvyの動作とどのように適合するかは説明されておらず、私はそれを理解する時間を使っていません。

そして、一般的な注意として、この素晴らしいツールの使い方を学ぶためにMastering Emacsという本を強くお勧めします。Emacsには非常に多くの機能があるため、私のような長年のユーザーでさえ、その本を読んで「そんなこともできるんだ」と驚くことがありました。

興味のある方のために、Emacsの設定の関連部分を以下に示します。

(use-package ivy
  :demand t
  :diminish ivy-mode
  :config
  (ivy-mode 1)
  (counsel-mode 1)
  (setq ivy-use-virtual-buffers t)
  (setq ivy-use-selectable-prompt t)
  (setq ivy-ignore-buffers '(\\` " "\\`\\*magit"))
  (setq ivy-re-builders-alist '(
                                (t . ivy--regex-ignore-order)
                                ))
  (setq ivy-height 10)
  (setq counsel-find-file-at-point t)
  (setq ivy-count-format "(%d/%d) "))

(use-package counsel
  :bind (
         ("C-x C-b" . ivy-switch-buffer)
         ("C-x b" . ivy-switch-buffer)
         ("M-r" . counsel-ag)
         ("C-x C-d" . counsel-dired)
         ("C-x d" . counsel-dired)
         )
  :diminish
  :config
  (global-set-key [remap org-set-tags-command] #'counsel-org-tag))

(use-package swiper
  :bind(("M-C-s" . swiper)))

(use-package ivy-hydra)

オンボーディングのボトルネック:効果への道のりを作成する

2024年1月24日 水曜日 10:45 EST

TimとPremが、新入社員のための効果への道のりを作成する方法について説明し、オンボーディングの困難から抜け出す方法についての議論を開始します。このような道のりは、従業員のニーズと、オンボーディングプロセスがそれらをどのように満たすべきかを概説します。

詳細…


スケールアップのボトルネック #06: オンボーディング

2024年1月23日 火曜日 09:13 EST

昨年はテクノロジー業界にとって厳しい年であり、世紀初めのドットコムバブル崩壊以来、最大の削減とレイオフの波に直面しました。2024年が始まるにつれて、好転の兆しが見え始めており、うまくいけばテクノロジー組織はすぐに採用について再び考えるでしょう。そのような幸せな日々が戻ってくると、企業は新入社員が効果を発揮するまでに時間がかかりすぎるという共通の問題に再び直面するでしょう。Tim CochranとPremanand Chandrasekaranは、スケールアップのボトルネックに関するシリーズの第6部でこれに対処します。この最初の記事では、TimとPremが、成長する組織がこのボトルネックに陥っている兆候について見ていきます。

詳細…


継続的インテグレーションの主要な改訂

2024年1月18日 木曜日 10:01 EST

世紀の変わり目、私は幸運にも継続的インテグレーションの実践を開発するいくつかのプロジェクトに関わることができました。この重要な実践に関する私たちの教訓を自分のウェブサイトに記事としてまとめ、そこでは今でも頻繁に参照されるリソースとなっています。昨年末、同僚から、20年近く経ったその記事は今でも役立つが、古くなっていると言われました。彼はいくつかの修正案を送ってきて、それをきっかけに私は、元の記事のすべてのセクションを検討し、過去20年間に現れた問題に対処するための新しいセクションを追加して、記事を徹底的に改訂しました

この数十年の間に、フィーチャーブランチングは業界で広く採用されてきました。私の多くの同僚は、継続的インテグレーションは多くのチームにとってより適切だと感じています。この記事が、読者がそれが当てはまるかどうかを評価し、もしそうなら、継続的インテグレーションを効果的に実装する方法を判断するのに役立つことを願っています。

詳細…


Bliki: レガシーシーム

2024年1月4日(木) 09:13 EST

レガシーシステムを扱う場合、シーム、つまりソースコードを編集せずにシステムの動作を変更できる場所を特定して作成することは価値があります。シームを見つけたら、それを使って依存関係を断ち切り、テストを簡素化し、観測性を得るためのプローブを挿入し、レガシー置き換えの一環としてプログラムの流れを新しいモジュールにリダイレクトすることができます。

マイケル・フェザーズは、著書「レガシーコード改善ガイド」で、レガシーシステムの文脈で「シーム」という用語を作り出しました。彼の定義は、「シームとは、プログラムの動作をその場所で編集せずに変更できる場所」です。

シームが役立つ例を次に示します。注文の価格を計算するコードを想像してください。

// TypeScript
export async function calculatePrice(order:Order) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await calculateShipping(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}

関数calculateShippingは外部サービスにアクセスしますが、これは遅く(かつ高価)であるため、テスト時にはアクセスしたくありません。代わりに、スタブを導入して、各テストシナリオに対して事前に用意された決定論的なレスポンスを提供したいと考えています。異なるテストでは関数から異なるレスポンスが必要になる場合がありますが、テスト内でcalculatePriceのコードを編集することはできません。したがって、テストでスタブへの呼び出しをリダイレクトできるように、calculateShippingへの呼び出しの周りにシームを導入する必要があります。

これを行う1つの方法は、calculateShippingの関数をパラメーターとして渡すことです。

export async function calculatePrice(order:Order, shippingFn: (o:Order) => Promise<number>) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await shippingFn(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}

この関数の単体テストでは、単純なスタブを代用できます。

const shippingFn = async (o:Order) => 113
expect(await calculatePrice(sampleOrder, shippingFn)).toStrictEqual(153)

各シームには、イネーブルメントポイントが付属しています。「ある振る舞いを使用するかどうかを決定できる場所」です[WELC]。関数をパラメーターとして渡すと、calculateShippingの呼び出し元にイネーブルメントポイントが開きます。

これでテストがはるかに簡単になり、さまざまな配送コストの値を入れて、applyShippingDiscountsが正しく応答するかどうかを確認できます。シームを導入するために元のソースコードを変更する必要がありましたが、その関数に対するそれ以上の変更では、そのコードを変更する必要はなく、変更はすべてテストコードにあるイネーブルメントポイントで発生します。

関数をパラメーターとして渡すことは、シームを導入する唯一の方法ではありません。結局のところ、calculateShippingのシグネチャを変更することは困難な場合があり、本番コードのレガシーコールスタックを通じて配送関数パラメーターをスレッド化したくない場合があります。この場合、サービスロケーターを使用するなど、ルックアップがより適切なアプローチになる可能性があります。

export async function calculatePrice(order:Order) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await ShippingServices.calculateShipping(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}
class ShippingServices {
  static #soleInstance: ShippingServices
  static init(arg?:ShippingServices) {
    this.#soleInstance = arg || new ShippingServices()
  }
  static async calculateShipping(o:Order) {return this.#soleInstance.calculateShipping(o)}
  async calculateShipping(o:Order)  {return legacy_calcuateShipping(o)}
  // ... more services

ロケーターを使用すると、サブクラスを定義することで動作をオーバーライドできます。

class ShippingServicesStub extends ShippingServices {
  calculateShippingFn: typeof ShippingServices.calculateShipping =
     (o) => {throw new Error("no stub provided")}
  async calculateShipping(o:Order) {return this.calculateShippingFn(o)}
  // more services

その後、テストでイネーブルメントポイントを使用できます。

const stub = new ShippingServicesStub()
stub.calculateShippingFn = async (o:Order) => 113
ShippingServices.init(stub)
expect(await calculatePrice(sampleOrder)).toStrictEqual(153)

この種のサービスロケーターは、関数ルックアップを介してシームを設定する古典的なオブジェクト指向の方法であり、他の言語で使用する可能性のあるアプローチを示すためにここに示していますが、TypeScriptやJavaScriptではこのアプローチを使用しません。代わりに、このようなものをモジュールに入れます。

export let calculateShipping = legacy_calculateShipping

export function reset_calculateShipping(fn?: typeof legacy_calculateShipping) {
  calculateShipping = fn || legacy_calculateShipping
}

その後、このようなテストでコードを使用できます。

const shippingFn = async (o:Order) => 113
reset_calculateShipping(shippingFn)
expect(await calculatePrice(sampleOrder)).toStrictEqual(153)

最後の例が示すように、シームに使用する最適なメカニズムは、言語、利用可能なフレームワーク、そして実際にはレガシーシステムのスタイルに大きく依存します。レガシーシステムを制御下に置くということは、レガシーソフトウェアへの混乱を最小限に抑えながら、適切な種類のイネーブルメントポイントを提供するさまざまなシームをコードに導入する方法を学ぶことを意味します。関数呼び出しは、そのようなシームを導入する簡単な例ですが、実際にははるかに複雑になる可能性があります。チームは、使い古されたレガシーシステムにシームを導入する方法を理解するために数か月を費やす可能性があります。レガシーシステムにシームを追加する最適なメカニズムは、グリーンフィールドで同様の柔軟性を実現するために行うこととは異なる場合があります。

フェザーズの著書は主に、レガシーシステムをテスト対象にするということに重点を置いています。それが、レガシーシステムを健全な方法で操作できるようにするための鍵であることが多いためです。しかし、シームにはそれ以上の用途があります。シームがあれば、レガシーシステムにプローブを配置して、システムの可観測性を向上させることができます。calculateShippingへの呼び出しを監視して、使用頻度を把握したり、個別の分析のために結果をキャプチャしたりすることができます。

しかし、おそらくシームの最も価値のある使用法は、動作をレガシーから移行できることです。シームは、価値の高い顧客を別の配送計算機にリダイレクトする可能性があります。効果的なレガシー置換は、レガシーシステムにシームを導入し、それらを使用して、徐々に動作をより近代的な環境に移行することに基づいています。

シームは、新しいソフトウェアを作成するときにも考慮すべきことです。結局のところ、すべての新しいシステムは遅かれ早かれレガシーになるでしょう。私の設計アドバイスの多くは、適切に配置されたシームを備えたソフトウェアを構築し、簡単にテスト、観察、および強化できるようにすることに関するものです。テストを念頭に置いてソフトウェアを作成すると、適切なシームのセットを取得する傾向があります。これがテスト駆動開発が非常に有用な手法である理由です。


2023年の私のお気に入りの音楽発見

2024年1月2日(火) 18:42 EST

また1年、6つのお気に入りの音楽発見を選ぶ時が来ました。2023年には、アンビエントブルーグラス、アフロアンデスのファンク、ノーサンブリアの小型パイプ、踊るコラ、ウクライナのフォークジャズが含まれます。

詳細…


Bliki: ソフトウェアとエンジニアリング

2023年12月13日(水) 00:00 EST

私のキャリアを通じて、人々はソフトウェア開発を「従来の」エンジニアリングと比較してきましたが、それは通常、ソフトウェア開発者が適切な仕事をしていないことを叱るためのものでした。電子工学の学位を取得した者として、これは私のキャリアの初期に共感しました。しかし、この考え方は欠陥があります。なぜなら、ほとんどの人がエンジニアリングが実際にどのように機能するかについて誤った印象を持っているからです。

グレン・ヴァンダーバーグは、これらの誤解を掘り下げるために多くの時間を費やしており、ソフトウェア開発をエンジニアリングと比較したい人は、彼の講演「真のソフトウェアエンジニアリング」を視聴することを強くお勧めします。また、彼のポッドキャスト「Oddly Influenced」でのインタビューも聞く価値があります。残念ながら、彼にこの資料を書き留めるように説得することはできませんでした。素晴らしい記事になるでしょう。

この関係に関するもう1人の優れた思想家はヒレル・ウェインです。彼は「クロスオーバー」、つまり伝統的なエンジニアリングとソフトウェアの両方で働いた経験のある人々にインタビューしました。彼は、「私たちは本当にエンジニアなのか?」を皮切りに、一連のエッセイで彼が学んだことをまとめました。


Bliki: テスト駆動開発

2023年12月11日(月) 14:40 EST

テスト駆動開発 (TDD) は、テストを作成することでソフトウェア開発をガイドするソフトウェア構築手法です。これは、エクストリームプログラミングの一部として、1990年代後半にケント・ベックによって開発されました。本質的に、次の3つの簡単なステップを繰り返し実行します。

しばしばレッド-グリーン-リファクタリングと要約されるこれらの3つのステップがプロセスの核心ですが、最初にテストケースのリストを作成するという重要な初期ステップもあります。次に、これらのテストの1つを選択し、それにレッド-グリーン-リファクタリングを適用し、完了したら次のテストを選択します。テストを適切に順序付けることはスキルであり、設計の重要なポイントに迅速に到達できるテストを選択する必要があります。プロセスの過程で、思いついたときにテストをリストに追加する必要があります。

最初にテストを作成すること、つまりXPE2がテストファーストプログラミングと呼ぶことには、2つの主な利点があります。最も明白なのは、テストに合格するように機能コードを記述することによってのみ自己テストコードを取得する方法です。2番目の利点は、最初にテストについて考えることで、最初にコードへのインターフェイスについて考えさせられることです。インターフェイスとクラスの使用方法に焦点を当てることで、インターフェイスを実装から分離することができます。これは、多くのプログラマーが苦労する優れた設計の重要な要素です。

TDDを台無しにする最も一般的な方法は、3番目のステップを無視することだと聞いています。コードをクリーンに保つためにリファクタリングすることは、プロセスの重要な部分です。そうしないと、コードフラグメントの乱雑な集合で終わります。(少なくともこれらにはテストがあるため、設計の失敗のほとんどよりも苦痛の少ない結果になります。)

関連資料

TDDを行うための規範的な方法に関するケントの要約が、オンライン上の重要な要約です。

詳細については、ケント・ベックの著書「テスト駆動開発」をご覧ください。

ジェームズ・ショアの「アジャイル開発の芸術」の関連章は、効果的なアジャイル開発の残りの部分にも関連付けて説明したもう1つの健全な説明です。ジェームズはまた、「Let's Play TDD」という一連のスクリーンキャストも作成しました。

リビジョン

このページの私の最初の投稿は2005年3月5日でした。ケントの規範的な投稿に触発されて、2023年12月11日に更新しました。


Bliki: 差分デバッグ

2023年12月4日(月) 00:00 EST

リグレッションバグとは、しばらく前から存在していたソフトウェアの機能で新たに発生したバグです。それらを調査するときは、通常、ソフトウェアのどの変更がそれらを発生させたかを理解することが価値があります。その変更を見ると、バグがどこにあるのか、それをどのように修正するのかについての貴重な手がかりが得られます。この形式の調査にはよく知られた用語はありませんが、私はそれを差分デバッグと呼んでいます。

差分デバッグは、コードがバージョン管理されている場合にのみ機能しますが、幸いなことに、今日ではそれが標準となっています。しかし、それを効果的に機能させるためには、さらにいくつかのことが必要です。ソフトウェアの古いバージョンを簡単に実行できるように、再現可能なビルドが必要です。高頻度の統合のため、小さなコミットがあると非常に役立ちます。そうすることで、問題のあるコミットが見つかったときに、何が起こったのかをより簡単に絞り込むことができます。

バグを生み出したコミットを見つけるには、まずバグのない過去のバージョンを見つけます。これをlast-goodバージョンとしてマークし、現在のバージョンをearliest-badとしてマークします。次に、2つのバージョンの中間のコミットを見つけ、バグが存在するかどうかを確認します。存在する場合は、このコミットがearliest-badになり、存在しない場合はlast-goodになります。問題のあるコミットが見つかるまで、このプロセス(「二分探索」または「バイナリ」検索)を繰り返します。

gitを使用する場合、git bisectコマンドは、この作業の多くを自動化します。バグの存在を示すテストを作成できる場合、git bisectはそのテストを使用することもでき、問題のあるコミットを見つけるプロセス全体を自動化できます。

私は、プログラミングセッション中に差分デバッグが役立つことにしばしば気づきます。実行に数分かかる遅いテストがある場合、最も関連性の高いテストのサブセットのみを実行しながら、30分ほどプログラミングするかもしれません。テストがすべてパスするたびにコミットしていれば、遅いテストのいずれかが失敗した場合、差分デバッグを使用できます。これは、長期的な履歴のためにsquashするのが最適だと感じるほど小さくても、非常に頻繁にコミットする価値です。一部のIDEでは、バージョン管理へのコミットよりもきめ細かいローカル履歴を自動的に保持することで、この作業が簡単になります。

リビジョン

私はこのページを2004-06-01に最初に投稿しました。元の形式では、もっとカジュアルな体験レポートでした。2023-12-04に、用語の定義のようにするために書き直しました。差分デバッグは業界であまり普及した用語ではありませんが、一般的にそれを説明するために使用される別の用語は見たことがありません。


コーディングアシスタントの信頼性の低さにどのように取り組むか

2023年11月28日 火曜日 10:21 EST

昨年、多くの開発者がLLMコーディングアシスタントを業務に取り入れ、便利なツールとして活用しています。しかし、これらのツールの問題点の1つは、信頼性が低く、質の低いまたはまったく的外れな提案をすることが多いことです。Birgitta Böckelerは、この信頼性の低さについてどのように考えるか、そしてなぜLLMツールを「Dusty」と呼ぶのが良いのかについて、彼女が学んだことを伝えながら、開発者向けのGenAIの探求を続けています。

詳細…


分散システムのパターンはPearson社から出版されています

2023年11月24日 金曜日 14:11 EST

過去4年間、私の同僚であるUnmesh Joshiは、現代の分散システムがどのように機能するかを私たち全員がより深く理解するのに役立つパターン集を開発してきました。私たちはこれらのパターンの草稿をこのサイトに公開してきました。現在、これらは私のシグネチャーシリーズでAddison-Wesley社から出版された書籍になりました。そのため、進行中の草稿はサイトから削除し、パターンの概要カタログに置き換えました。oreilly.comのサブスクリプションをお持ちの方は、概要からオンライン書籍の関連章への深いリンクをご利用いただけます。

詳細…


リベラルアーツの学位がテクノロジー分野での成功に役立った3つの理由

2023年11月9日 木曜日 10:12 EST

私の同僚であるSannie Leeは、テクノロジー分野への参入を検討しており、専門分野に特化した専攻をしている多くの学生と会ってきました。しかし、Sannieは、伝統的なリベラルアーツの学位が、プロダクトマネージャーとしての彼女の仕事に非常に密接に関連するスキルを与えてくれたことを発見しました。

詳細…