こんにちは、Habr。 私の名前はエフゲニー・ウドドフです。私はロイスタットの共同設立者であり技術ディレクターです。 大規模で複雑な製品である分析システムの開発での経験を共有したいと思います。
TL; DR :
コード規約をgithubに投稿し、記事でそれを実践する方法について話しました。
大きな製品を開発するとき、共通の問題があります-時間の経過とともに、多くのレガシーコードが蓄積し、タスクがますます遅くなります。 また、チームの成長に伴い、開発者はさまざまな方法でコードを記述し始め、統一されたルールの欠如が競合と紛争につながる可能性があります。
私たちのプロジェクトの存在の4年間で、私たちは20,000を超えるプルリクエスト(以下PR)を行ってきましたが、これらの問題をどのように解決したかを説明します。
最も役に立つ記事を書こうとしました。 以下にリストされた問題に遭遇した場合、あなたはそれに興味を持ちます。
テクニカルディレクターまたはテクニカルエキスパートの場合:
- なじみのないプロジェクトコードで何が起こっているのかを理解するには、多くの時間を費やす必要があります。
- 各タスクについて、開発者に同じエラーを指摘する必要があります。
- 機能を作成する方法について議論した後、開発者は合意されたものと同じではないPRを行います
- 誤ったPRの後、開発者はいくつかの間違いを犯して、他の人を作ります
- 新しい開発者が長い間滞在しなくても、各開発者のトレーニングに多くの時間を費やします
- 上級開発者は独自のルールを考え出し、経験の浅い人にそれらを課します
プロダクトマネージャーの場合:
- 開発者は、各機能(一見、最も難しいことではないように思えます)について議論するとき、それを行うには長くて費用がかかることを伝えます
- プログラミングの原則は大体理解しているが、プロジェクトのコードについては何も理解していない
- 複雑なタスクを完了するには、新しい開発者が最新の状態を保つのに長い時間を待つ必要があります。
開始する
2014年の初めには、わずか2〜3人の開発者がRoistatで働いていましたが、最初の問題はすでに始まっています。 各開発者は同じ間違いを説明する必要があるという事実に直面しています。 また、開発者の数が増えているため、この状況は悪化しているだけです。
経験豊富な開発者にとっても、別の困難がありました。 彼らはそれぞれ、自身の蓄積された経験と、プロジェクトのアーキテクチャを構築する方法についての独自の理解を持っていました。 多くの場合、彼らの意見は互いに矛盾していました。
雪玉のように蓄積された同様の問題。 これが続くと、開発の速度と柔軟性が失われ、各リリースが苦痛を伴うことは明らかでした。
ソリューションを検索する
まず、問題のある領域について議論し、将来そのような場合に何をするかについての言葉で合意しました。 当然、これは機能しませんでした。 しばらくして、誰もが以前に合意したことについて異なる考えを持っていました。 また、新しい開発者はこれらの契約について知りませんでした。
次に、「すべての人にこの情報を同じように修正する方法は?」と考えました。 プロジェクトのアーキテクチャと開発の基本原則について話し合ったトレーニングビデオを記録しようとしました。 しかし、この形式は非常に不便でした。 ビデオを修正または上書きすることは困難です。 プロジェクトの活発な成長の間、新しい合意または古い合意への変更を必要とする新しい状況と新しい問題が絶えず発生します。
その後、ディスカッションの結果を別のドキュメントに記録し始めました。 最初は、ほんの数件の提案でした。 しかし、Code Reviewでは、開発者がコードに個人的な意見を課すべきではないことに同意しました。 代わりに、彼らはこのドキュメントを参照し、それとの矛盾を指摘する必要があります。 必要なルールがない場合は、まず問題を話し合い、共同で解決策を考え出し、ドキュメントに記述してから、コードレビューに戻って続行する必要があります。
そしてそれは働いた。 契約に対する異なる理解の問題は最小化され始めました。 このドキュメントでは、コード例を使用して詳細な説明を書いたため、誰もそれらを異なって解釈することはできません。 私たちのチームの新しい開発者はそれぞれ、彼に何が必要か、そして私たちがさまざまな状況で行動することがどのように慣習的であるかをすぐに理解できました。 コードレビューは、終わりのない議論と紛争の代わりに、かなり透明で実用的なプロセスになりました。
6か月の作業の後、このドキュメントには既に多くの有用な情報が含まれており、チームの作業に不可欠なツールになりました。 これをCode Conventions(または略してCode Conv)と呼びました。
コード規約
コード変換-これらは、コードを記述するときに従わなければならない規則です。 コードスタイルとコード変換を区別します。 私たちにとって、コードスタイルはコードの外観です。 つまり、インデント、コンマ、ブラケットなどの配置。 Code Convは、コードのセマンティックコンテンツです。 正しいアクションアルゴリズム、変数とメソッドの名前の正しい意味、コードの正しい構成。 コードスタイルへの準拠は、自動化によって簡単に検証されます。 しかし、ほとんどの場合、コード変換のコンプライアンスを検証できるのは人だけです。
Code Convを使用する場合、次のアプローチを取ります。
開発者向け:
- 開発者は、チームでコードの最初の行を書く前にこのドキュメントを研究します。
- 開発者は、書かれた規則を理解し、理解しなければなりません。 このドキュメントを学習するだけでは機能しません。
- 開発者は、コードを記述する際にCode Convのルールに厳密に従います。
- 開発者はPRを作成し、すぐに自分でそれを調べ、Code Convへの準拠をチェックします
- 開発者はPRをCode Reviewに送信し、指摘されているが自分が見逃しているCode Convのエラーと不整合を修正します。
コードレビューアの場合:
- レビュー担当者は、コード変換で説明されているルールに準拠しているかどうかコードをチェックします
- コードレビュー中に開発者に発言が表示される場合は、コード変換へのリンクを添付する必要があります。
- Code Convに必要な項目がない場合、ワーキンググループは新しいルールを作成し、ドキュメントで修正します。 その後、レビュアーはPRチェックに戻ります
いくつかの例
私が話していることを明確にするために、このドキュメントが実際にどのように見えるかの例をいくつか示します。
ドキュメントの最初に目次があります。 時間が経つにつれて、情報は目次なしでますます多くなります-どこにもありません。
値、一般原則、特定のルールの3つの主要セクションがあります。
値は、開発チームのビジネス要件です。 企業は、どの方法論と原則が内部で使用されているか詳細を知りませんが、製品が単純に、迅速に開発され、時間の経過とともに複雑にならないことが重要です。 これらの値は、新しいルールの開発と、ルールに記載されていない問題に対処するために、チーム全体が従う必要があります。
原則は、前述の値を維持する方法です。 それらはもう少し詳細であり、基本的な開発方法論と私たちが導かれているアプローチを含んでいます。 経験豊富な開発者は、ドキュメント全体を覚える必要はありません。 彼はこれらの原則を理解するだけで十分であり、彼はいつでもこれらの原則から他のすべてのルールを導き出すことができます。
それでも、価値と原則はさまざまな方法で解釈できます。 誤解を避けるために、ドキュメントには特定のルールとコード例があり、どのようにそれを行うことができ、どのようにしないかが示されています。
そのようなルールはたくさんあり、ドキュメントの大部分を占めています。 彼らのおかげで、秩序は維持されます。
実際には、ドキュメントの適用は次のとおりです。
Code Reviewの開発者は、Code Convに違反していることに気付いたコードの部分についてコメントします。 コメントで、彼はどのルールに違反しているかを示しています。 また、オプションで、これが明白でない場合は、彼がそう思う理由の説明を追加します。
たとえば、このスクリーンショットでは、DRY(Do n't Repeat Yourself)の原則に違反していることがわかります。 この特定のPRでは、開発者が繰り返しなくコードを記述し、1回しか使用していないように見えますが、追加の検証なしでは将来使用できないメソッドを作成しました。 つまり、彼は明らかにコードとロジックの繰り返しを必要とするメソッドを作成しました。
頻繁な開発者の反対
開発者はしばしば、さまざまな口実の下で、コード変換に対応しないコードをプッシュしようとします。 彼らは違反に対してさまざまな言い訳を見つけますが、最も一般的なものがいくつかあります。
「でも一度は可能ですか?」
開発者は、Code Convの1回の違反でも害はないと考えています。 また、あまり重要ではない場所では、これらのルールは価値を持たないか、重要ではないと信じることがあります。 これに応えて、私たちは常に
壊れた窓の
理論を参照し
ます :「1つのガラスが建物で壊れていて、誰もそれを交換しない場合、しばらくすると、この建物には窓全体が1つなくなります。」 規則に例外を設けた場合、6か月後には、プロジェクトコード全体がこのような違反で構成される状況に陥ります。
「しかし、非常に緊急に必要です!」
開発者は、長い間行うのは普通であり、クライアントが問題の解決を待っていると言い、戦闘はできるだけ早く編集する必要があります。 しかし、第一に、Code Convは単純化されたコードで最初の反復を行うことを禁じています。 このコードはまだ品質基準を満たしている必要があります。 第二に、まだコード変換に違反する必要がある場合、作成されたエントロピーが悪性でない場合にこれを行うことは許されます(詳細は以下)。 ただし、この場合でも、この状況でCode Convを実行すると実際にはさらに多くのコストがかかるという共通の理解が必要です。
エントロピーに関するいくつかの言葉。 エントロピーは、プロジェクトが構成する情報の量です(プロジェクトの情報容量)。 開発者がすべての開発者が知る必要がある重要な情報を追加するコードを記述する場合、そのようなエントロピーは悪性です。 多くの場合、このようなコードは時限爆弾です。 つまり、現時点では、この無知は何にも影響を及ぼさない可能性があり、将来的にはそのために重大なエラーが発生する可能性があります。 このようなエントロピーを悪性と呼びます。 情報の無知が他の開発者の作業に影響しない場合、そのようなエントロピーは有害ではなく、私たちはそれを害のないものと呼びます。
たとえば、いくつかのイベントをリッスンし、どこかに統計を追加する別個のマイクロサービスを作成する場合、このサービスは悪性エントロピーを導入しません。 他の開発者がこのサービスについて知らない場合、彼らは間違いを犯さず、作業に影響しません。 破損した場合、このサービスの所有者を除いて誰も苦しむことはありません。 そのため、このようなサービスでは、低品質のコードを使用して最初の反復(概念実証など)を実行することができます。 そして、それを開発する必要がある場合は、定められた技術的負債を修正し、すべてのルールですでにそれを使用する必要があります。 その結果、Code Convは、システムの他の部分に影響を与えない限り、実験や高速で簡単な概念の作成を禁止していません。
おわりに
このアプローチにより、4年以上にわたって高い開発ペースを維持し、新しい開発者を簡単に仕事に取り入れることができ、時間の経過とともに遅くなることはありませんでした。
マイナスのうち、このアプローチでは、コードレビューに通常より時間がかかることに注意できます。 小さなタスクでも、最も重大なエラーではないため、数日以上遅れることがあります。
しかし、このマイナスはプラスによってブロックされます。これは、悪性コードが戦闘に陥らず、すべての「ウィンドウ」がそのまま残るためです。
Code Convの例を共有するように繰り返し求められました。
みんなと共有して公開することにしました。 そのまま使用して、すぐに使用できます。 または、自分で変更できます。 また、PRにも対応しており、改善のための提案を検討します。
コード変換へのリンク開発チームを積極的に拡大しているため、アプローチがお客様に近い場合は、
空席に対応するか、
メールでご連絡ください 。