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


10

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

回答:


13

ウォーターフォールとアジャイルの両方でリファクタリングと最適化の必要性を管理する包括的な原則が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 /秒を取得します。「かなり良い」とあなたは思う、「でも、もしコードにループが貧弱だったとしたら、他に何ができますか?」バズ「時期尚早の最適化」ルールに違反しました。コードは機能し、すべての要件を満たします。15KB /秒を必要とするように要件が更新されるまで、「完了」します。その場合は、コードを元に戻し、改善すべき点を探します。

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


3
+1にO(my God)-complexityすぎないので、笑わせました!
ジョエルC

最初に動作させるための+1。あまりにも多くの人々がパターンを書き、時期尚早にすぐに最適化しようとします。
ジャスティンシールド

これは、プログラマーとして克服するのが最も難しい問題の1つだと思います。エンジニアには、実験、開発、改良を行うという生来の欲求がありますが、結局のところ、生産性に対する見返りが得られます。時間やお金をかけすぎてオーバーランが原因でキャンセルされる場合、完璧な製品とはどのようなものですか。
ToddR

私は実用的なアプローチが好きですが、「2番目のパスできれいにする」に問題があります。2番目のパスが1年後で、変数名とメソッド名が完全で、マジック番号がシンボリック定数に置き換えられていることを確認していない場合おそらくコードを理解するのに問題があります。これに対処するには?「Make it pretty」は、「make it work」から1時間後の方が「make it pretty」より1か月または1年後のほうがはるかに安価です。「make it pretty」が最初から行われていない場合は、次のコード変更が必要なときに「make it pretty」を行うと便利です。
k3b

アジャイル/ TDDでは、2番目のパスは通常、最初のパスのすぐ後に発生することが私の経験です。滝っぽいSLDCでは、あなたはもっと正しいです。関数は一度記述される傾向があり、次のラウンドの要件がそのメソッドに影響を与えるまでそこにとどまります。したがって、自己文書化コードなど、いくつかの優れたコーディングプラクティスを最初に実行する必要があります。これにより、1年後に戻ってきたときに、コードの機能とその理由を思い出すことができます。
KeithS

10

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

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

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

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


2
私は「技術的負債」という概念のファンになりました。この文脈でそれを育てることに対して+1します。
Patrick Hughes

「技術的負債」の考え方を完全に忘れていました。良い言葉。しかし、「技術的負債」に該当するもの、つまりリファクタリングにはかなりの開発者サイクルが必要となるものはすべて避けるべきだと教えられました。「それを軽くする」というのは、まだ「正しいことをする」という意味ですが、1回限りのコードを「象牙の塔」にしないでください。
KeithS、2007

5

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

はい。

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

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

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


2

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

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


1
コードが存在するすべての製品が死ぬまで、コードは「100%完成」しません。あなたの心が永久に鼓動を停止するまで、あなたは人として「完全」ではないように。常に新しい情報を吸収し、以前に行ったことのない特定のことを行うか、同じことをより効率的または安価な方法で行う必要があります。同様に、誰もソフトウェアを使用しなくなるまで、コードベースは常に作業(新機能と古い修正)を必要とします。
KeithS、2011

2

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

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

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


0

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

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

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

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

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

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

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

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

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

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


0

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

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

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

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


「実際のところ、リファクタリングのためのアジャイルには場所がない」 -それは本当の発言ではないと思います。アジャイルには、ビジネスケースが存在する限り、リファクタリングを含むあらゆる種類の開発の場所があります。ビジネスケースがない場合、なぜそれを行うのですか?
ブライアンオークリー

少し単純化しているとしたら、ポイントがあると思います。理論的には、開発者は機能的な変更が発生しなくても、粗雑なコードを修正するためのビジネスケースを作成することができますが、ビジネスをプロキシとして使用して作業を正当化することは、アジャイルの精神に反することにはなりません。リファクタリングの活動はアジャイルの領域の外にあると主張します-CYAの活動の一種-メンテナンス不可能なコードを修正するので、ビジネスの長期的なコストがかからず、開発者が非難されます。これを「リファクタリングスプリント」などと呼びますが、正式な場所がなければなりません。
blindcodifier9734
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.