コードが「間違っている」必要がある場合、レビュアーとして何をすべきですか?


18

私は、数ヶ月前に必須のコードレビューが導入された、設計が不十分でオーバーエンジニアリングされたプロジェクトで働いています。

新しい機能を実装するコードのかなりの部分をレビューするように頼まれました。コードベースの他の部分と同じ欠陥があります。私は、これらの欠陥が新しいコードに忍び込むことを大いに理解しています。ひどく設計されたクラスから継承するか、互換性を保持しながらひどく設計されたインターフェイスを実装する必要があるため、コードベースの半分を書き直さずに、はるかに優れたソリューションを提供することはできません。しかし、エンジニアリングの観点からは、すでに壊れているコードベースに対して、それをさらに壊していることは役に立たないと思います。私がレビューしているコードは間違いなく悪いですが、機能を実装する場合はそうでなければなりません。

この特定のレビューに関して、どのように振る舞うべきですか?誠実さを維持し、建設的であり続ける方法はありますか?

この文脈でのコードレビューの境界について尋ねていることに注意してください。この問題は組織や仕事の文化などの他の要因によって引き起こされることは承知していますが、私が知りたいのはレビュー自体の処理方法です。


1
開発者は、なぜそれがこのように行われたのかを文書化し、おそらく問題トラッカーにコア問題の問題を書いたでしょうか?
リュックフランケン

わずかに、いいえ。
レッド

4
組織内に技術的負債について何かする意欲がありますか?
ロバートハーベイ

5
環境を考慮してコードが間違っていなければ、コードを攻撃しません。主にあなたが書いたので、現時点では実際の改善は見られません。それは改善する機会なしに対立を生み出します。私がやることは、最初のステップとしてより良い文書化を教えることです。次に、明確な問題を作成するための手順を作成します。その結果、次の2つの問題が発生します。問題に関するドキュメントです。次の問題を迅速に処理できるようにします。それに加えて、修正される可能性のある具体的な問題のリストを取得します。GitHubが言及しているのは、タグを付けた場合に繰り返し発生する回数がわかるからです。
リュックフランケン

回答:


25

シンプル:

1.技術的負債を文書化する

動作するが、技術的な問題があるコードを特定しました。これは技術的負債です。他の種類の借金のように、対処しないと時間とともに悪化します。

技術的負債に対処するためのこの最初のステップは、それを文書化することです。これを行うには、負債を説明するアイテムを問題トラッカーに追加します。これは、問題の規模をより明確に把握するのに役立ち、また、それに取り組む計画を立てるのにも役立ちます。

2.徐々に借金を返済する

ソフトウェア開発プロセスを変更して、技術的負債の返済を考慮に入れます。これには、不定期の強化スプリント、または定期的な間隔(たとえば、週に2項目)での負債項目の単純な解決が含まれます。発生するよりも早く負債を削り取るようにするための重要な部分(負債、さらには技術的な負債でさえもそれに関心を持っています)。

技術的欠陥がなくなった時点で、より健全なコードベースに向かっています:)


5

サイドノートとして:新しい仕事を探してください。これはこれ以上良くならないでしょう。

レビューしているコードの目標は次のとおりです。

  • 要件に従って機能する機能を出荷する。

  • 技術的負債の増加を減らすため。

最初の目標は、ユニット、統合、システムおよび機能テストがここにあること、それらが関連していること、およびテストする必要があるすべての状況をカバーすることを確認することによってレビューされます。また、元の作者がプログラミング言語について持っている可能性のある信念を確認する必要があります。信念は、微妙なバグや、実際の動作とは異なる動作をするふりをする可能性があります。

2番目の目標は、質問に焦点を当てることです。一方で、新しいコードが技術的負債を増やすことは期待されていません。一方、レビューの範囲はコード自体ですが、コードベース全体のコンテキストです。そこから、レビュアーとして、元の著者からの2つのアプローチを期待できます。

  • 外部コードは私のせいではありません。この機能を実装するだけで、コードベース全体を気にしません。

    この観点では、コードはコードベースの欠陥をコピーするため、必然的に技術的負債が増加します。つまり、悪いコードが多いほど常に悪化します。

    これは短期的には有効な短期的アプローチですが、長期的には遅延が増大し生産性が低下し、最終的に開発プロセスが非常に高価でリスクが高くなり、製品の進化が止まります。

  • 新しいコードを書くことは、レガシーコードをリファクタリングする機会です。

    この観点では、新しいコードに対するレガシーコードの欠陥の影響を制限できます。さらに、技術的な負債は削減されるか、少なくともコードの増加に比例して増加しません。

    これは有効な長期的アプローチですが、短期的なリスクがあります。主なものは、短期的には、特定の機能を出荷するのに時間がかかる場合があることです。もう1つの重要な側面は、レガシーコードがテストされていない場合、リファクタリングするとリグレッションが発生する大きなリスクが発生することです。

奨励したい観点に応じて、レビュー対象者にリファクタリングを増やすかしないかをアドバイスする傾向があります。すべての場合において、すばらしいコードベース内の素晴らしいアーキテクチャとデザインを備えた完璧できれいなコードを期待しないでください。あなた奨励すべきでないのは、くだらないコードベースで作業しなけれならない知識豊富な開発者が自分の役割をうまくやろうとする行動です。物事を単純化する代わりに、以前よりも複雑にするだけです。これで、均一な不良コードの代わりに、デザインパターンのある部分、きれいで明確なコードのある部分、時間の経過とともに大幅にリファクタリングされた別の部分があり、統一性はまったくありません。

たとえば、中規模のWebサイトのレガシーコードベースを発見しているとします。通常の構造の欠如と、ロギングが行われたときに、ロギングフレームワークを使用する代わりにテキストファイルに手作業で追加することによってロギングが行われるという事実に驚いています。MVCとロギングフレームワークを使用する新しい機能を決定します。

あなたの同僚は別の機能を実装していますが、完璧なサイズを作成できるORMがないことに非常に驚いています。そこで彼はORMの使用を開始します。

あなたもあなたの同僚も、何十万行ものコードを経てMVC、ロギングフレームワーク、ORMをどこでも使用することはできません。実際には、数か月の作業が必要になります。MVCの導入を想像してください。どのくらいかかりますか?または、SQLクエリが、誰も理解できないコード内の連結(SQLインジェクションのための場所が時々ある)によってカオス的に生成された状況でのORMについてはどうでしょうか。

あなたは素晴らしい仕事をしたと思いますが、今では、プロジェクトに参加する新しい開発者は以前よりもはるかに複雑に直面する必要があります。

  • リクエストを処理する古い方法、

  • MVCの方法、

  • 古いロギングメカニズム、

  • ロギングフレームワーク、

  • オンザフライで構築されたSQLクエリを使用したデータベースへの直接アクセス、

  • ORM。

私が働いていたあるプロジェクトでは、4つの(!)ロギングフレームワークが並んで使用されていました(さらに手動ロギング)。理由は、誰かがログを記録しようとするたびに、それを行うための一般的なアプローチがなかったため、新しいフレームワーク(すべてのケースでコードベースの5%でのみ使用されていた)を学ぶ代わりに、単純に別のものを追加することですすでに知っています。混乱を想像してください。

より良いアプローチは、コードベースを一度に1ステップずつリファクタリングすることです。再度ロギングの例を取り上げると、リファクタリングは次の小さな手順で構成されます。

  • レガシロギングが行われるすべての場所(つまり、ログファイルに直接アクセスする場合)を見つけ、それらがすべて同じメソッドを呼び出すようにします。

  • 該当する場合、このコードを専用ライブラリに移動します。ショッピングカートクラスにストレージロジックを記録したくない。

  • 必要に応じて、ロギングメソッドのインターフェースを変更します。たとえば、メッセージが非公式か、警告かエラーかを示すレベルを追加できます。

  • 新機能で新しくリファクタリングされたメソッドを使用します。

  • ロギングフレームワークに移行します。影響を受けるコードは専用ライブラリ内のコードのみです。


1
最後の段落までの素晴らしい答え。意図しているかどうかに関係なく、新しいコードにはグッドプラクティスを使用しないでください。-1
ラバーダック

2
@RubberDuck:それはグッドプラクティスではなく、残りのコードベースとは根本的に異なるコードを書くことです。私はその開発者であり、自分がやったことの結果を見てきました。悪いコードの中で劇的に良いコードを持っていると、事態は悪化するだけです。それを改善するのは、小さなリファクタリング手順を通じてコードベースを改善することです。数分後に回答に例を追加します。
Arseni Mourzenko

できれば再びDVをします。編集により悪化します。新しい方法で何かを行うための4つの異なる方法があるのは悪いことですが、2番目のロギングフレームワークを追加する人のせいです。砂に線を引き、腐ったコードの隣にきれいなコードを置くこと自体は悪くありません。
ラバーダック

@RubberDuck:2番目のロギングフレームワークを追加することではなく、最初のフレームワークを追加することです。2つ目のログフレームワークを追加する人は、最初のログフレームワークが1つの小さな機能でのみ使用されているという理由でそれを行います。私がアドバイスするようにコードベースがリファクタリングされた場合、これは起こりません。
Arseni Mourzenko

私はあなたと私は同意すると思いますが、あなたの答えは改善を妨げるような方法で読みます。私はそれで乗ることができません。
ラバーダック

3

開発プロセスの一部としてコードレビューを行っている場合; 次に、レビューするコードを「判断」するルールを設定する必要があります。

これは、「定義の完了」に入り、スタイルガイド、コードベースまたは静的分析のアーキテクチャドキュメント、法的要件のチェックなど、会社が「コード品質」の要件であると判断したものになります。

これを適切に実施すると、コードレビューが当然の問題になり、スタイルガイドに従っていますか、テストカバレッジなどの必要な割合がありますか。

これが適切に行われていない場合、コードレビューは、コーディングの意欲が最も高い人との戦いになったり、状況に応じて、期限前に行われたリファクタリングと機能についての判断を求める質問になります。これは皆の時間の無駄です。


3

あなたの主な問題は、重要な新機能のコードレビューがこの議論をするのに間違った時期であることです。その時点で、マイナーな変更以外の変更を行うには遅すぎます。適切な場所は、計画段階、または遅くとも予備設計レビューです。あなたの会社がこれらの初期レビューを少なくとも非公式に行っていない場合は、まずその文化を変えることに取り組むべきです。

次のステップは、それらの会議に招待され、それらの会議で生産的なアイデアを持つことです。ほとんどの場合、一晩ですべてを変更するのではなく、分離して取り組むことができる一口サイズのチャンクを探します。これらのチャンクは、時間の経過とともに大幅に増加します。

言い換えれば、重要なのは、プロジェクトの終わりに向かって大きな変更を提案するのではなく、プロジェクトの開始に向けて小さな変更を定期的に提案することです。


2

コードレビューを行っている場所では、(少なくとも)リファクタリングを行うというコミットメントが伴う場合は、コードの送信を受け入れてOKです。それは、提出されたバグ、物語、または(一部の)リファクタリングが完了した別のレビューを送信する約束としてです。

これらの場合、レビューするコードを書いている人であれば、通常2つの変更を準備します。1つは新しい機能またはバグ修正で、もう1つはそれとクリーンアップです。そうすれば、クリーンアップの変更によって新しい機能やバグ修正が損なわれることはありませんが、トークンとして簡単に指摘できます。「はい、これらの問題は解決しませんが、そこにあります」純粋なクリーンアップ」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.