web-dev-qa-db-ja.com

計画を立てるか、プログラムを書いているときにプログラムを理解する必要がありますか?

今日、ポール・グラハムの本「ハッカーと画家」について考えていました。より具体的には、 これらの2つの段落

「私は大学で、コンピューターに近づく前に完全に紙の上でプログラムを理解する必要があると教えられました。私はこの方法でプログラムしないことがわかりました。コンピューターではなくコンピューターの前に座ってプログラムするのが好きであることがわかりました。さらに悪いことに、私は辛抱強く完全なプログラムを書いてそれが正しいことを確信するのではなく、絶望的に壊れたコードを吐き出し、徐々に形を整えていく傾向がありました。デバッグは、一種の最終パスであり、タイプミスや見落としを見つけました...プログラミングはデバッグで構成されているように見えました。

...私が知る限り、彼らが大学でプログラムすることを私に教えた方法はすべて間違っていました。作家や画家、建築家と同じように、プログラムを書いている最中にプログラムを理解する必要があります。」

それが私の大学で教えられている方法であり、私は他のほとんどの大学も同様にかなり確信している。あなたはあなたのプログラムが何をするかを理解し、それからその方法を理解し、そしてあなたはタイプしてデバッグします。基本的なバージョンを作成して機能を追加することもありますが、考えてからタイプするという考え方です。

このようなことは、ファインマンの本の「彼はラジオを考えることで解決する!」と呼ばれる本の章を思い出させる。彼はラジオがどのように壊れるかを考えてペースを調整し、それを修正しました。私にとって、それがプログラミングの目的です。考えてから解決策を見つけることです。

これはコーディングに対する一般的なアプローチですか?もしそうなら、なぜそれがどのようになるかという先入観を持たずに、ハッキングしてプログラムを組み立てる人が増えないのはなぜですか?

Think&type対spew&beatの長所と短所は何ですか?

56
BlackJack

これは、除外された中間の誤りの完全な例です。はい、実際のキーボードに触れる前にプログラム全体を紙に書くことは悪い考えです。しかし、それは反対の極端なものにはなりません-すぐにコーディングに飛び込み、ハッキングを開始します-良いアイデアです。実際、それはさらに悪いことです。

書き始める前に、何を書こうとしているのかを理解することが非常に重要です。職場で実装する新機能を入手したら、作業を始める前に必要なことを説明した仕様を用意しておきます。私はそれを見直し、そこに意味のない何かがある場合は、仕様を作成した人々と話し、合意に達するまで問題について取り組みます。時々私は要件を理解していなかった、そして彼らは私をまっすぐにすることができます。 PM人々は技術的な詳細を理解していなかったため、仕様を変更することになります。

これを行った人なら誰でも、個人的な経験から、実装の途中でコードの問題を見つけ、それをすべて取り除き、別のものに置き換えるよりも、仕様の問題を修正する方がはるかに簡単であることがわかります。 。そのため、コードの記述を開始する前に、記述内容について計画を立てることが非常に重要です。

70
Mason Wheeler

ミケランジェロがシスティーナ礼拝堂の頂上に登り、描き始めたばかりだと思いますか?テスト図面が作成されました。教皇からの承認が必要でした。建設する足場がありました。他のアーティストのグループをガイドするために作成されたテンプレート。修復はさらに複雑でした。

アプリケーションを構築したいが、他の誰かの頭の中のデザイン設定を考慮する必要がない場合は、コーディングを開始するだけです。間違った方向に進んだ場合は、考えを変えてください。とにかくその機能は欲しくない。

画家または作家に委員会に座らせます。 「ああ、先に進んでメインキャラクターを女性にしてください。後で気が変わったら、お知らせします。そして、WTFを、30ではなく20フィートにします。50のスペインガレオン船を追加できますか?明日の除幕前のユニークな漕ぎ手?」

36
JeffO

バランスの形成がすべてだと思います。すべてを入力する前にすべてを考えることは不可能です。そのため、ウォーターフォールモデルは非常に壊れています。同時に、あまり考えすぎない場合、最初の数回の反復を通過するときに、自分自身に大きな混乱を引き起こす可能性があります。結局のところ、すべてのコードを完成させることはできません。プロジェクトの途中で書き換えを必要とする基本的な要件を見落としていたとしても、それは非常に残念です。

開発プロセスでは一定数の反復が必要です。これは、Waterfallが見落としているものです(1つの完全な反復を想定しています)。アジャイル(または「アジャイルのような」方法論の広範なグループ)は、各反復に特定の量のオーバーヘッドがあることを見落とし、各反復を通じて多くが得られない場合、合計反復数が増加し、そのオーバーヘッドが加算されますかなりのコストに。

22

類推の前提は間違っています。多くの作家は、執筆を始める前に何を書こうとしているのかを概説したり、少なくとも考えたりします。多くの画家や建築家は、実際の「仕事」を始める前に何十もの研究やスケッチを行います。

アナロジーが間違っていることを考えると、答えはイエスです。プログラマーは作家、画家、建築家のように働くべきです。

22
Matthew Flynn

私は、美術と美術の二重の専攻で、絵画とウェブデザインを行っていました。彼と私はワークフローについて多くのメモを比較しました。絵を描くとき、​​絵を描くときに絵を理解するだけではありません。彼が事前にできることはいくつかありました。コラージュタイプの絵画の場合、彼はスケッチを描くかもしれません。フォトリアリスティックな絵画では、鉛筆で主要な形状をスケッチし、詳細にペイントしました。しかし、彼が望んでいたものを正確に知っていれば、これらの援助は必要ありませんでした。彼はちょうど描いた。

きっと似ていると思います。問題の適切な解決策を見つけるために、さまざまな方法を使用しています。テクノロジーをよく知らない場合は、少しハッキングして、最終的なソリューションがどのようになるかを理解します。大規模な製品は、大局的な設計セッションの恩恵を受けることが多く、詳細は後で記入されます。また、必要なものが正確にわかっている場合もあるため、コーディングするだけです。私たちが怠惰だからではなく、経験と考えにより、追加のツールは必要ないからです。

前もって設計することのいくつかの利点:

  • 全体像が見えます。
  • 何もせずに、いくつかのデザインを反復処理できます。すでにコードを記述している場合、大規模に方向を変えることはできません。

コードにジャンプする利点:

  • マイクロレベルでは、One True Parserに落ち着く前に、多くのことをすばやく試すことができます。
  • 設計ブロックを壊すのに役立ちます。たとえば、特定のオブジェクトモデルを決定できない場合は、少しのコードを作成して、それがどのように適合するかを確認できます。

この質問への答えは、プログラミングにおける多くの人への答えに似ています。それはプロジェクトによって異なります。設計の監査証跡が必要ですか、プロセスはあなたとあなたの仲間の開発者があなたが必要とする決定を完全に理解するのに役立ちますか?プロジェクトが完全に正しいことが重要ですか、それともいくつかの欠陥を後で発見して修正できますか?あなたの時間枠はどのようなものですか?問題にどんな経験をもたらすことができますか?そして最後にあなたが解決しなければならない問題を完全に理解していますか?

現在私にとって有効なのは、紙の上で全体像を前もってデザインすることです。これは、アプリケーションの主要な部分とそれらがどのように通信するかを説明します。通常、私はオブジェクト図と、よりトリッキーなセクションのフローチャート/擬似コード/実際のコードを描画します。次に、一度に1つのセクションずつジャンプします。モデルの欠陥が問題を引き起こしている場合は、いつでも設計仕様に戻って、その領域に合わせて修正することができます。また、適切な事前設計を変更しても、通常は少しだけ変更が必要になるわけではありません。

9
Michael K

私はあなたが鉄道模型を組み立てるのと同じ方法でプログラムするように教えられました。

鉄道模型を作るときは、線路を1本敷き、線路にエンジンをかけます。移動したら、次のトラックを敷いて、エンジンがそのトラックに移動するかどうかを確認します。ループが完了するまで続行し、エンジンもループを完了します。

この鉄道模型の作成方法の利点は、エンジンが停止した場合、どの線路が問題であるかがはっきりわかることです。あなたが置いたばかりのもの。

プログラミングも同様です。分析と設計を行う必要がありますが、ある時点で、軌道に乗る必要があります。最初のイテレーションはダミーモジュールに過ぎないかもしれません。プロジェクトが異常終了せずに実行される限り、問題ありません。

一度に1つのメソッドを(理想的には)追加するか、何かを実行するためのメソッドの最小数を追加します。毎回、エンジンが動くかどうかを確認します(プロジェクトは異常終了せずに実行されます)。

トラックを敷設しているときに、追加のサイディング(いくつかの追加のメソッド)が必要であることに気付く場合があります。デザインを根本的に変更していなければ問題ありません。デザインを根本的に変更している場合は、コーディングを停止します。コーディングを再開する前に、少し時間をかけてデザインについて考え、デザインを変更してください。

トラックの最後の部分を配置した(最後のメソッドを終了した)とき、プロジェクトは異常終了せずに実行されます。あなたはずっとテストしてきたからです。モデルの鉄道ビルダーのように。

8

アクションに対する思考の比率は、問題の複雑さからドメイン、最終目標まで、さまざまな変数に依存します。プログラムを "ハック"できる場合と比較して、どれだけ多くの思考と計画が必要かを事前に把握するための単一の万能のアプローチはありません。

複雑な問題がある場合や、生命やミッションクリティカルな何かに取り組んでいる場合は、問題を理解し、解決策とトレードオフについて事前に検討することに時間を費やす必要があります。テクノロジー、ライブラリ、またはフレームワークをすばやく学習したい場合は、使い捨てのプロトタイプ環境ですぐに始めて、間違いを犯すことが最も効果的です。その他のオプションには、進化的なプロトタイピングが含まれます-完成した製品に作品を進化させることができるように十分な思考と設計が含まれますが、片道で制約を受けるほどではありません。

4
Thomas Owens

@Thomasが述べたように、万能のソリューションはありません。コンピューティング能力とメモリが豊富なこの時代において、私たちが直面している問題のほとんどは難しくはないので、ほとんどすべてのアプローチで適切な解決策が得られます。ただし、コードをすぐに記述して、その場で解決策を見つけようとすると、惨めに失敗する可能性のある領域がまだあります。

たとえば、私が取り組んだ1つのアプリはモバイルネットワークの分析でした。スーパーコンピュータではなく、単なるデュアルコアラップトップで実行されることが想定されている、数十の異なるネットワークレイヤーにまたがる数千のノードのネットワークを分析するためのコードを記述する必要がある場合、人類が以前に知っていた最高のグラフアルゴリズムを見つける方がよいでしょう。コードを書き始めます。代わりの方法は、開発の半年後、アルゴリズムが10ノードのテストネットワークに正しい結果を提供するものの、O(n4)したがって、ユーザーが現在取り組んでいる実際のネットワーク計画を入力すると、ユーザーのラップトップで2年後に終了します...

2
Péter Török

それがどのようになるかという先入観を持たずに、ハッキングしてプログラムをまとめる人が増えないのはなぜですか。

多くの人の人々は、自分のキャリアを通じてそれをしています。このサイトは彼らの質問でいっぱいです。他のアフィリエイトサイトには、作成したソフトウェアを使用しようとする他の人々からの質問がたくさんあります。

あなたがそれを置くように、ちょうどコードを噴出する種類の人々は、しばしば「コードはそれ自身のドキュメントです」のようなものを言うでしょう。コードはnotドキュメントです。コードは意図を実証するものではなく、意図として覚えているもののいくつかのバージョンに加えて、途中で興味を持ったものの束であり、そのうちのいくつかは役に立たないことが判明しましたが、時間を割くことができませんでした削除する。ああ、そしてあなたが2晩眠れなかったけれども、プロジェクト全体に革命をもたらす多くのカフェインを持っていたという驚くべきアイデアは、それがどのようにコンパイルされているかはもちろん、コンパイル方法さえ知らないだけです削除するとどのような影響がありますか。

ある種の設計ドキュメントがなければ、最小限ではありますが、共同編集者(または後継者)はどのビットを拡張し、どのビットを削除するかをどのように指示しますか?そのドキュメントは最初に作成する必要はありませんが、任意のサイズと価値のあるプロジェクトの場合、いつかは発生する必要があります。

Spew-and-refactorは、ある時点まで(そしてその時点がどこにあるかについての優れた判断者である人は知っておく価値があります)、ソロプロジェクトで機能します。チームにとってはあまり実用的ではありません。仕様についての最小限のコンセンサスなしで、人々はどのように効率的に並行して作業しますか?アジャイル方法論は、主に人々のコーディングに対する熱意を失わずにその問題を解決する試みです。

2
itsbruce

一般に、プログラミングは抽象化の練習です。したがって、特定のソリューションを過度に実現しようとすると、間違いなくあなたの努力の範囲が誤って判断されることになります。

あなたは、複雑さを判断するのが得意ではありません。私を信じてください、あなたはそうではありません。

最良のコードは、達成したいことの概要から始まり、チャンクで繰り返し成長します。継続的なコードの構築。プロジェクトの計画段階では、座ってプログラムが実行しないことをリストする方がはるかに便利です。そうすれば、少なくともあなたはいまいましい海を沸騰させることに屈することはありません。

http://en.wikipedia.org/wiki/On_Exactitude_in_Science

1
splicefracture

ワークフローはプログラマごとに非常に個別だと思います。最適な方法を使用してください。

私は、個人的には、通常、白紙と鉛筆(または私が持っている場合は非常に大きなホワイトボード)から始めます。私は最初にクラス図と関係を描きます。次に、基本的な構造が完成するまで調整します。この段階でステートマシンも作成します。この時点では、コードやクラスは考えられておらず、クラスと関係のみが記述されています。

さて、これは単なるスケッチに過ぎず、クラスのプログラミングを開始するときに、さらに多くの設計上の問題にぶつかります。次に、ホワイトボード(または紙)に戻って新しい問題を解決します。これは、元のデザインの一部を引き裂くことを意味します。

これは、Agile designの仕組みにも似ています(注記[〜#〜] similar [〜 #〜]これについて文句を言うあなたすべてに)。この方法を使用してプロジェクトの進行状況を追跡する方法については、全体的な科学があります。これは、新しいタスクの数が最初に加速し、プロジェクトの終わりまでフェードインする必要があるためです。

アイデアは、コードと設計を繰り返すことです。以前の会社(開発者130人)でこのプロセスを使用しましたが、うまく機能します。また、Doxygenを使用して、コードからクラス図と関係図を作成しました。これは、実際にコーディングされた設計の概要をすばやく把握し、欠陥や欠落している関係を見つけるための迅速な方法でした。

これでうまくいくかどうかはわかりません。あなたは何があなたにとって最も効果的かを試してみなければなりません。

0
Max Kielland

私も2セントでチャイムを鳴らします。

開始する前に完全なプログラムを紙に書くことは、Hello Worldで機能する「CS 101」演習です。しかし、達成したいことを考えるのに時間をかけずにコードを吐き出すことも、時間の無駄です。

これらの2つの両極端の間で、ハードウォーターフォール(拡張仕様のセット、最後にほとんど1つの出力)からアジャイル(リリース間のターンアラウンドが非常に速く、「顧客」ダイアログが常に続く「軽量」仕様)まで、ソフトウェア手法の全範囲があります。 )。

いずれの場合も、方法論に関係なく、始める前に何を構築しているかを知る必要があります。これは、プログラムのアーキテクチャを組み立てるのに役立ちます。ウォーターフォールでは、コーディングを開始する前にシステム全体のアーキテクチャを構築することに重点を置き、最終的に何が得られるかを理解できるようにします。アジャイルは、「次の反復で達成される最小の機能を指定する」ことに重点を置き、絶えず再設計する準備ができるように警告します(適切なテストスイートなどを作成して、実際にそのような作業を実行できるようにします) )。

方法論は何も考えずにコーディングを開始するように指示するものではないことに注意してください。実際、何をしようとしているのかはかなりよくわかっているはずです(Waterfallを使用する場合は全体で、Agileを使用する場合は小さい領域で)。 「何を」しようとしているのかではなく、「どのように」あなたが何かをしているのか、いくらか即興を行います。

演技のレッスンを受けたときに、あなたが学んだことと同じものを描くことができます。 1つの大きな部分は「改善」です。即興を始めるときは、できるだけ小さな石を用意して、誰かがシーンを別の方向に導いた場合にアイデアを放棄する準備をする必要があります。優れたリスニングスキルが必要で、他の人の命題を受け入れる必要があります。主なことは、登場人物の状況、おそらく伝えたい感情、そしてシーンを撮りたい方向性でステージに上がることです。しかし、アイデアがシーンから最も遠いほど、どこか別の場所に行き着く可能性が高くなります。結局のところ、これは非常に「アジャイル」な考え方であり、これがあなたがここで苦労していることかもしれません。

さて、「コードを書いてみましょう」レベル(仕様、ストーリー、または入手可能なもの)で話している場合、それはあなた次第です。疑似コードを書く人もいれば、実際のコードの前に(「空欄で記入」で)コメントを書く人もいれば、テストを書くことから始める人もいます(テスト駆動開発を参照)。特定の方法で設定したことを達成します。そのレベルでは、ほとんどの人が実際のコードを書く前にある程度考えます。しかし、紙に手書きする前にコードを書き留めるまでは、私にはやり過ぎです...

0
Denis Troller

私はこれが答えられたことを知っていますが、グラハムがすべてのハイレベルな概要やデザインをすべて無視することを意図していたとは確信していません。私は前もって問題について考え、スペックなどを持っていますが、私が同じように作業しているので、彼の言っていることを完全に理解しています。

私にとって「ハッキングアウェイ」は、あなたが何をしようとしているのかではなく、どのようにそれを実行するのかということで生じます。学校では、疑似コードを学び、実際のコードを事前に設計しました。私には、それはばかげています。高レベルの概要、コンパス、そしてハックを取ります。私はコンパイラーでもコンピューターでもないので、すべてのコードについて考えるつもりはありません。また、すべてのコードオンペーパーの結果を前もって理解することはできません。私は、仕様や設計の非効率な、または壊れた実装をハッキングして、そこから「形を整えます」。

0
Bob

ええと、私がpgの発言に異議を唱えるのは誰かですが...最善のアプローチはおそらく個人によって異なると思います。つまり、この時点まで客観的な真実が存在する可能性がある限り、真実はおそらくどこかの真ん中にあります。少なくとも、「前もって計画を立てない」と「すべてを事前に予測する」の二分法を作ることは、誤った二分法だと思います。私の経験では、それは連続です。

個人的には、探索的プログラミングスタイルと「それを想像してみる」ことに傾倒していますが、私のお気に入りのプログラミングツールの2つは、アーティストのスケッチパッドと色鉛筆のセットです。座って高レベルの関係をスケッチし、物事を視覚化して物事がどのように組み合わさるかを理解するのに役立つ時間と場所は間違いなくあります。まあ、私のためにあります。

繰り返しますが、これは個人に大きく依存していると思います...また、問題の領域とプログラムの固有の複雑さにも依存します。つまり、単純なコマンドライン計算プログラム(たとえば、「貧乏人のbc」と考える)は、おそらくERP 30,000人の従業員企業のシステムよりも)事前計画が少なくて済みます。

0
mindcrime

義務的なハンターS.トムソンの引用 しかし、それは常に私のために機能します

何を達成したいのかが明確で、コードを構造化する方法を知っていて、優れたコーダーである場合は、コードを記述するだけのほうが速いことがよくあります。

0
James Anderson