プログラムを開発中からリリースにどのように移行しますか?


67

ある時点で、プログラムが開発中です。機能は常に追加、削除、または変更されています。すべてのバージョンはプロトタイプにすぎません。ですから、その時点で非常にきれいなコードを書くことに時間を無駄にしないのは、何かがいつまで続くかわからないからです。もちろん、コードの品質を特定の標準に保つよう努めていますが、時間は常に問題です。

次に、プログラムが終了し、意思決定者が「それでいい」と言うところまで来ます。私はこの時点で動作するプロトタイプを持っていますが、内部のコードは開発フェーズの前後で少し面倒です。テスト/最終デバッグを開始することが期待されていますが、メンテナンスなどを容易にする適切なアーキテクチャを提供するために、なんらかの方法でクリーンアップおよび/または書き直すべきであると言っています。

ひとたびテストされ承認されたら、その時点で書き直すことは意味がありません。定期的に「完成した」プロトタイプを使用してそこに立ち、テスト中にバグが発生します。これは、開発プロセス全体の結果であるスマートでないコーディングの結果であることがわかります。私はテストの最中であり、バグ修正は書き直しになるでしょう...それは混乱です!

より良い/教科書的な方法があります、私は確信しています。しかし、私はすべてが教科書ではない実際の職場環境で働かなければなりません。

それでは、どのように作業中のプロトタイプを安定したコードベースを備えたリリースバージョンに移行するのですか?たぶん、開発が完了したと考えるべきではなく、実際にクリーンアップフェーズと見なすべきです...わかりません。ここで助けが必要です。

編集

いくつかのことを明確にしたいと思います。

  • 私はコードをクリーンで読みやすいコードの前後ではなく、100%実行しています。しかし、私はまた、物事を成し遂げなければならず、コードの美しさをすべてきれいで輝くように夢見ることはできません。妥協点を見つけなければなりません。

  • 多くの場合、新しい機能は実際に試してみて、このようなものを実装する意味があるかどうかを確認したいものです。(特にモバイルアプリでは、実際のデバイスで実際のルックアンドフィールを取得するため)最初の「見てみよう」の繰り返しで(imho)があまり多くの作業を正当化しないのは小さなものです。ただし、このtech.debtを支払うときに疑問が生じることがありますか?それがこの質問のすべてです。

機能の半分が1日後に削除されることがわかっている場合(今までの会社での十分な経験)、私の問題にアプローチする最善の方法は、それでもすべてをきれいに書くために余分な時間を費やすことであると信じることは本当に難しいと思いますそのほとんどはまもなく削除されます。物事が固まったら一度大きなクリーンアップをすれば時間を節約できると感じているので、私の質問です。


68
あなたの質問は、「私は自分自身を穴に掘った。どうやって外に出るの?もちろん、標準的な答えはステップ1、「Deeping DEEPER」です。開発プロセスは、「膨大な技術的負債を生成し、期限が来たら無視する」と要約できます。これが問題になる場合は、開発プロセスを変更してください。慎重に作成された仕様を満たす、クリーンで動作し、デバッグされ、慎重にレビューされたコードのみをチェックインしてください。借金に陥らないでください、あなたは借金から抜け出す必要はありません。
エリックリッパー

11
@NikkyD適切な実装の時間が与えられていない場合は、ソフトウェアの品質への影響について上司と会話する必要があります。ここにいるすべての人があなたに言っていることを理解してください。前もって時間を投資しないと、後で効率的に仕事をする能力が損なわれます。あなたが彼らに持ち帰りたい別の問題:会社を辞めた場合(または「バスにひかれて」)、新しい開発者がコードに慣れるのは非常に高価です。彼らが今貯金していると思うお金は、後でそれらを犠牲にします。
jpmc26

32
機能の提案されたユーザーインターフェイスをモックアップするために小さな機能ブランチを作成している場合、それは素晴らしいことです。それを好きなだけすばやく汚し、クライアントに見せてから、そのブランチを削除します。自動車メーカーが粘土と紙で車を作り、新しいデザインをモックアップする場合、粘土モデルにエンジンを入れようとはしません。機能を実行する価値があるかどうかを判断するプロセスは、安価でなければなりません。この機能を実行することを決定したら、クリーンコードから開始、常にクリーンコードを生成していることを確認してください。これは、そのコードが本番コードになっているためです
エリックリッパー

10
「きれいで光沢のあるコードの美しさを夢見ることはできません」これは、「きれいなコード」の意味の根本的な誤解です。きれいなコードとは、タブを揃えて午後を過ごしてコードを印刷してフレーム化できるという意味ではありません。きれいなコード良いコードであり、良いコードきれいなコードです。クリーンなコードとは、適切に動作し、デバッグでき、理解できるコードです。最初からきれいなコードを書く時間がない場合、面倒なコードを書いて後で修正する時間は絶対にありません。それはタスクにかかる時間です。
-GrandOpener

8
「また、物事を成し遂げなければなりません。コードの美しさをすべてきれいで光沢があるとは夢にも思いません。妥協を見つけなければなりません。」妥協とは、双方にとって「十分な」妥協点を意味します。コードが乱雑である場合-特に、それを維持するのに苦労すると思うほど乱雑である場合-それは「十分」ではなく、より良い妥協を見つける必要があります。
アナキシマンダー

回答:


98

ですから、その時点で非常にきれいなコードを書くことに時間を無駄にしないのは、何かがいつまで続くかわからないからです。

何かがいつまで続くかわからないことは、ずさんな言い訳になることはありません-まったく逆です。最もクリーンなコードは、何かを変更する必要があるときに邪魔にならないコードです。ですから、特にプロトタイプをコーディングするときは、できる限りクリーンなコードを作成するようにしてください。何かを変更しなければならないとき(確かに起こるでしょう)にそれを適応することはずっと簡単だからです。

誤解しないでください-「最もクリーンなコード」についての私の理解は、美しさのためにコードを美しくすることとは関係ありません。それは本当にあなたを遅くすることができる何かです。私の観点では、きれいなコードとは、ほとんど説明のないコード(多くのドキュメントを書く必要がない-高速化をもたらす)、理解しやすい(エラーが少ないため、デバッグの必要性が少ない-高速化、正しい検索に必要な時間の短縮)変更する場所-スピードアップ)、必要なコードの最小量で特定の問題を解決し(デバッグするコードが少ない-明らかなスピードアップ)、DRY(何かを変更する必要がある場合に変更する唯一の場所-スピードアップ-導入するリスクが少ない) 2番目の場所を変更することを忘れることによる新しいバグ)、コーディング標準(考えにくい面倒なこと-スピードアップ)に従います。

テスト/最終デバッグを開始することが期待されていますが、メンテナンスなどを容易にする適切なアーキテクチャを提供するために、何らかの形でクリーンアップおよび/または書き直すべきであると私の腸は言います

後で「クリーンアップ」を実行しても機能しません。新しい機能を実装する、または実装を開始するときはクリーンアップを検討してください。その後は実行しないでください。たとえば、機能のメソッドに触れ始めて10行より長くなることに気づいたときは、機能を完了する前に、すぐにそれをより小さなメソッドにリファクタリングすることを検討してください。既存の変数または関数名を検出するたびに、それが何を意味するのか正確にわからない場合、それが何を意味するのかを見つけ、何かを行う前にその名前を変更します。これを定期的に行うと、コードを少なくとも「十分にクリーンな」状態に保つことができます。そして、あなたは時間を節約し始めます-デバッグに必要な時間はずっと少ないからです。

私はテスト中です。バグ修正は書き直しになるでしょう

...これは私が上に書いたものの実際の証拠です。「汚い」ことは、コードのデバッグを開始するとすぐにあなたに戻り、遅くなります。

すぐにクリーンアップを行うと、これをほぼ完全に回避できます。その場合、バグ修正はほとんどコードの小さな変更を意味しますが、大きなアーキテクチャの変更は決してありません。テスト中にアーキテクチャの改善の証拠を実際に検出し、それを遅らせて問題追跡システムに入れ、次にその変更の恩恵を受ける機能を実装する必要があるときに(その機能を開始するに)実装します。

もちろん、これにはある程度の規律とコーディング経験が必要です。「テスト駆動開発」の背後にある考え方と同様の考え方であり、後で行うのではなく、これらのことを事前に行います(TDDも役立ちますが、TDDを使用しなくても機能します)。したがって、これを行う場合、リリースする前に特別な「クリーンアップフェーズ」は必要ありません。


40
@NikkyD Doc Brownによる提案は、実際にかかる時間を短縮する習慣であり、長期的には非常に現実的です。変更する必要があるたびにコードを壊さない方法を見つけるためにコードを調べる必要がない場合、どれだけ時間を節約できるかを考えてください。ゲインは、「ハントアンドペック」タイピングからタッチタイプの学習への変更に似ています。最初は学習に時間がかかる場合がありますが、習慣が身につくと、間違いなく改善され、残りのキャリアで利益が得られます。試さないことを選択した場合、そこに到達することはありません。
ダニエル

44
@NikkyD:時間枠を膨らませません。時間枠はすでに肥大化しています。ソフトウェアを作成したときに肥大化を考慮しなかったため、予算を組んでいない技術的負債に陥りました。
エリックリッパー

7
@NikkyD:Feet of ClayTechnical Debtのコンセプトのあるアイドルを紹介します。前者は、不安定な基盤上でサウンドソフトウェアを構築できることを意味し、後者は、構造が健全でないときに追加しようとする機能が経験する「興味がある」(追加コスト)についてです。
マチューM.

10
@NikkyD:いいえ、ビリヤードの専門家がボールをプレーする方法と同様のコードを書くことをお勧めします。ショット後、ボールは新しい「単純なショット」の位置で止まるため、各ショットは部外者にとってシンプルに見えます。そして、ビリヤードまたはコーディングでは、これには数年の練習が必要です;
Doc Brown

16
@NikkyD:私の経験では、「小さな機能を追加するには多くのリファクタリングが必要です」というコードはすでに混乱しており、「たくさんのリファクタリング」の必要性は、あなたがやった関数やクラスを変更する必要があるという事実から来ています過去に十分にきれいに保っていない。物事をここまで行かせないでください。ただし、そのような状況にある場合は、妥協点を見つけてください。少なくとも「ボーイスカウトルール」に従って、機能を追加する前よりもコードをより良い状態のままにします。そのため、来週その機能が削除されたとしても、コードは以前よりも良い形になっているはずです。
ドックブラウン

22

2つの別個の問題があり、どちらも同じ症状(ずさんなコード)を持っています。

問題#1:要件の管理が不十分 利害関係者が頻繁に要件を変更するわけではなく、バグ修正/テストサイクル中に要件の変更を許可しているという意味ではありません。アジャイル手法でもそれをサポートしていません。構築し、テストし、提供し、新しい要件を注入します。

問題#2:あなたが書いているものは「今のところ」であると信じている ソフトウェア開発では、「今のところ」コードは非常にまれです。ユーザーの要件を満たした後は、需要と供給の厳しさにより、「完了」機能を実装し直すことを正当化するのが非常に困難になることに気づきました。それでは、どうすればいいのでしょうか?常に実動コードを作成してください。機能的には、利害関係者への見積もりを大幅に大きくする必要があるため、適切な時間を確保できます。

また、あなたが開発者として最も困難な立場で働いていることを理解してください:社内開発者の生活に関するJoel Spolskyの見解を 読んでください。そのため、健全性を損なわずにやり遂げたい場合は、十分に注意する必要があります。


21

これは一般的な問題です。特に、本質的にソフトウェア トライアルバルーンを作成する場合はそうです。

役立つ多くのアプローチがあります。まず、TDDアプローチは、コードベースを厳密に必要なものに減らすのに役立ちます。テストがコードと密接に関連していれば、少なくともコードが本来どおりに動作することをある程度確信できます。

時間をかけてリファクタリングしてください。プロトタイプを作成し、顧客がそれを手に入れることに非常に熱心になったら、完成したものを磨くのに時間が必要だと言うのは難しい売りです。私は毎日チェックインした後、YMMV以外のリファクターチェックインが好きです。

コードを素早く書く開発者はしばしば需要があります-私たちの最後の部門にはそのような開発者がいました。彼は非常に速く働いたので、すべてのチームが彼を望んでいました。しかし、コードをテストしてリリースする時が来ると、車輪はすぐに外れました。ハードコードされたもの、ハック、ショートカットはどこでも。彼の在庫はすぐに落ちました-大規模。

生産コードを最初からカットすることはドラッグのように見えますが、環境によっては、GhostdocStylecopなど、開発の手間省くことができるツールがたくさんあります。

最初から適切な開発マインドセットを取得する価値があります。単なるストップギャップソリューションであるはずのパケットバックシステムがどれだけ基礎的なアプリケーションになるのか、驚くでしょう。


あなたが意味するすべての権利、これまでに書かれたストップギャップソリューションを?
ラバーダック

4
顧客への正当化に関する大きなポイント。GUIが完成したように見えると、アプリケーションも完成したと考える顧客との豊富な経験があります。バックグラウンドでのコードの準備がまだできていないときにGUIを不完全に見せることを学びました。その結果、コード(およびビジネスロジック)が完成したときに顧客に見えるものだけが洗練されたように見えます。顧客に仕上がったように見えるものが実際に届けられるまでにまだ1、2ヶ月かかると説明するのは非常に難しいです。
ルアーン

11

継続的に

開発の速度が、クリーンで読みやすく、テスト可能なコードを書く主な理由です。それは美のためにも、他の抽象的な価値のためにもされていません。なぜ私はそれを自分で否定し、将来のプログラマーのためにそれをやるだけですか?

確かに、ほとんどが外観上の変更であり、したがって重要ではない変更があるかもしれません。私は、開発中に今すぐ適度に素敵なコードを用意する方が、今混乱して後で完璧にすることを望んでいるよりもはるかに便利であると主張します時間)。


6
+1と個人的な観点から、自宅で個人的なプロジェクトをハッキングし、私の仕事で生産コードを書くことからギアを変更するのは難しすぎると感じました。私の趣味のプロジェクトでプロのコードを書くと、すぐに成果が上がりました。コードは読みやすく、バグははるかに少なかったです。
ロビーディー

それが決して起こらない理由の1つは、時間の経過とともにあなたが(より良い)あなたが何をするかにより良くなることです。したがって、何かを「クリーンアップ」するために半年待つと、クリーンアップを安全に行うために必要なすべてのminutaeを忘れるだけでなく、以前よりも優れたプログラマーになり、誘惑される可能性があります。すべてを捨ててやり直します そして、それは非常に多くの作業であるため(多くの場合、とにかく悪いアイデアです)、おそらくクリーンアップを再びスキップすることになるでしょう。
ルアーン

「なぜ私はそれを自分自身で否定し、将来のプログラマーのためにそれをやるのですか?」啓示!そして、何だと思う?あなたは時々(そして時には、しばしば)その将来のプログラマーです。
レーダーボブ

@RobbieDee、最高の観察!インタビューでMalcom Gladwell-「10,000時間ルール」を一般の認知度にもたらした人(Outliersの本で)は、それは「意図的な練習」であるか、時間を浪費しているだけだと言いました。改善に焦点を当てること、スキルのその特定の側面を改善することを目的とした具体的な実践など
レーダーボブ

@ThanosTintinidis、それから「善行は罰せられない」問題があります。そのようなクリーンなコードを書いた人は、必然的にそれをブロックします。他の誰かがあなたのきれいなコードに触れるときは、あなたがコードレビューアであることを確認してください。簡単な追加方法の1つは、インラインで文書化されたカプセル化と一貫性を実現しました。私は一週間激怒しました。そして1年後、そのコードを見るたびに。
レーダーボブ

4

これを行うには、「これがどのように機能するかを確認するためにこれを試しているだけです」コードと「これは製品に向かう」コードを区別します。それを行うには多くの方法があります。

1つは、分岐またはソース管理システム内の単語が何であれです。新しいレポート、新しいインポートレイアウト、その他のブランチを作成します。人々がそれを好めば、それをメインブランチに戻す仕事は別の追跡可能な仕事です。誰かに割り当てて報告することができ、機能が製品に属していることを日管理(または販売)が同意するだけで魔法のように起こるとは期待されていません。

もう1つはスパイクです。製品ではその変更を行いません。あなたはコードを置く場所を持つためだけに存在する、非常にシンプルな別のアプリに行きます。新しいAPIなどを探しているだけなので、好きなだけ散らかることができます。繰り返しになりますが、戻って「はい、できます。方法を見つけました」と報告すると、追跡可能なレポート可能な割り当て可能なタスクがあり、製品で製品対応のコードを記述して、必要な処理を実行できます。

どちらの場合も、製品対応とは、読みやすく、簡潔で、命名基準に従い、テストを行い、コードスタイルとパフォーマンスターゲットを遵守することを意味します。どちらの場合も、その作業を表示します。誰かがこの機能を製品から削除する可能性が高い場合は、毎回すべての作業を行いたくないことに同意します。ただし、その作業を非表示にしたくない場合もあります。製品の個別のコピーで、またはテストハーネスにとどまらない無関係な製品で作業することで、誰かが何かが欲しいと判断したら、作業を表面化して製品の準備ができたコードを作成できます。

欠点は、明日、何か欲しいものを決めてそれを出荷できないことです(つまり、概念実証として実装した、半ば嫌い、乱雑な、テストされていない、文書化されていない、おそらく遅いハーフバージョンを意味します)。彼らが最初にプッシュバックするときは、念のために、毎回長い(より高価な)方法でそれを行うべきかどうかを尋ね、拒否された機能への道を遅くします。正しく尋ねると、「いいえ」が表示されます。


1

本当に問題をすでに理解していると思います。問題は、コーディングスタイルにより、やり直しが多すぎることです。やり直しが多すぎる理由は、(a)不十分な先見性と計画とともに組み立てられていること、および(b)開発中に定期的に追加される短期パッチが増分的に必要とされるすべてのやり直しの複雑さを増大させるためです。

したがって、答えは

(a)開発スタイルをウォーターフォールに向けてもう少しシフトし、アジャイルを少し減らします。ただし、古典的な滝には独自の落とし穴があります。健康的なバランスが必要です。開発がまだ行われていないように、数日間物事について考えることだけに関係することもありますが、プロセスを信頼する必要があります。エンジニアリングでは、物を一緒に釘付けしてから、物事を上に釘付けして、エレガントな解決策を考え出すことはできません。誰もアーキテクチャと高レベルの技術設計を行っていない場合、それはあなたの仕事を意味します。あなたはその仕事を怠る代償を払ってきました。

(b)パッチを当てないようにしてください。QAを行う時が来たときだけ、長期的に考えないでください。実際、構築するすべての小さなピースを常にテストし、すべての入力ケースをカバーする必要があります。これらのケースは、ハッピーパスにもありません。パッチ/ハックは、ほとんどの場合、短期的な修正であり、長期的なコストがかかる可能性があり、システムのクライアントの総所有コストに影響します。繰り返しますが、コードを公開するというプレッシャーがかかっているため、バランスを取る必要があります。しかし、短期的な修正を適所に置かないようにしてください。本当に疎結合されるべきコンポーネントを密結合するもの。再作業が行われるので、時間の経過とともにマウントされて管理不能になるハッキングやパッ​​チを回避するために、早期にそれをはるかに簡単にする必要があります。


2
ほんの一言-アジャイルとは、「考えずに頻繁に変更する」ことや「デザインを少なくすること」を意味しません。実際、アジャイルには、人々が一般的にウォーターフォールと呼んでいるものよりもはるかに多くの設計が必要であることがわかりました。優れたデザインの欠如は、実際にはウォーターフォールがうまく機能しない理由の1つです。実際にデザインに適切に投資すれば、うまく機能します。また、アジャイルよりもはるかに高価になります。アジャイルで設計の部分をスキップすると、コードを意地悪に結び付けているだけであり、設計を回避する他のプラクティスよりもうまく機能しません。
ルアーン

短い反復、スプリントなどにアジャイルに焦点を合わせ、プロトタイプを迅速に開発するため、十分な設計を前もって無視することにより必然的にプレッシャーがかかる
Brad Thomas

いいえ、小さな部品の設計に重点を置いています。しかし、全体的には、多くのこと設計する必要あります。そうでなければ、恐ろしい製品を生産するだけです。重要なのは、物事を小さく、適切に設計し、交換可能にすることです。アジャイルでの設計を減らすと、自分自身(および顧客)に損害を与えることになります。短いイテレーションは、前提条件やプロセスの一部ではなく、アジャイルを使用することの利点です-すべてが十分に得られると、突然、短いイテレーションを行うことができます。
ルアーン

本当に大きな絵が再作業の最も重要な原因である場合、小さな部品の設計に重点を置くことは大きな問題です。私は、「しかし、これを行うにはそれが必要です」と言って、突然のビジネスに多くのお金が浪費されるのを見ました。それは、私が今までに見たよりも広範囲のオーバーホールを必要とします小さな疎結合コンポーネント
ブラッドトーマス

はい。しかし、その時点までにあなたはすでに負けています(そして、アジャイルとウォーターフォールのどちらをしようとしているかに関わらず)。「全体像」が比較的孤立している多くの小さなパーツで構成されている場合、広範囲にわたるオーバーホールは、ほとんどすべてを交換する必要がある場合のみです。ゼロから始める必要があるときに、すべてを失うことのないアプローチ何ですか?NASAのレベルの設計でさえ、「すべてを変更する必要がある」ということもあります。柔軟性と順応性を維持することで、小規模または大規模な変更に対応するためのより多くの操作スペースが得られます。
ルアーン

0

あなたが書く:

すべてのバージョンはプロトタイプにすぎません。ですから、その時点で非常にきれいなコードを書くことに時間を無駄にしないのは、何かがいつまで続くかわからないからです。...

次に、プログラムが終了し、意思決定者が「それでいい」と言うところまで来ます。私はこの時点で動作するプロトタイプを持っていますが、内部のコードは開発フェーズの前後で少し面倒です。

チェックインバージョンは、機能を失うか一部の機能が肉付けされないという点で「プロトタイプ」になりますが、チェックインするコードはすべて、必ずしもクリーンアップを必要としない製品品質のコードである必要があります。

「クリーンアップ」を大幅に延期していると思います。

私の経験則は次のとおりです。

  • (サブ)機能で開始
  • 私はコーディングの最後の時間(秒)をスクラッチする必要がある場合、私は実装したりしています何の感触を得るために、不完全とinclompleteもの、おそらくいくつかのC&Pを書く気軽に(これがあることに注意することができます TDD /テストと手をつないで行きます、私が探求している実装スペースの素早いフィードバックを得るために、すべてが少しトーンダウンされているだけです)
  • 今のところ十分に機能するサブ機能
  • 次に、SCCコミットの前にクリーンアップを実行します。
    • コードを見て、明らかなことを確認してください
    • 変更を確認し、おそらくいくつかの問題をキャッチするために、最後のコミットと比較してください
    • スクラッチパッドに書き留めたものを修正する
  • 今、私はコミットします-このコード品質は出荷する準備ができています

この時点で、コミットされたコードには、クリーンアップするのが良いと思われる回避策または「技術的負債」が含まれている可能性があります。そのコードがそのままリリースされれば問題ありません。

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