偶然によってプログラミングを克服する方法は?[閉まっている]


24

The Pragmatic Programmerの本では、作家はプログラミングを偶然の一致の概念に言及しています。それが何であるか、なぜそれが引き起こされるのか、あなたが遭遇するかもしれない危険は何かを説明し、戦争中の地雷原と比較します。

古い白黒の戦争映画を見たことはありますか?疲れた兵士は慎重にブラシから飛び出します。前にクリアがあります:地雷はありますか、それとも安全に渡れますか?地雷原であることを示す兆候はありません。標識、有刺鉄線、クレーターはありません。兵士は銃剣とひるみで彼の前の地面を突いて、爆発を期待します。ありません。それで、彼はしばらくフィールドを苦労して進み、彼が行くにつれて突き、突きます。最終的に、フィールドが安全であると確信して、彼はまっすぐになり、誇らしげに前進し、破片に吹き飛ばされるだけです。

兵士による地雷の初期調査では何も明らかにされませんでしたが、これは単に幸運でした。彼は誤った結論に至り、悲惨な結果をもたらしました。

開発者として、私たちは地雷原でも働いています。毎日私たちを捕まえるのを待っている何百ものtrapがあります。兵士の話を思い出して、私たちは誤った結論を出すことに注意する必要があります。偶然のプログラミング(幸運と偶然の成功に頼る)を避け、意図的にプログラミングを行うべきです...

しかし、私は彼らが「それを克服する方法」問題を説明する方法に本当に満足していません。ええ、あなたはコードを書く前に先を考えなければなりませんが、それをどのように実践するのですか?私が考えることができる唯一のことは、既存のオープンソースプロジェクトに機能を追加することです。ここでは、「今何をしているのか」と「他のコードの動作」の両方に関する知識が必要です。独自のプロジェクトを書いているとき。

編集:

投稿の要約:

  • 次の動きを推測しないで、それが正しいことを証明してください
  • 必要に応じて、可能な限り単体テストとリファクタリング
  • 機能の追加-コンパイル-テストを頻繁に行う
  • 初心者にコードを説明できない場合、おそらく偶然のプログラミングでしょう。

ところで、答えを受け入れるのは難しいです、本当に難しいです。すべての答えは本当に素晴らしいです:)


6
この本を長い間読んでいなかった人々がpragprog.com/the-pragmatic-programmer/extracts/coincidenceのようなリンクを持っているのを助けるでしょう。
btilly

プログラミングのキャリアが非常に短い(または1人の男性ショップである)場合を除き、奇妙に馴染みのあるコードに出くわす可能性があります。それは...だけでなく、オープンソースの検討事項である
ロビーディー

@ロビー・ディー。もう少し明確にできますか?わかりません。実際、私はプログラミングのキャリアが短く、それがジュニアプログラマータグの理由です。
py_script

2
@py_script私はあなたが自分のコードに数年後に簡単に出会える(そしてそれによって混乱する)ことができることを他の誰かと同じように指摘していました。したがって、良い習慣から始めれば、これは後で配当を支払うことになります。
ロビーディー

回答:


26

あなたは先を考える必要はなく、単に何が行われたのかを非常に明確にし、あなたが今何をしているのかを非常に明確にする必要があります。

サブルーチンは、何をすべきかを言い、彼らが言うことをし、隠された依存関係を持ってはいけません。そうすれば、誰かがそれらを呼び出すことで、彼らが何をするかについてより簡単に推論することができます。

グローバル状態を避けてください。(変数、シングルトンなど)物事が何をするかを理解するために頭の中にもっと多くの状態を持たなければならないほど、何が起こるかを理解してエッジケースを見つけることは難しくなります。

単体テストを作成します。単体テストは、探している理想的な動作ではなく、作成したばかりのコードの実際の動作をキャプチャするのに最適です。

編集/コンパイル/テストのサイクルを短くします。大量のコードを追加してテストを不十分にすると、予想とは異なる動作をする可能性が高くなります。次に、ランダムな変更を加えて「修正」し、今のところ正しい答えを得ましたが、実際にどのように発生したのかわかりません。偶然のプログラミングです。しかし、5行追加してからテストすると、正しいと思われるように動作するため、正しい答えが得られる確率ははるかに高くなります。経験から言えば、個別にテストされた各10行の5つのチャンクは、一度にテストされた50行のコードとは非常に異なるものです。

冷酷にリファクタリングします。多くの場合、コードをいくぶん単純にするリファクタリングを見つけましたが、やりたくない作業をたくさん取ります。優先事項としてこれらのリファクタリングに意図的に取り組み始めた後、通常は1か月以内に成果を上げることがわかりました。しかし、キーに注意してください、私が焦点を当てているリファクターは、日々の生活をよりシンプルにするものであり、より良いまたはより一般的な何らかのarbitrary意的な美学を満たすものではありません。私が学んだこれらのリファクタリングは、より慎重になりました。

これらはどれも事前の計画を必要としません。しかし、これらはすべて既存のコードを理解しやすくするため、次の小さなチャンクを意図的な方法で簡単に実装できるようにします。


ありがとう、本当に良い答え。サイクルについての部分は本当に価値があると思います。リファクタリングを行う必要があるが、実装に非常に時間がかかり、誰かを落胆させるかもしれないリファクタリングの例を教えてもらえますか?
py_script

1
たくさんの例があります。C ++プロジェクトでは、文字列化メソッドのないクラスを作成しました。それらを作成すると、デバッグが容易になり、開発がスピードアップしました。Perlプロジェクトでは、各開発者がそれぞれの新しい構成の微調整されたコピーを持つ構成ハッシュがありました。すべての開発者の構成を編集しなければならなかったため、構成パラメーターの追加は苦痛でした。ハッシュ用のテンプレートシステムを作成しましたが、簡単になりました。レポートシステムに、中間結果を表示する機能を追加しました。私の開発がスピードアップし、私もユーザーのバグ報告を得ました...
btilly

1
財務部門が私のロジックをトレースし、間違ったクエリとバグを正確に見つけました。(間違って重複した行UNIONを必要な場所に押しつぶしていましたUNION ALL。)など。
btilly

1
1ヶ月以内に?通常、コードに触れるたびにリファクタリングする必要があると感じますが、リファクタリングしていないため、リファクタリングするのと同じくらい時間がかかります。
エイミーブランケンシップ

1
@AmyBlankenshipはい。月の中。時にはとんでもないことに、時にはそうではない。上で述べた設定ファイルは、「時々」という例です。新しいテンプレートエンジンの作成、文書化、テストには数日かかりました。次に、既存の構成を書き換えて使用します。はるかに短くなりますが、まったく同じデータ構造を生成します。(それがプロジェクトの最も難しい部分でした。)だから..日が無駄になり、目に見える結果は全くありませんでした。しかし、この努力はわずか1か月足らずで報われましたが、それ以来関心を集めています。
btilly

41

推測しないためにかなり煮詰めます。ほとんどの新しいプログラマーがそれを行いますが、ベテランもそれを行うのを見てきました。なぜなら、彼らは研究時間を節約できると思うからです。あなたが追加して何かが、ない仕事をし+1たり-1、変更するtrueにはfalse、いくつかのステートメント並べ替え、またはその逆の追加や、それが動作するまでの変化の遅延、変更スレッドの優先順位、およびその他の小さな変換は、基本的にランダムな順列をテストします。

これは主に既存のコードの変更に適用されますが、真にゼロから始める人はいないため、新しいコードの要因でもあります。常に標準ライブラリ、オペレーティングシステム、または少なくともプロセッサアーキテクチャの上に構築します。

つまり、修正が機能する理由がわかるまでは完了しません。そこにたどり着くまでの道はそれほど重要ではありません。ランダムな並べ替えでさえ、「OK、trueからfalseに修正したが、なぜですか?」


1
優秀なポイント+1。どこにもこれは...より多くのコードの修正よりも当てはまらないん
ロビーディー

残念ながら、私にも当てはまります。正直に言うと、ドキュメントの不足などの客観的な問題が時々あります。今日、私はコードを少し修正していましたが、ドキュメントが不足していたため、パラメーターが何に役立つかわからないという事実に思いつきました。私たちはそれが数字であることを知っています。
py_script

私は認めます。傾くつまようじ症候群に直面するとき、それがうまくいくまで\ sを積み重ねることは、あなたがどのくらいの数の層と
闘っ

16

私がこれまでにプログラムで遭遇した最も恐ろしいコメントは

これに触れないでください。できます。方法や理由はわかりませんが、機能します。1

そして、それはコードの一部が偶然プログラミングの結果であることを認めているという理由だけで怖いです。

偶然のプログラミングを避けるために、コードが何をするのなぜ機能するのかを(同僚、自分、またはゴム製のアヒルに)正確に説明できる必要があります。意図的にプログラミングするための箇条書きは、コードを説明できるという目標に向かって進むための助けになります。


1コンテキストについては、このコメントはプリミティブOSのコンテキストスイッチを処理するコードに登場しました。このコードは、私が遭遇した数年前からすでに本番環境にありました。


2
これはvoodoo chicken coding c2.com/cgi/wiki
。VoodooChickenCoding– minusSeven

1
コーダーがそれを真実だと信じていたとしても、そのようなコメントは非常に役に立たない。コードは複雑だったかもしれませんが、別の方法でコードを読むとしたら、簡単だと思うかもしれません。コメントはパラノイアを増やすだけです!
ロビーディー

3
これは、現在の開発チームのほとんどがあまり慣れていない言語で古いコードベースを維持している場合にも発生する可能性があります。
-pcurry

そのため、ゴム製のアヒルはデバッグ用だけではありません。いいね...私たちは同じ会社に取り組んでいると思う、私たちはこのような多くのコメントを持っている:P
py_script

APIの不具合のために修正が機能する場合がありますが、それ以上の論理的な修正はありません。コンパイルされたサードパーティのlibのデバッグは、カーネルのデバッグと同じくらい深くなります。そして、たとえ問題を発見したとしても、何時間もデバッグした後、できることはほとんどありません。そのため、問題へのアプローチは異なります。偶然にプログラムすることを強制する「ブラックボックス」モデルを採用します。ブラックボックスの奇妙な振る舞いをいじくりまわし、望みどおりに動作させることができたら、素晴らしい、「魔法は触れないで」というコメントを追加して先に進みます。
ラドゥシミオネスク

7

新しいプログラマーにとって、これを克服するための最も重要な部分は、彼らが何をしているかを本当に理解することです。

多くの分野で、何かをする方法がわからないときは、試行錯誤を繰り返します。何か試してください。それが機能する場合、素晴らしい、そうでない場合は、何か他のものを試してください。

プログラミングでは、特に未定義の動作(CやC ++など)の概念を持つ言語を使用する場合、成功はもはやブール値の決定ではないため、このアプローチは単純に機能しません。「ある種の」機能、時には機能するもの、一部の入力に対しては機能するが他の入力に対しては機能しないものを持つことができます。

私は時々新しいプログラマーを指導しましたが、ランダムなものをタイプして、それが機能するかどうかを確認する傾向があります。彼らは線をタイプしてから、私に向かって「このように機能しますか?」と尋ねます。一方、彼らがそうするかどうかについてはまったく手がかりがないことは明らかでした。

重要なことは、新しいプログラマーとして、コードが何をするのかを本当に説明できなければならないということです。コードを書くだけでなく、コードを読むことを学ぶ必要があります。

(もちろんそれはベテランのプログラマーにも当てはまりますが、ここでの私の経験は主に完全な初心者です。)


<<コードを書くだけでなく、コードを読むことを学ばなければなりません。>>私の最初の質問について、オープンソースプロジェクトに機能を追加するのに役立つと思いますか?
py_script

2

「レーシングライン」でコーディング、テスト、修正するのは非常に簡単です。XとYを与えてZを生成する機能があります。しかし、Xが破損し、Yが使用できない場合はどうでしょうか。Zを出力できない場合はどうしますか?何が間違っているのかを常に念頭に置き、テストサイクルのためにそれを書き留めます。

ルーチンを短く、わかりやすいものにしてください-最適なコードには、コメントはほとんど必要ありません。

意味のあるメソッド名、クラス名、変数名は、読みやすさの向上に役立ちます。

コードの匂いに出会ったら、やめてください。その匂いが消える可能性は低く、今は少し努力すれば、後で大きな悲しみを救うことができます。

開発プロセスにテストを含めます。TDDではなくBDDを使用することをお勧めします。これは、誤った安心感を与える可能性のある一連のテストに盲目的に頼るのではなく、達成することを目指していることを説明することを強制するためです。

特別なクールな機能を追加する衝動に抵抗します(それがあなた自身のペットプロジェクトでない限り)。余分なコードは、設計、作成、テスト、および保守する必要があります。クライアント/ビジネスで必要とされていない場合、これがリソースの膨大な流出になるリスクがあります。

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