web-dev-qa-db-ja.com

コードのリファクタリングと最適化は、アジャイルとウォーターフォールの両方のプロセスタイムラインのどこに適合させるべきですか?

プロジェクトマネジメントチームの間では、「機能する」とは100%完成したものと見なす必要があることを意味するというこの考え方があるようです。ほとんどのプログラマは、それが常に当てはまるとは限らないことを知っています。機能の一部を機能させるために別のアプローチを試みている場合、それは必ずしも最良の解決策を見つけたことを意味するわけではありません。私はしばしば何かをやり遂げ、一歩下がって、ビジネスルールが満たされた後、自分に何ができるかを自問します。この「もっと上手にできる」時間は、実際にはタイムラインのどこかに収まるでしょうか。最善の方法は、コードを見つけたときよりも常に(ある程度)そのままにしておくことです。これは、リリース後のリファクタリングを意味する可能性があります。ただし、プロジェクトチームはこのアプローチに非常に不快であることがよくあります。なぜなら、これが機能し、テストされているのであれば、なぜそれを修正するのでしょうか。

10
user9483

ウォーターフォールとアジャイルの両方で、リファクタリングと最適化の必要性を管理する1つの包括的な原則があります。YAGNI(You Ai n't Gonna Need It)です。第2の原則は、第1の帰結です。「早期最適化はすべての悪の根源であり」、コーディングは、一般的なことわざ「卓越性の敵は完全である」に相当します。

原則を取って適用しましょう。特定のタイプのファイルを取得してその情報を抽出し、その情報をデータベースに入れるETLアルゴリズムを構築する必要があります。今週の目標(私たちの目的では、アジャイルショップにいるかSDLCショップにいるかは関係ありません)は、それを達成することです。

あなたは賢い仲間であり、全体像を垣間見ることができます。これは、プロジェクトがETLを必要とする唯一のタイプのファイルではないことを知っています。したがって、このETLアルゴリズムを実装して、わずかな違いしかない別のタイプのファイルでも機能することを検討してください。これを行うと、YAGNIに違反します。あなたの仕事は、他のファイルのアルゴリズムを開発することではありません。週末までに必要な1つのファイルのアルゴリズムを開発することです。その目標を達成し、受け入れテストに合格するには、そのアルゴリズムを開発して正しく動作させる必要があります。他のファイルで機能させるための追加のコードは「必要ありません」。今組み込むことで時間を節約できると思うかもしれませんし、あなたは正しいかもしれませんが、ひどく間違っているかもしれません。他のファイルのアルゴリズムは、コードを使用できないシステムの領域で使用する必要がある場合があります。または、新しいファイルの要件が、自分の方法とは異なる方法(Agileでは、要件がまだ存在しない場合があります)。その間、時間を浪費し、アルゴリズムの複雑さを不必要に増やしました。

さて、来週です。最初のアルゴリズムの優れた取り組みに対する疑わしい報酬として、2つの新しいファイルタイプのアルゴリズムを作成するタスクが与えられました。アルゴリズムをより多くのファイルで動作させるには、追加のコードが必要です。ファイル固有の個々のステップを含む基本パターンを使用するテンプレートメソッドパターンを使用して既存のアルゴリズムを拡張するか、既存のアルゴリズムから共通のインターフェイスを派生させ、そのインターフェイスに従う2つの新しいインターフェイスを開発してそれらをプラグインすることができます。使用するアルゴリズムを選択できるオブジェクト。

開発中に、システムが毎秒10KBの生データを処理できる必要があることを知っています。負荷テストを行い、初期ドラフトアルゴリズムが8KB/sを処理することを確認します。まあ、それはAATを通過するつもりはありません。見てみると、アルゴリズムにO(私の神)の複雑さのループ構造があることがわかります。あなたはそれを合理化し、12KB /秒を取得します。 「かなり良い」とあなたは思う、「でも、もしコードにループが貧弱だったら、他に何ができますか?」 buzz「時期尚早の最適化」ルールに違反しました。コードは機能し、すべての要件を満たします。 15KB /秒を必要とするように要件が更新されるまで、「完了」します。それが発生した場合は、コードを元に戻し、改善すべき点を探します。

アジャイルであろうと従来のSDLCであろうと、開発中は次の単純なプロセスに従ってください。「最初のパスで機​​能させる。2番目のパスできれいにする。3番目のパスでしっかりさせる。」つまり、コード行を最初に作成するときは、そのコードが正しく機能し、バグが発生しないようにしますが、このコード内のデザインルールにはあま​​り注意を払わないでください。この領域には二度と触れないでください。次にそのコード行にアクセスしたとき、自分が間違っていることがわかりました。システムの一時的なものではなくなりました。読みやすさ、コードの簡潔さ、およびDRY原則のためにリファクタリングします(コードを5回コピーするためにコードをコピーアンドペーストした場合があります。ループやメソッド呼び出しにリファクタリングしてください)。 。そのコード行またはその周辺で3回目に作業するときは、システムの重要な領域と見なして、SOLID構造にリファクタリングし、見つけやすいように実行する必要があります。これに従って、リファクタリングが必要な領域がそれを受け取ることがわかりますが、同時に時間の無駄がありません。

13
KeithS

それが機能し、テストされている場合、なぜそれを修正するのですか?

これは、エンジニア/プログラマーとしてのあなた自身の個人的な気質に反するかもしれませんが、それが機能している場合、それを洗練し続けるためにどのようなビジネス価値がありますか?時間の経過とともに維持しやすくなりますか?その場合、アジャイル方法論の下で作業し、バックログに新しいアイテムを作成して既存のコードを改良およびリファクタリングでき、それらはバックログの他のアイテムと優先されます。これはアジャイルプロセスの価値の一部です。チームは何が最も重要で次に何が行われるかを一緒に決定します。

私たちのチームは、「技術的負債」と呼ばれるものも追跡します。そのため、何かが機能しても、それがもっとうまくいくとわかっている場合は、技術的負債として記録します。私たちはスクラムを使用しており、時にはすべての作業をスプリントで早期に完了します(見積もりにかなり近づいている場合は、ほぼ半分の時間で少し早く完了する必要があります)が、完全に新しいものを取り込むための十分な時間がないユーザーストーリーなので、私たちは戻って技術的な負債を減らすために余分な時間を費やしています。バックログのユーザーストーリーのように正式に追跡されるわけではないので、時間があるときはいつでも対応できます。

また、タスクを「完了」と呼ぶとき、それは多かれ少なかれあなたの判断の呼びかけです。コードの状態に満足できない場合は、タスクに完了のマークを付けないでください。

10
Joel C

この「もっと上手にできる」時間は、実際にはタイムラインのどこかに収まるでしょうか。

はい。

nextリリースのコーディングを始める直前。

「直感」に基づいてリファクタリングしないでください。

次のスプリントの実際のストーリーに基づいてリファクタリングします。

5
S.Lott

リファクタリングに満足するまで、コードを100%完了としてマークしないでください。コードをリファクタリングするためのコスト/メリットを常に評価する必要があるだけです。十分に勉強すれば、常にコードを改善する方法が見つかるからです。

TDDの赤緑リファクタリング手法を使用しています。したがって、私のリファクタリングは私の開発に組み込まれています。基礎となるモデルの変更などの大きなリファクタリングの場合は、最初に時間を費やすように経営陣に賛同してもらいます。

2
mpenrow

「リリース後のリファクタリング」には、回帰テストとQA時間に無視される隠れたコストがあり、加えて、報告されたバグや新機能/リクエストされた機能や変更に取り組んでいないという機会コストが伴います。 TANSTAAFL

実行する価値がある場合は、特別な例外としてではなく、通常のプロセスで優先順位を付けるタスクを作成する価値があります。結局のところ、あなたはチームの一員であり、共通の目標に取り組み、作業中のコードの修正に対応するためにスケジュールを任意に延長することは、それらにも影響します。

したがって、実際の答えとしては、リファクタリングが必要であることがわかっている場合は、その時間をタスクの一部としてスケジュールします。スクラム/アジャイルを行う場合は、クリーンアップタスクのタイムボックスを設定します。ウォーターフォール/スパイラルの場合は、リファクタリングをプロセスの一部にして、コードレビューを行い、モジュールを受け入れます。

2
Patrick Hughes

私が見て、読んだ限り、これは未解決の質問です。したがって、回避は「YAGNI」のような回答と、最初からの正しい応答を行います。実際のところ、リファクタリングを行うアジャイルには場所がないのですが、あるべきだと私は主張します。

これまでの最良の答えは、技術的負債に言及しています。残念ながら、これは多くの企業におけるソフトウェアの悲しい現実です。アジャイル手法でも非アジャイル手法でも、ラッシュが戸外で物事を進めることはすべて一般的ですが、アジャイルでは迅速で汚れたソリューションです。 「最低限のビジネス要件を満たしている」と「YAGNI」(コードをクリーンに保つことに関して)は、良いものとして合理化されています。

誰もがTDDを実行できればすばらしいでしょうし、すべての開発者が1つの回答で提案されているように2回または3回リファクタリングすればすばらしいでしょう。しかし、それは現実の世界では起こりません。さまざまなスキルレベルの開発者は、ほとんどの場合、迅速な解決策を追求して手を抜いています。その結果、コードは、新しい開発者が解読するだけで何日もかかる保守不可能なコードの山に崩壊し、生産性を損ない、締め切りを遅らせます。 「保守不能」とは、コピーアンドペーストソリューション、5000行クラスなどを意味します。また、このすべてのコードと、修正時のこれらの修正は、すべてビジネスの中核です! -加法的解決策のこれらのケースでは、YAGNIのようなものはないと主張します。クリーンなコードが必要になります-常に。コードがクリーンでない場合、あなたは間違いなくそれを必要としません-自己実現預言を参照してください?見るのが面倒なので、開発者はそのコードをまったく使用しないように努力します。そして、悪玉のサイクルは、泥だらけのボール全体がひっくり返されて書き直されるまで続きます。

つまり、コードリファクタリングは、適切で、明確で、価値のある独自のアジャイルコンセプトではないにもかかわらず、リファクタリングする時間を作るべきだと私は言います。現在、一部のショップでは、チームがスプリントの20%を技術的負債に費やすことを要求しています。うまくいけば、アジャイルの支持者はYAGNIについての考えを変え、別の時間割り当てアクティビティとしてリファクタリングの場所を作るでしょう。そして、彼らがすでにそれを聞いていて、聞いたことがない場合は、私が知ることに非常に興味があるので、それが記載されている場所を指摘してください。

0

機能の一部を機能させるために別のアプローチを試みている場合、それは必ずしも最善の解決策を見つけたことを意味しません。

...その場合、まだ100%完了していません...

または、他の開発者とレビューした後、多少の再作業は必要ありません。

コードのレビューとその後のリワークが開発ライフサイクルの一部である場合も、これらのすべてが完了するまで機能は実行されません。

私はしばしば何かをやり遂げ、一歩下がって、ビジネスルールが満たされた後、自分に何ができるかを自問します。この「もっと上手にできる」時間は、実際にはタイムラインのどこかに収まるでしょうか。

場合によります。リファクタリングを意味する場合は、元の開発タスクの一部である必要があります。潜在的に優れたアルゴリズムで実験することを意味する場合、それは別のタスクである可能性があります。

最善の方法は、コードを見つけたときよりも常に(ある程度)そのままにしておくことです。これは、リリース後のリファクタリングを意味する可能性があります。ただし、プロジェクトチームはこのアプローチに非常に不快であることがよくあります。なぜなら、これが機能し、テストされているのであれば、なぜそれを修正するのでしょうか。

簡単に言うと、コードは多くのレベルで壊れる可能性があるためです。

それが現在機能していることの1つです。長期的に見れば、クリーンで、拡張可能で、保守可能かどうかは、まったく異なります。

より詳細な回答については、 このスレッド を参照してください。

0
Péter Török