苦しみによる発達

翻訳者から:

多くのコピーは、KISSがより適切であるとき、DRYであるとき、できるだけ早く問題をできるだけ早く解決する方がよいとき、美しく普遍的な抽象化を作成する価値があるときについての紛争で壊れています。 Twitterで使用されている人気の高いStormフレームワークの著者であるNathan Martzは、彼自身のバージョンを提供しています。 抽象的普遍性のために無数の無駄なコードを作成しないと同時に、システムが松葉杖の混乱にならないようにするために、彼は「苦しみによる開発」(苦しめられたプログラミング)を使用します。






彼らが私に尋ねたとき、「どうやってそのような恐ろしいリスクを取ることに決めたのか- スタートアップを始めると同時にStormを書くのか?」( Stormはリアルタイムでの分散コンピューティングのためのフレームワークです)。 はい、おそらく、側から見れば、スタートアップ向けのこのような大規模なプロジェクトの作成は非常にリスクが高いようです。 しかし、私の観点からすると、これは危険なビジネスではありませんでした。 難しいが、危険ではない。



Stormなどの大規模プロジェクトのリスクを大幅に軽減する開発スタイルを使用しています。 このスタイルを「苦しみによる発達」と呼びます。 簡単に言えば、苦しみを経験していないテクノロジーの実装に従事しないでください。 このアドバイスは、大規模なアーキテクチャソリューションと小さな日常タスクの両方に適用されます。 苦しみを乗り越えて開発することでリスクが大幅に軽減され、常に重要なことに取り組むことができ、ソリューションに多くの努力をする前に対象分野に精通していることが保証されます。



この開発マントラを思いつきました。「まず、それを実現します。 その後-美しいこと。 それから-迅速に。」



する



新しい主題領域に直面して、「一般的な」または「拡張可能な」ソリューションを作成しようとすることは最初から不可能です。 あなたは単にあなたが将来必要とするものを予測するほど十分に問題を理解していない。 必要のない場所を一般化し、複雑さを追加し、時間を無駄にします。



おそらく松葉杖や汚いハックで、すべての問題を「正面から」解決する方がはるかに優れています。 これにより、無駄な時間を無駄にすることなく、迅速に結果を得ることができます。 そして、その過程で、対象分野の複雑さについてますます学びます。



StormのDIYフェーズは約1年続きました。 試行錯誤により、キューとプロセスでメッセージフローを処理するシステムを作成しました。 保証されたデータ処理のために確認メカニズムを使用する方法を学びました。 キューとプロセスのクラスターでリアルタイムコンピューティングをスケーリングする方法を学びました。 同じエンティティが同じプロセスで処理されるように、場合によっては偶然やハッシュによって、メッセージフローをさまざまな方法で分割する方がよいことを学びました。



「自分でやる」フェーズの最中にいることすら知りませんでした。 製品を書きました。 しかし、ラインとプロセスが私たちに与えた痛みはすぐに深刻になりました。 スケーリングはひどい手間であり、信頼性は適切なレベルからはほど遠いものでした。 キューとプロセスのパラダイムが間違っていて、間違ったレベルの抽象化を使用していることが明らかになりました。 コードのほとんどは、ビジネスロジックではなく、メッセージのルーティングとシリアル化に焦点を当てています。



同時に、開発プロセス中に、サブジェクト領域で新しいタスクを発見しました。 Twitter上のURLのリーチ、つまり、このURLを見たユニークユーザーの数を計算する関数が必要でした。 これは、数百のデータベースアクセスと数百万の操作を必要とする複雑なタスクです。 同じマシン上で実行される最初の実装では、1つのURLを処理するのに1分以上かかる場合があります。 迅速に動作するためには、分散環境でコンピューティングを並列化する必要があることが明らかになりました。



Stormの背後にある重要なアイデアの1つは、「カバレッジ問題」

また、「メッセージフロー処理」の問題を1つの単純な抽象化にまとめることができます。



美しくする



サブジェクトエリアの「戦闘での偵察」では、マップを作成できます。 時間が経つにつれて、ニュアンスと実際のユースケースについての理解が深まります。 この理解は、既存の「クランチ」の代わりに美しいソリューションの作成につながり、苦しみを癒し、これまで到達できなかった新しい機能やシステムを作成できるようになります。



美しいシステムを見つけるための鍵は、扱っている特定の問題をすべて解決するのに十分な最も単純な抽象化セットを決定することです。 あなた自身が遭遇したことのない仮想的なケースを予測しようとすると、過剰なエンジニアリングにつながるエラーです。 一般に、システムが大きいほど、対象領域を深く理解する必要があり、ユースケースのセットはより汎用性が高くなります。 そうしないと、2番目のシステムの影響にさらされる可能性があります。



「Make it Beautiful」フェーズでは、単純な抽象概念を調和して組み合わせたセットを強調するために、抽象化と設計のスキルを自由に制御できます。 これは、グラフ上の一連の点(ユースケース)を最も単純な数学関数(一連の抽象化)で近似することに似ています。







グラフ上のポイントが多いほど、最適な曲線が見つかる可能性が高くなります。 ポイントが少なすぎる場合、リスクは、曲線が実際のデータをあまりにも不十分に記述するか、その式が複雑すぎることです。 そして、これは時間と労力の不必要な損失です。



美しいソリューションの非常に重要な条件は、パフォーマンスとリソースの要件を覚えることです。 これに必要な知識は、最初のフェーズで正確に現れます。



Stormの作業中に、ストリーム、スパウト、ボルト、およびトポロジという主要な抽象化の小さなセットを強調しました。 私は、中間メッセージブローカー(システムの中で最も苦しんでいる部分)を節約する新しい保証付きデータ処理アルゴリズムを開発することができました。 カバレッジの問題やメッセージフローの処理など、一見非常に異なる2つの問題が1つの方法で非常にエレガントな方法で解決されたという事実は、目を見張るものがありました。



設計をテストするために、さらにいくつかのユースケースを探しました。 馴染みのあるプログラマーに尋ねて、新しいリアルタイムシステムに取り組んでおり、実際の使用例に興味があるとツイートしました。 たくさんの興味深い議論があり、多くの貴重な情報を得て、私のアイデアが機能することを確認しました。



早くする



美しいソリューションを作成できたら、プロファイリングと最適化を進めることができます。



「高速化」フェーズでは、アーキテクチャのパフォーマンスに関する深い問題に対処しません。 最初のフェーズでそれらについて学習し、2番目のフェーズで対処する必要がありました。 今、私たちはマイクロ最適化とコードを「なめる」ことについて話している。 最初の2つのフェーズでは、アルゴリズムの漸近的な複雑さを減らす必要があり、3番目のフェーズでは、速度に影響する定数を減らす必要があります。



すすぎと繰り返し



苦しみによる開発は継続的なプロセスです。 美しく効果的なシステムは、新しい可能性を開き、新しいタスクをもたらします。つまり、チャートの新しいポイントに対応するために、受信した情報に基づいてデザインを変更する必要があります。



ストームはそのような繰り返しを何度も繰り返しました。 使用を開始したとき、1つのコンポーネントから複数の独立したスレッドを生成する必要がありました。 特殊なタイプのストリーム「ダイレクトストリーム」を追加すると、Stormはレコードパケット全体を処理できることが判明しました。 最近、私は実質的に任意の計算で厳密に一度だけメッセージを処理することを保証する「トランザクショントポロジ」を開発しました。



サブジェクト領域での試行錯誤の方法は、非常によく理解されていませんが、定義上、コードが混乱します。 したがって、苦しみによる開発の最も重要な特徴は、リファクタリングに常に焦点を当てることです。 これは、 偶発的な複雑さがコードあふれさせるのを防ぐために不可欠です。



おわりに



苦しみによる開発では、ユースケースがすべてです。 彼らは金でその重量の価値があります。 そして、それらを取得する唯一の方法は、コードの作成を開始することであり、最初はどんなに美しくてもです。



すべてのプログラマは、開発のいくつかの段階を経ます。 まず、プログラムを何らかの形で機能させます。 コードには構造がなく、コピーアンドペーストでいっぱいです。 時間が経つにつれて、より構造化されたアプローチ、カプセル化のマスター、ますます抽象化および一般化された構造の利点を理解します。 そして、私たちは可能な限り最も一般的で拡張可能なコードを書き、将来のために安全であるという欲求に夢中になります。



苦しみによる開発方法論は、あなたがまだ遭遇していない問題を予測する試みを拒否します。 彼女は、主題分野を深く理解せずに一般化すると、過度の複雑さと労力の損失につながることを認めています。 アーキテクチャは常に、発明されたものではなく、実際の要件に従う必要があります。






All Articles