私たちのソフトウェアのコードの品質は確かに欠けています。 1つのコンポーネントのコード行を変更すると、通常、他のコンポーネントのコードが壊れます。
私たちのソフトウェアアーキテクトは、これを集団的なコード所有権のせいにしている。彼は、すべての開発者が自分のコードに責任がある場合、コンポーネントの所有権を感じるため、常に片付けていると信じています。
現在の状況では、開発者は複数のコンポーネントのコードを変更し、コンポーネントがどのように動作するかを理解していないため(非常に多くのコンポーネントで動作するため)、または変更がどのように影響するかについて気にしていないため、他のコンポーネントを壊しますコンポーネントの他のクライアント(影響を受けない限り)。
ソフトウェアアーキテクトの懸念に対処しながら、コードの共同所有権を維持するにはどうすればよいですか?
1つのコンポーネントのコード行を変更すると、通常、他のコンポーネントのコードが壊れます。 ...すべての開発者が自分のコードに責任がある場合、コンポーネントの所有権を感じるため、常に片付けます。
コンポーネントを更新すると他の誰かのコンポーネントが壊れることが問題である場合(まともなデカップリングがない疑わしいアーキテクチャのため)、コンポーネントを開発者が所有するようにすると、誰かのコンポーネントが突然魔法のように停止するのはどうしてですか最初の更新で壊れないように分離する!?!
唯一の答えは、現在のように絡み合わないようにコンポーネントを適切に整理することです。それと、それらの間のインターフェイスとデータコントラクトを文書化します。
コンポーネントの所有権には同意します。コードだけでなく品質の向上にも役立ちますが、代わりにコードレビューを使用します。結局のところ、APIを適用してその動作を修正するには、誰かが各コンポーネントについて多くのことを知っている必要があります。この場合、コードレビューは、とにかく所有権を実装する方法の1つにすぎないと思います。
コードレビュー、コードレビュー、コードレビューの3つだけです。これらは、コードの品質を向上させ、「共有コード」に対する責任感を高めるのに役立ちます。
1つのコンポーネントのコード行を変更すると、通常、他のコンポーネントのコードが壊れます。
理想的な世界のシナリオ:APIを形式化し、APIの不変条件を単体テストでテストする必要があります。これがカバーされている場合、開発者が不変条件に影響を与える変更を行うと、テストは失敗します。開発者がユニットテストに違反する変更を加える場合、開発者はユニットテストを更新するか、APIのドキュメントを更新する(そしてユニットテストを削除する)ことを検討する必要があります。
私たちのソフトウェアアーキテクトは、これを集団的なコード所有権のせいにしている。
いいえ、違います。私が理解しているように、同時に複数のコンポーネントにまたがって、すべての人がアドホックにコードを変更することの方が問題です。これはコードの所有権の問題ではありませんが、チームの方法論ではAPI契約と不変式を形式化/尊重していません。
彼は、すべての開発者が自分のコードを担当する場合、コンポーネントの所有権を感じるため、常に片付けていると考えています。
それは現実的ではありません。私がコードを書いて他の開発者がそれを壊した場合、私はその開発者によって導入されたバグを修正するために私がやっていることを落としません(私には自分のタスクと期限があるため)。
現在の状況では、開発者は複数のコンポーネントのコードを変更し、コンポーネントの動作を理解していない(コンポーネントが非常に多いため)か、変更が他のクライアントにどのように影響するかを気にしていないため、他のコンポーネントを壊しています。コンポーネントの(影響を受けない限り)。
現在のコードを機能させるために複数のコンポーネントを変更する(そしてランダムな要素を壊す)開発者は、APIの明確な/正式な定義の欠如(つまり、現時点ではコンポーネントが何をすべきかについての明確なイメージがない)と適切なドキュメントの欠如を意味しますAPI(つまり、開発者が関数を入力して、実装のドキュメントを読むのではなく、実装の動作を確認する)。
ソフトウェアアーキテクトの懸念に対処しながら、コードの所有権をまとめて維持するために何をすべきだと思いますか?
インターフェイスを形式化し、それらを文書化します。 APIのドキュメントが常に正確であることを確認します(関数でnull値によりMyExceptionがスローされることが示されている場合は、nullを使用してAPIを呼び出し、例外をキャッチする単体テストを使用することをお勧めします)。
カウボーイのコーディングと「5分の」修正をあきらめて、欠陥を修正します。何にも「迅速な修正」はありません。欠陥修正はこれらすべてをカバーするべきです:
クリーンなコードとクリーンな差分を確認してください(コメント付きのデッドコードなし、奇妙に配置されたコードなしなど)。
最も重要なのは、DO NOT ACCEPT失敗したテストを伴うパブリックコミット、または2回のコードレビューを行っていないコミット(変更がテストの失敗を引き起こした場合、修正ではなく、1つ以上の導入された欠陥です) )。 2回のコードレビューとは、
理想的には、修正された各欠陥には、欠陥に記述されている動作を正確にチェックする新しいユニットテストがシステムに追加されます。
このように実行すると、1行の「5分修正」が「30分以上」修正になります。最終的には、これは無駄な時間ではなく、デバッガーで時間を費やすのではなく、新機能の実装に費やす時間です。
これは、Doc Brownの回答に対する補足/解説です。
IMHO-ソフトウェアアーキテクト(SA)は、他人の責任を正確に特定する方法を探しています。誰もが計画を守っているかどうかはわかりません。一部の企業は、チームリーダーまたはチーム全体が計画に従う責任を負う場合があるため、設計者は計画自体について質問がある場合にのみ関与します。他の人はSA=に依存して計画が守られているかどうかを判断するかもしれません。
いくつかの計画は他のものよりも優れています。チキンのレシピが非常に貧弱で、特にそれが得意なコックに頼っている料理長を想像してみてください(基本的に、彼は独自のレシピを持っています)。ある夜、別の料理人が介入しなければならず、品質の悪さのせいになります。彼は悪いレシピ(調味料なし)を守ろうとしたためです。多くの場合、貧弱な設計を救済したり、自分で残した場合は計画を実行したりするのに十分な優れたコーダーがいない。
Doc Brownが彼の回答で示したように、コードレビューは、これが他の標準の以下に沿って行われていることを確認するための最良の方法です。自分のバグを修正しなければならない場合、人々がコードの責任を負うと考える人もいます。肝心なのは、誰かがコードが出荷可能であることを確認する必要があり、レビューがない場合は、チャンスをつかむことです。
集団的または個人的な所有権は、物事の変更が他のコンポーネントのコードを破壊するという事実を変更するつもりはありません。
触れるすべてのユニットテストの追加を開始します。可能であれば、触れたものの呼び出し元の一部(またはすべて)のテストを追加します。これは(最終的には)人々が知らないうちに他のコードを壊すことを本当に難しくします。おそらくこれが現在起こっていることです(私はあなたのチームが故意に壊れたコードをコミットしていないと思います)。
また、コードの奇妙な絡み合いがたくさんあることも指摘するでしょう。これはおそらく問題の少なくとも一部です。
ソフトウェアアーキテクトの懸念に対処しながら、コードの共同所有権を維持するにはどうすればよいですか?
私はおそらく bikeshedding ですが、それはあなたの問題ではありません。会社はコードを所有しており、開発者や設計者ではありません。誰もが全体を改善するために働きます。エンジニアリングプロセスに問題があり、後で責任のないゲームが発生します。
障害の原因(セルフテストの失敗とコンポーネントの破損)を特定し、ギャップに対処するためのポリシーと手順を導入する必要があります。ポリシーと手順が整ったら、「物事はうまくいく」ので、誰にも責任はありません。
現在の状況では、開発者は複数のコンポーネントのコードを変更し、コンポーネントがどのように動作するかを理解していないため(非常に多くのコンポーネントで動作するため)、または変更がどのように影響するかについて気にしていないため、他のコンポーネントを壊しますコンポーネントの他のクライアント(影響を受けない限り)。
おそらく3分の1があるでしょう。開発者は、他のコンポーネントのコードを動かしたり壊したりしたことを知りません。
それは疑問を投げかけます:ギャップに対処するためのエンジニアリングプロセスには何がありますか?問題を早期に発見するためのポリシーと手順はありますか?
プロセス1
ASSERT
s の寛大な使用は、( [〜#〜] posix [〜#〜] の役に立たないassert
とは対照的に)開発者が確実に知っていると言えるでしょう。開発時のほぼevery予期しない状態。私はそれを「セルフデバッグ」コードと呼びます。コードが問題の場所を教えてくれるので、デバッガの下でほとんど時間を費やしません。
「ASSERT
sの寛大な使用」と言うとき、私はすべてを意味します。関数を入力するときは、すべてのパラメーターが予期されていることを表明します。関数で使用されるすべてのプログラム状態をアサートします。そして、システムコールからのすべての戻り値をアサートします。何かを検証するif
がある場合、一致するASSERT
が必要です。何かを検証するASSERT
がある場合、一致するif
が必要です。開発者が知らない限り、コードはおならやくしゃみをすることができません。
それを見る別の方法:なぜ私のコードをデバッグする必要があるのか、なぜ私はコードをデバッグする必要があるのか?コード自体をデバッグして、問題の場所を教えてください。
それを見る別の方法:デバッグに時間を費やす必要があるのはなぜですか?あなたの時間は機能を追加することに費やされます。コード自体をデバッグして、問題の場所を教えてください。
ASSERTの方法を学習していない場合は、John Robbinsを読むのはご褒美です。彼はマスターバグスレイヤーです。私が学んだ本はDebugging Applicationsでした。彼のブログは http://www.wintellect.com/blogs/jrobbins にあります。
2つのプロセス
コンポーネントの完全なセルフテストが必要です。私は肯定的なセルフテストに多くの時間を費やしていません。インドまたはパキスタンの子供を1日10ドルで雇って、良性の条件下で期待どおりに機能するコードをコピーして貼り付けることができます。レンタコーダーはそれらでいっぱいです。
私は否定的なセルフテストに焦点を当てています。プログラムがどのように失敗するかを知り、正常に回復または失敗することを確認したい。また、テストとは、すべてをテストすることを意味します。C++クラスの保護されたインターフェイスやプライベートインターフェイスも含めます。
「パブリックインターフェイスのみがテストを必要とする」という主張には賛成しません。誰かがバグのないプログラムを作成するまでホグウォッシュ。私のエンジニアリングプロセスでは否定的なテストケースを100%カバーする必要があるため、バグレポートの間に何年もかかるコードをフィールドに持っています。
プロセス3
ステージング領域への継続的な統合。すべてのコミットはビルドとセルフテストを開始します。ビルドに問題がある場合は、チェックインを拒否します。
本物の宝石
上記の3つのプロセスの本当の逸品は、エキスパートコーダーを必要としないことです。インターンとジュニア開発者を雇って、ASSERT
sでコードを計測し、テストケースを作成できます。コードはそれ自体をデバッグすることで大きな力を発揮しているので、エキスパートプログラマーの数は少なくて済みます。それは経営者を幸せにするはずです。
そして、後輩が明白な方法で彼らのコードを壊し始めるとき、あなたの専門家の開発者は腹を立てます。私は、10年または15年の経験を持つ男が何度も発砲しているいまいましい主張について私に不平を言った回数をあなたに言うことはできません。あなたがしっかりしていると思ったコードの問題を探し始めたときにあなたが見つけたものは驚くべきものです。
彼の分析には妥当性があり、一般的にプログラマーは問題を頭に「ロード」して、全体として問題に取り組みます。
複数の人が同じコードを編集しないでください。他人のコードや自分のコードを理解することはありません。
実際の状況によっては、プログラマーがお互いのコードを操作する必要がありますが、これは標準の操作手順ではありません。
ちなみに、これがTDDとコード品質が人気の大きな理由です。修正が最も安いときにバグをキャッチします。コードを記述して情報が消え始めるよりも後で問題を修正する方がはるかにコストがかかります。
ソフトウェアアーキテクトの役割の1つは、アーキテクチャをこの方向に移行する手助けをすることです。
ソフトウェアアーキテクトは、このプロセスを積極的に支援する必要があります。私は彼らがアーキテクチャについてより深い知識を持っていると思いますので、彼らはこの計画の詳細、モジュールに分解できるものを決定するのを助けることができるはずです?依存関係はどのように管理されますか?誰がどの部分の所有権を取得する必要がありますか?ソフトウェアアーキテクトが単に「所有権を取得する」と言っていて、すべての詳細をハッシュ化するのに役立たない場合、それらもこの問題の一部です。
1つのアプローチは、依存関係が最も少ない部分を見つけ、それらをリファクタリングすることです。そのためだけにリファクタリングするのではなく、多くの場合、各モジュールには1つまたは2つの機能リクエストがあり、リファクタリングする価値があります。書き直さないでください!
このプロセスにテストとコードレビューを追加すると、プログラマーは他の人が作成したモジュールを使用できるようになります。これは、より簡単にテストしてデバッグできる類似のコードを作成するためですが、コードレビューとコード所有権は、ソフトウェアを改善するために、計画の全体ではなく計画の一部である必要があります。
私は個人的にあなたの建築家は正しいと思います。私は、この「コードの所有権は悪い」という概念に慣れていません。私たちは職人です。コーダーは彼らが作成したものに対して責任を負う必要があります。そして、もし彼らが混乱を生み出すなら、彼らはそれを片付ける人でなければなりません。そうしないと、プログラマーがバグを作ったり、他の人たちがバグを修正したり、元のコーダーが間違いから学んだりしなくなります。またはさらに悪いことに、特定の貧弱なコーダーは常に間違いを犯し、他のコーダーは常にそれらを修正し、彼らの重荷を負うことに行き詰まっています。
はい、コードレビューが役立ちます。そして、人々がことわざのために他のモジュールに慣れ親しんでいることは常に良いですバスの状況によって実行される。しかし、責任を持って、そして防御的にコーダーコードを助けて、もし彼らが何かを台無しにしたとしても、彼らがそれを修正するために行き詰まっているという難しい方法を学ぶことは何もありません。
そうは言っても、あなたが説明したようなdaintyコードベースが簡単に壊れるので、コードの所有権の欠如がonlyの問題であるとは思えません。これは、前進する明確な思考が欠如していること、そしておそらく関係者全員の短期的な思考が多いことを示しています。
それは責任を共有することです。
各プログラマーは自分のコードに責任を持つ必要があり、同時にアーキテクトはすべてのプログラマーのコードをチェックする必要があります。
その「責任の共有」を実装するために、会社にはコードに関するいくつかのポリシーも必要です。それらは、バグを回避するのに十分「閉じる」必要があり、あまり制限されずにプログラマーがスキルを適用できるように「開く」必要があります。
ポリシーの例としては、バージョン管理ソフトウェアのインストールが考えられます。すべての開発者は、去る前に、コードに対する最後の変更を毎日保存する必要があります。
ポリシーの別の例は、「C」のような言語を使用して、「if-else」文をどのように書くかです。私が働いていた会社では、1つの命令しか使用していなくても、常にブラケットを使用しています。
したがって、この:
if ()
DoSomething();
else
DoSomethingElse();
これになった:
if ()
{
DoSomething();
}
else
{
DoSomethingElse();
}
プログラマーが雇われるとき、彼はコーディング方針について知らされるべきです。そして、契約書にサインします。ただし、ポリシーは、例やトレーニングを使用して、仕事を支援するものとして説明する必要があります。
開発者がルールをスキップしたり、ワークロードが多すぎたり、予期しないシナリオが発生したりする可能性があります。壊れたルールが1つのルールになることがあります。
しかし、開発者が重要でない理由でそれらを頻繁に破壊する場合、他の同僚を台無しにする可能性があるため、あなたは彼を解雇する必要があります。
会社に正式なポリシーがない場合、またはそれらのポリシーを更新する必要がある場合は、アーキテクトやプロジェクトマネージャーだけでなく、プログラマーと一緒に確認してください。
コンポーネントの変更が他のコンポーネントに頻繁に影響を与える場合、それは悪いアーキテクチャを意味します。したがって、そのようなエラーはすべて、建築家自身に原因があります。
彼がそれを認めた後、あなたは個人の著者に関する情報に同意することができます。隣接するコンポーネントの所有者が行ったコードレビューと連携することで、機能する可能性があります。
この方法では、悪い雰囲気は作成されません。
現在の状況では、開発者は複数のコンポーネントのコードを変更し、コンポーネントがどのように動作するかを理解していないため(非常に多くのコンポーネントで動作するため)、または変更がどのように影響するかについて気にしていないため、他のコンポーネントを壊しますコンポーネントの他のクライアント(影響を受けない限り)。
これは本当に管理上の問題のように聞こえます。開発者は、コードを所有するために必要なスキルを学ぶ時間を与えられていません。他の回答はこれに対する実用的な解決策を提供しますが、根本的な問題を解決するとは思いません。
5つの理由 を調べてグループに適用し、スキルが学習されていない理由を確認することをお勧めします。これがその例です。
この時点で、このトレーニングに投資するメリットにより、コードを実際に所有できるようになり、品質が向上することをマネージャーに納得させる必要があります。