レビュー中に他の人の不適切に設計されたコードの改善を巧妙に提案するにはどうすればよいですか?


130

私はきれいなコードとコードの職人技を大いに信じていますが、私は現在、これが最優先事項と見なされていない仕事に就いています。機能的でバグがほとんどないのに、ピアのコードが乱雑な設計に埋もれており、将来のメンテナンスにほとんど関心がないという状況に陥ることがあります。

変更が必要なものが非常に多く、期限が近づいていると思われる場合、コードレビューの改善をどのように提案しますか?期限が過ぎた後に改善を提案することは、新機能やバグ修正が追加されると、優先度が完全に解除されることを意味することに注意してください。


25
まず、あなたの意見が主観的でないことを確認してください。多くの場合、開発者は他のスタイルや方言が好きなので、他の人のコードを書き留めます。そうでない場合は、一度に1つずつ改善してください。
コーダー

多くのソフトウェア開発はトレードオフに関係しており、主に設計ベースのコードクラフツマンシップについて話しているため、多くのコードレビューコメントは主観的になります。だから「改善の提案をどうするのか」と尋ねたのです。確かに、何を指図することも私の目標ではありません。
ヨニー

5
この質問によりテストの完了後にコードレビューが行わているように聞こえます。その場合は、テスト時間を浪費している(変更を再テストする必要がある)か、コードレビューの結果として変更を取得するのがはるかに困難になっています(既に動作しているコードを変更する理由)。
vaughandroid

3
@Baqueta-コードがまだ機能しているかどうかわからないのに、なぜコードをレビューして複数の人の時間を無駄にするのですか?
ダンク

4
@Baqueta明らかに異なる種類のテストがあります。有用である場合、コードレビューはユニットテストなどの初期テストの後で(動作することを知っている)、ユーザー受け入れテストのような最終テストの前に(変更によって大量のテープが発生しないように)行う必要があります。
カレブ

回答:


160
  1. モチベーションを再確認してください。あなたは、コードを変更する必要があると思われる場合は、何らかの理由で明確ことができるはず、なぜあなたはそれが変更されるべきだと思うが。そして、その理由は「私はそれを違うやり方でしただろう」または「 "い」よりも具体的であるはずです。提案された変更から得られるメリットを指摘できない場合、変更に時間(お金)を費やすことはあまり意味がありません。

  2. プロジェクト内のすべてのコード行は、維持する必要がある行です。コードは、仕事を成し遂げ、簡単に理解するために必要である限り、それ以上ではないはずです。明快さを犠牲にすることなくコードを短くできるなら、それは良いことです。明快さを高めながらそれを行うことができれば、それははるかに優れています。

  3. コードは具体的なものです。しばらく座った後に変更するのはより困難です。変更のコストとリスクの両方が最小限に抑えられるように、可能な場合は早期に変更を提案してください。

  4. すべての変更にはお金がかかります。動作し、変更が必要になる可能性が低いコードを書き換えると、無駄な労力を費やす可能性があります。変更される可能性の高いセクションまたはプロジェクトにとって最も重要なセクションに注意を集中してください。

  5. フォームは機能に従い、時にはその逆もあります。コードが乱雑な場合、バグも含まれている可能性が高くなります。それらのバグを探して、コードの見た目の魅力よりも欠陥のある機能を批判してください。より良いコードを動作させるための改善を提案し、検証するコードの操作が容易になります。

  6. 設計と実装を区別します。くだらないインターフェースを持つ重要なクラスは、がんのようなプロジェクト全体に広がる可能性があります。これは、プロジェクトの残りの部分の品質を低下させるだけでなく、損傷を修復する難しさも増します。一方、適切に設計されたインターフェイスを備えたクラスで、実装が粗末なものは大した問題ではありません。パフォーマンスや信頼性を向上させるために、いつでもクラスを再実装できます。または、正常に動作し、十分に高速である場合は、そのままにしておいて、そのクラフトが十分にカプセル化されているという知識で安心できます。

上記のすべてのポイントを要約するには:提案された変更が価値を高めることを確認してください。


3
実際、あなたの懸念を「売る」ことになります。前述のように、利点と付加価値を指摘します。私の経験でも、それは大変な仕事です。
Wivani

4
あなた自身の動機を理解することは、単に売ることではありません。一部のテクニックが好きで他のテクニックが好きではない理由を理解する必要があります。そのため、経験則がいつ有効で、いつ有効でないかを知ることができます。経験豊富なプログラマーが間違った状況で正しいテクニックを適用することで、多くの多くの問題が生じます。
ヨルゲンフォグ

1
あなたのポイントは、ゴルフは大丈夫のように思われます... :
フロリアン

2
答え全体に対して+1。ただし、特に「コードが乱雑な場合、バグも含まれている可能性が高くなります」
コナミマン

2
ポイントへの当然の帰結は、(6)、興味深いことにそのインターフェイスの品質が実装品質よりも重要であるように思わ
ブラッド・トーマス

16

リファクタリングを通じて価値を追加するためのスイートスポットがあります。変更では、次の3つのことを実行する必要があります。

  • 変更される可能性があるコードを改善する
  • 明快さを増す
  • 最小限の労力で

考慮事項:

  1. クリーンなコードは、作成と保守にかかる費用が少なく、作業が楽しくなることがわかっています。あなたの仕事は、そのアイデアを社内の人々に売ることです。sales慢な詐欺師のようではなく、セールスマンのように考えてください(つまり、私とは違う)。
  2. 勝つことはできず、失うことは少なくなります。
  3. 美しさだけでなく、真の価値を付加することに焦点を当てます。私は自分のコードが見栄えがするのが好きですが、時にはその安価な問題をもっと受け入れなければなりません。
  4. スイートスポットを見つける良い方法は、ボーイスカウトの原則に従うことです。コードの領域で作業するときは、常に、見つけたよりも良い形のままにしておきます。
  5. 小さな改善は改善なしよりも優れています。
  6. 自動化ツールを十分に活用してください。たとえば、わずかな書式設定をクリーンアップするだけのツールは、世界を変えることができます。
  7. 偶然にコードの明快さを改善する他のアイデアを売り込む。たとえば、単体テストでは、大きなメソッドを小さなメソッドに分解することが推奨されます。

5
自動化ツールを使用する場合は+1。驚いたことに、多くのショップは開発者ツールキットがどのように見えるかを十分に気にしていないようです。ソース管理、エディター、コンパイラーを持っているからといって、ツールキットが完成するわけではありません。
スペンサーラスブン

4
@スペンサー:私はこれ以上同意できませんでした。同時に、持っているツールを使用していない開発者に不満を感じています。機能や利点、または単純な怠inessを知らないためです。最近のほとんどのIDEには、わずか数回のキーストロークでコードをフォーマットする機能が組み込まれていますが、一部の開発者はそれを使用しません。
Kramii

2
本当です。しかし、私はそれ自体を気にしない店自体の下に含めます。開発者は、現在のツールセット内の一部の機能について、特に管理者が標準を作成することに煩わされることがない場合、特に知らない場合があります。第二に、多くのIDEは非常に大きく、巨大な機能セットを備えています。私はここ数年、vimを使用していますが、vimでできることのすべてがまだわかりません。あなたが私をVisual Studioに落とし込んだ場合、私はそれを掘り下げる時間ができるまで、機能の90%をそのままにしておきます。それから私はそれを覚えていないかもしれません。
スペンサーラスブン

14

コードが重大なバグなしで機能し、主要な期限(影響P&Lまたは企業PR)が差し迫っている場合、大幅な変更を必要とする改善を提案するには遅すぎます。コードの改善でさえ、プロジェクトの展開にリスクをもたらす可能性があります。コードベースの将来の堅牢性に投資する時間が増えたとき、改善の時期はプロジェクトの早い時期でした。


そこにたどり着いた場合、その時点に至ったプロセスはおそらく失敗したでしょう。
ティムアベル

9

コードレビューには3つの目的があります。

  1. バグを確認する

  2. コードを改善できる場所を確認する

  3. コードを書いた人のための教育ツール。

設計/コード品質の評価は、もちろん#2と#3についてです。

#2まで:

  • 提案された変更と修正コストのメリットを非常に明確にします。ビジネス上の決定として、これはコスト/利益分析に関するものでなければなりません。

    たとえば、「設計に対するXのアプローチは、変更Zを行うときにバグYが発生する可能性を大幅に削減します。このコードは2週間ごとにタイプZの変更を受けることを知っています。 +修正の修正とリリース+次の一連の機能を提供しないことによる機会費用は$A、コードを今すぐクリーンアップする費用と機会費用(たとえば、出荷が遅れる、または機能が少ない価格)は$B。あなたのチームのリーダー/マネージャーが持っている-評価$A$Bと決めます。

    • これは、スマートチームがこれを効果的に管理するのに役立ちます。例えば、彼らは完全な情報を使用して合理的な決定を下します

    • これは(特にこれをうまく言い表せば)あなたの地位を高めます-例えば、あなたはより良いデザインの利点を見るのに十分な知性を持ち、ビジネス上の考慮事項を考慮せずにそれを宗教的に要求しないほど賢い人です。

    • そして、バグZが発生する可能性が高いイベントでは、次の一連の提案でそれだけのレバレッジを得ることができます。

#3まで:

  • 「これはベストプラクティスであり、リソースを節約できる場合は修正する必要があります-添付の賛否分析を参照してください」デザインの改善(上記の#2で説明したものを添付)と「これらは、コードの堅牢性を向上させるのに役立つと思われる一般的なガイドラインであり、コードをより簡単に維持できるようになります」オプションの変更。文言に注意してください-それは「あなたのコードを私が望むものにする」ことではありません-それは「あなたがこれを行うと、あなたは利益a、b、cを得る」です。トーンとアプローチが重要です。

2
#3では、コードレビューはコードの作者に教えるためだけのものではありません。レビューは、経験の浅い開発者が学習するのに良い方法であり、チームに初めて参加する経験豊富なプログラマーがコーディング標準を理解するのに良い方法です。グループとして問題を議論することも、製品に関する洞察につながる可能性があります。
カレブ

1
@カレブ-良い点。私はあまり多くのポイントを作りたくなかったので、これはアウトラインから編集されましたが、それはまだ有効なポイントです。
DVK

#4新機能に関する開発者のクロストレーニング
フアンメンデス

1
#5-コードレビューの主な目的は、設計ドキュメントが(正しく)実装されていることを確認することです
-Mawg

8

締め切りが迫っている場合は、何もしないで戦いを選びましょう。次回他の誰かがコードをレビューまたは保守していて、問題を抱えている場合は、チームとして、コードをレビューする際にコード品質をより重視して、後でそれほど問題にならないようにする必要があると考えます。

追加の作業を行う前に、値を確認する必要があります。


5
期限は常に地平線上にありませんか?
FreeAsInBeer

8

私は常に「私は」とコメントを開始します。これは、私の意見が単なる多くの意見の1つであることを示しています。

また、常に理由を含めます。

私は考えメソッドにこのブロックを抽出するため、読みやすさの。」

すべてについてコメントします。大小。時々、変更について100以上のコメントをすることがあります。その場合、ペアプログラミングもお勧めします。

理由により共通言語を確立しようとしています。可読性、DRY、SRPなど

また、クリーンコードとリファクタリングに関するプレゼンテーションを作成し、その理由を説明し、同僚に公開しました。これまでに3回開催しましたが、私たちが使用しているコンサルタント会社から、彼らのために再度開催するように依頼されました。

しかし、とにかく聞かない人もいます。それから私はランクを引っ張って残っています。私がデザインリーダーです。コードの品質は私の責任です。この変更は、現在の状態では時計に反映されません。

私が行ったコメントは喜んで引き下げます。技術的な理由、締め切り、プロトタイプなどのために。コーディングについても学ぶべきことがまだたくさんあり、常に理由に耳を傾けます。

ああ、私は最近、私は持っていなかった上の非自明な変化を提出し、私のチームの最初の1に昼食を購入することを申し出た任意のコメントを。(ねえ、あなたも楽しんでいる必要があります。:-)


5

機能的でバグがほとんどないのに、ピアのコードが乱雑な設計に埋もれており、将来のメンテナンスにほとんど関心がないという状況に陥ることがあります。

このコードは完了です。ある時点で、再設計にはコストがかかりすぎて正当化できません。バグがほとんどないかまったくないコードがすでに機能している場合、これは不可能な販売となります。将来これをクリーンアップして先に進むためのいくつかの方法を提案してください。コードが将来壊れる場合/その場合、再設計の価値を再評価してください。それは決して壊れないかもしれません、それは素晴らしいことです。いずれにせよ、あなたはそれが壊れないことをギャンブルするのが理にかなっている時点にいます。なぜなら、コストは今でも後ででも同じになるからです:引き出されたひどい再設計。

将来する必要があるのは、開発の反復をより厳密にすることです。バグを解決するすべての作業に投資する前にこのコードをレビューできた場合、再設計を提案するのは理にかなっているでしょう。最後に向かって、コードが根本的に維持不可能な方法で記述されており、リリース後すぐにコードを変更する必要があることを確信していない限り、メジャーリファクタリングを行うことは意味がありません。

2つのオプション(リファクタリングまたはリファクタリングなし)から選択できることを考えて、どちらがよりスマートな販売のように聞こえるかを考えてください。

ボス、私たちはスケジュール通りに機能していたが、今は機能Xを追加できるように多くのものを再構築するつもりだ。

または

ちょっとボス、リリースする準備ができました。機能Xを追加する必要がある場合は、さらに数日かかることがあります。

どちらかを言った場合、上司は次のように言うでしょう。

フィーチャーXについてだれが言いましたか?

一番下の行は、特定の欠陥を安価に修正できなかった場合(初期のイテレーション)には、技術的な負債が少し意味があることです。品質の高いコード設計を行うと、完成した機能と期限に近づくにつれて収益が減少します。



方法は次のとおりです。「ボス、機能Xが欲しいことはわかっています。まあ、作業を始めるには数日必要です。」彼もそれを望んでいます。YAGNIは乱雑なコードを作成したり、コードを乱雑にしたりする言い訳ではありません。わずかな技術的負債は大きな問題ではありませんが、負債は返済しなければなりません。返済が早ければ早いほど安くなります。
トールサル

5

[この回答は、コードレビューに関する他の非常に多くの質問へのリダイレクトであるため、元々提起された質問よりも少し広範です。]

ここに私が役に立つと思ういくつかの原則があります:

個人的に批判し、公に称賛する。 コードのバグを1対1で誰かに知らせてください。彼らが何か素晴らしいことをしたり、誰も望まない仕事を引き受けたりした場合は、グループ会議やチームに送られたメールで賞賛してください。

あなた自身の間違いを共有してください。 悲惨な最初のコードレビュー(受け取った)の話を、学生や後輩と共有しています。また、自分の前にバグを見つけたので、バグをすばやく見つけたことを生徒に知らせました。コードレビューでは、これは次のようになります。「ここでインデックス変数を間違えたと思います。インデックスを間違えてデータセンターをダウンさせたため、常に確認しています。」[はい、これは実話です。]

積極的なコメントを忘れずに。 短い「いいね!」または「ニートトリック!」ジュニアまたは安全でないプログラマーの日を作ることができます。

他の人は知的ですが、時には不注意だと仮定します。 「実際に返さない場合に、どのように呼び出し側が戻り値を取得することを期待しますか?!」説明:「あなたがreturnステートメントを忘れたように見えます。」早い段階でひどいコードを書いたことを思い出してください。誰かがかつて言ったように、「1年前からコードを恥じていないなら、あなたは学んでいない」。

職場にいない友人のために皮肉//笑を保存します。 コードがひどくひどい場合は、別の場所で冗談を言ってください。(私は仲間のプログラマーと結婚するのが便利だと思います。)例えば、私は同僚と以下の漫画(またはこの漫画)を共有しません。

ここに画像の説明を入力してください WTF /分


4

スプーン一杯の砂糖が薬を落とすのを助け、間違っていることを簡潔に表現することができます-間違っていることは20ありません-私は利害関係がないこと、私が欲しいものに投資していないことを示唆する形で導きます聞こえる。通常、次のようなものです。

私はそれがより良いだろうか...

または

意味がありますか...

理由がかなり明白な場合、私はそれらを述べません。これにより、次のように、提案の知的所有権を他の人々が引き継ぐことができます。

「はい、それは良い考えです。なぜならあなたの明白な理由はここにあるからです。」

改善がかなり明白であるが、私がそれを考えないために馬鹿に見えるほどではなく、それを行う理由がリスナーと共有されている値を反映している場合、代わりに私はそれを提案することさえありません、代わりに:

方法はあるのだろうか?<ここに値の共有ステートメント>

これは本当に気難しい人に対処するためだけのものです-私の仲間のほとんどと一緒に、私は彼らにそれを持たせます!


1
「…にした方がいいかな」と言うのはめったにありません。確信が持てなかった場合にのみ、私は言います。その場合、著者はそれが良いかどうか、そして変更するかどうかは自由です。私は通常「Xをやる」と言います。(時々、「Xをやればいいのに、あなたのアプローチのほうがいい」と言います)。つまり、Xの方が優れていると思いますが、反対することもできます。または、「これは機能しません」または「これは危険です」と言い、変更する方が良いでしょう。「これは機能しません」と言われることもありますが、通常はコードを見て「ああ、クソ」と言ってから修正します。
gnasher729

3

コードレビューは、常に改善を目的とするものではありません。

ここにあるように思われるプロジェクトの終わり近くのレビューは、バグが入ったときに誰がどこから調べ始めるべきかを知るためのものです(または、より良い設計のプロジェクトのために、後で再利用できるもの)。レビューの結果がどうであれ、何も変更する時間はありません。

実際に変更を加えるには、プロジェクトのかなり早い段階でコードと設計について話し合う必要があります-コードは、可能なアプローチについての話としてのみ存在する場合、変更がはるかに簡単です。


3

あなたの質問は、「不適切に設計されたコードをコードレビューする方法」です。

IMOの答えは簡単です。コードの設計と、設計に欠陥があるか、要件を満たしていないかについて話します。欠陥のある設計を指摘したり、「要件を満たしていない」場合、開発者は必要なことを実行しないため、コードの変更を余儀なくされます。

コードが「機能的に十分」および/または「仕様を満たしている」および/または「要件を満たしている」場合:

もしあなたがこの開発者の仲間なら、あなたは「彼に教えて」変化を起こさせるような直接的な力を持っていません。

いくつかのオプションが残っています。

  1. あなたはあなた自身の個人的な「影響力」(間接的な「力」の形)および/または「説得力のある」能力を使用しなければなりません
  2. 組織の「コードプロセス」グループに参加し、「コードメンテナンス」の優先度を高めます。
  3. 弾丸を噛んで、くだらないコードでハングアップしないようにするために、くだらないコードをより速く/より流lyに読む方法を学んでください。
    • また、これはあなたをより強力なプログラマーにします。
    • そして、それはあなたが安っぽいコードで作業しているときに安っぽいコードを修正できるようにします。
    • また、多くのプロジェクトには機能的な安っぽいコードがありますが、多くの安っぽいコードがあるため、これによりより多くのプロジェクトに取り組むことができます。
  4. 例でリード。コードを改善する...しかし完璧主義者になろうとしないでください。
    • あなたは「納期に間に合わず、常に批判的で、他の誰よりも優れていると思う遅い男」になるからです。

特効薬はありません。3つすべてを使用する必要があり、3つすべてを使用するには創造的でなければなりません。


私は....私は、私もそれを理解しようと苦労を持っている貧しい人々のコード...常にそれに取り組んでとてもイライラ、私は#3を学ぶことがしたい
フアン・メンデス

デザインに欠陥がありますか?どんなデザイン?
gnasher729

1

ひどく悪いデザインのイベントでは、カプセル化を最大化することに焦点を合わせる必要があります。これにより、個々のクラス/ファイル/サブルーチンをより適切に設計されたクラスに簡単に置き換えることができます。

コンポーネントのパブリックインターフェイスが適切に設計されていること、および内部の動作が慎重に隠されていることを確認することに焦点を当てます。また、データストレージラッパーも不可欠です。(大量の保存データを変更するのは非常に難しいため、システムの他の領域に「実装ブリード」が発生すると、問題が発生します)。

コンポーネント間の障壁を克服したら、主要な問題を引き起こす可能性が最も高いコンポーネントに注目します。

期限まで、またはシステムが「完全」になるまで繰り返します。


1

誰かのコードに対する直接の直接的な批判の代わりに、コードレビュー中に私たちのコメントで構成的であることが常に良いです。

私が従う一つの方法は

  1. この方法で行うと最適です。
  2. この方法で作成すると、実行速度が速くなります。
  3. 「this」、「this」、「this」を実行すると、コードがさらに読みやすくなります。

期限が迫っていても、そのようなコメントは真剣に受け止められます。そして、おそらく次の開発サイクルで実装されるでしょう。


0

コードレビューは、文化と開発サイクルと統合して機能する必要があります。機能Xの開発の終わりに大きなコードレビューをスケジュールすることはうまくいきそうにありません。まず第一に、変更を行うのが難しくなり、誰かが恥ずかしさを感じる可能性が高くなります-活動に対する抵抗が生まれます。

コミットレベルでのレビューと相まって、早期かつ頻繁なコミットが必要です。コード分​​析ツールを導入すると、ほとんどのレビューが迅速になります。FindBugsPMDなどの自動化されたコード分析/レビューツールは、大きなクラスの設計エラーを外部から取得するのに役立ちます。ただし、これらはアーキテクチャレベルの問題を解決するのには役立ちません。そのため、適切な設計を行い、その設計に対してシステム全体を判断する必要があります。


0

コードレビューの品質を向上させます。

レビュー中のコードの品質とは別に、コードレビュー自体の品質などもあります。

  • 提案された変更は、実際に改善されているのですか?
  • または単に意見の問題ですか?
  • 非常に明白なものでない限り、レビュアーは適切に説明しています
  • どれくらい時間がかかりましたか?(私は何ヶ月も続くレビューを見てきました。開発者がレビューを担当しており、多くのマージの競合をすべて解決しています)。
  • トーン?

疑わしいエゴのグルーミングよりも、高品質のコードレビューを受け入れる方がはるかに簡単です。


0

質問には2つの注目すべき問題があります。それは、巧妙な部分と締め切りの部分です。これらは明確な問題です。最初の問題はコミュニケーションとチームダイナミクスの問題であり、2番目の問題は計画と優先順位付けの問題です。

巧みに。私はあなたがブラシをかけられた自我とレビューに対する否定的なプッシュバックを避けたいと思います。いくつかの提案:

  • コーディング標準と設計原則について理解を共有します。
  • 開発者を批判したりレビューしたりするのではなく、コードのみを確認してください。「あなた」や「あなたのコード」という言葉は避け、開発者から切り離されたレビュー対象のコードについて話してください。
  • 完成したコードの品質に誇りを持ち、最終結果の改善に役立つレビューコメントを高く評価します。
  • 要求ではなく改善を提案します。同意しない場合は、常に対話をしてください。同意しない場合は、他の視点を理解するようにしてください。
  • レビューを双方向に行ってください。つまり、レビューした人に次にコードをレビューしてもらいます。「一方向」のレビューはありません。

2番目の部分は優先順位付けです。改善のための多くの提案がありますが、期限が近づいているため、いくつかを適用する時間しかありません。

まあ、まず最初にこれが起こるのを避けたいです!これを行うには、継続的な増分レビューを実行します。開発者に機能を数週間働かせて、最後にすべてをレビューさせないでください。第二に、コードのレビューとレビューの提案を実装する時間は、あらゆるタスクの定期的な計画と見積もりの​​一部である必要があります。適切にレビューするのに十分な時間がなかった場合、計画の中で何かがおかしくなりました。

しかし、プロセスで何かが間違っていると仮定すると、多くのレビューコメントに直面することになり、それらすべてを実装する時間がありません。優先順位を付ける必要があります。その後、延期した場合に後で変更するのが最も難しく、最もリスクの高い変更に進みます。

ソースコード内の識別子の命名は、可読性と保守性のために非常に重要である、しかしまた、将来的に変更することが非常に簡単かつ低リスクです。コードの書式設定と同じです。だから、そのようなことに集中しないでください。一方、公開されているインターフェイスの健全性は、将来変更するのが非常に難しいため、最優先事項です。永続データを変更するのは困難です。データベースに一貫性のないデータや不完全なデータを最初に保存し始めた場合、将来修正するのは本当に困難です。

単体テストでカバーされる領域は低リスクです。これらは後でいつでも修正できます。ありませんが、エリアができ、ユニットテストは、領域よりもリスクが低いですすることができないユニット・テストすること。

単体テストがなく、外部サービスへのハードコーディングされた依存関係を含む、あらゆる種類のコード品質の問題がある大きなコードの塊があるとします。代わりにこの依存関係を注入することにより、コードチャンクをテスト可能にします。これは、あなたが将来的にテストを追加し、できることを意味し、その後問題の残りの部分の修正に取り組んでいます。ハードコーディングされた依存関係では、テストを追加することさえできません。最初にこの修正に進みます。

しかし、そもそもこのシナリオで終わらないようにしてください!

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