web-dev-qa-db-ja.com

コードの機能を完全に理解しなくても大丈夫ですか?

現在、作業中のプロジェクトのWCFの学習に苦労しているため、過去数日間、WCFクライアントを作成するための最良の方法についてオンラインチュートリアルと例を見てきました。そして今日、私が上司に言ったとき、私は良いチュートリアルを見つけるのに苦労していました。彼らの一部は彼らの例では詳細に行きませんでした(例えば、機能するが正確に理由を説明しないコードの一部を示す、または例で作る)より大きなスケールの代わりに数行だけ)、彼は私がそれらを完全に理解しようとするべきではないことを私に言った、それはコードがそれが何をするかだけであり、私はそれのままにしておく必要があるときがあるからだ(彼は私に与えたたとえば、微積分を行う場合、それらがどのように考え出されたのか、またはどのように機能するのかわからない式を使用することを例にとります。

そして、私は常にあなたのコードを理解することが本当に重要であり、それがどのように機能するかを知らずにコピーして貼り付けることは実際には罪であると常に言われているので私を悩ませました。そのため、私は常に何かを理解することに時間をかけてから、それを進める前に取り組んでいます。そして、特定のクラスがアセンブリ言語レベルでどのように機能するかを理解しようとしているのではなく、なぜ一連の命令がうまく機能しないのか、なぜ別の命令が機能しないのか、なぜ両方が機能しないのか、そしてなぜ状況。しかし、上司は私にこれらの細部に取り付かれる時間を浪費することになると私に言ったので、私はそれをスキップするべきです。だから私の質問は、彼は正しいのですか?あなたのコードをある程度まで理解して続けても大丈夫ですか、そして私は重要でない小さなことだけにこだわっていましたか?

83
Ana Ameer

ソフトウェア抽象化の唯一の目的は、機能の詳細を隠すことです。これらの抽象化がなければ、コンピューティングの特定のポイントを超えて進むことはできません。なぜなら、システムは単にそれら自身の複雑さの重みの下で崩壊するからです。人間の脳は一度に多くの情報しか理解できません。

メソッドを作成するとどうなるかを考えてみましょう。メソッドを書くとき、あなたがしていることは、メソッド呼び出しの背後にあるソフトウェア機能の一部を隠すことです。そのメソッドが記述され、そのメソッドに関する単体テストを書くことで機能することが証明されたら、その実装について何かを変更する必要がない限り、メソッドの内部に何があるかを考える必要はありません

大規模なソフトウェアシステムは、これらの抽象化の多くのレイヤーに基づいて構築されています。プロセッサ、マシンコード、アドレスおよびデータバス、言語コンパイラにマイクロコードレイヤーがあります。オブジェクト指向、データ構造、ドメイン固有の言語など。他のライブラリの上に構築されたライブラリがあり、それらはオペレーティングシステムの上に構築されています。あなたはそれらのいずれかがどのように機能するかを完全には理解していませんが、それでも、何か有用なことをするコンピュータプログラムを首尾よく書くことができます。

それは言った...

どのように機能するかを理解せずにコードをコピーして貼り付けることはできません。理解できない貼り付けコードをコピーしてプログラムを動作させようとする人は、失敗するように設定しています。 作成するコードを理解する必要があります。これは、WCFが内部でどのように機能するかを知っている必要があるという意味ではありませんが、する必要がありますWCFの目的、WCFを適切にインターフェイスするコードの記述方法、および記述したコードがそれと連携して機能する方法を知る必要があります。多くのコピー/貼り付けのプログラマーは、コピー/貼り付けしているプログラミング言語を十分に理解していないだけでなく、使用しているライブラリーの詳細な知識も持っていません。

したがって、ある程度のスキルが必要であり、WCFを呼び出すコード(または貼り付け)を理解する必要があります。 しかし、WCFが内部でどのように機能するかについての深い知識は必要ありません。

同様に、ソフトウェアパターンをランダムに接続することでプログラムをつなぎ合わせることができると考えるプログラマは、ポイントを逃しています。それらを Cargo Cultプログラマー と呼びます。

124
Robert Harvey

答えは文脈だと思います。

コードの複雑さを管理するための最も強力な手法の1つは、私の考えではソフトウェアエンジニアの本当の仕事ですが、抽象化です。電気技師は新製品を開発するためにマクスウェルの方程式を解く必要はなく、ステアリングホイールを使用するために車について何も知る必要はありません。どちらも、理解せずに直感的に使用できるため、重要な抽象概念です。これにより、より大きな抽象化を構築できます。

余談ですが、抽象化は非常に重要であるため、他の開発者にそれを強制することも時には良いと思います。たとえば、私のオフィスでは、2人目の開発者がコードブロックを作成する前に、1人の開発者がコードブロックの単体テストを作成する場合があります。シンプルなインターフェースと明確な抽象化の考え方を強化します。

つまり、抽象化は、コードがどのように機能するかを理解することが重要な場合に、コードがどのように機能するかを理解できない言い訳にはなりません。コードのリファクタリングは、実装の詳細がかなり重要になる明らかなシナリオです。私はそれを運転するために車がどのように機能するかを知る必要はありませんが、機械エンジニアと整備士は両方とも、おそらく異なる方法で車がどのように機能するかを理解する必要があります。

もう1つ余談ですが、この仕事に関する最初のレッスンの1つは、本当に理解していないコードには絶対に触れないことでした。たとえば、私はかつて新機能に取り組んでいて、モジュール内の別のコード行が意味をなさないことに気付いたので、「修正」してバグをリリースしました。それは私にかなり大きな教訓を教えてくれました。それは、コードの一部を容易に理解できないときに認め、優れた複雑で重要なコードは自明ではない可能性があることを認識することです。私はソフトウェア開発に非常に慣れていませんが、「良いコードは読みやすい」という考えは、私が知っているソフトウェア開発者が実際に実践している潜伏的なものであることがわかりました。確かに、あいまいなコードや悪いコードを記述しないでください。しかし、難しい問題では、しばしば複雑なコードが必要になります。物事を理解するのに時間がかかるのであれば、怒らないでください。私のお気に入りのファインマンの言葉は、「しかし、それは複雑ではありません。たくさんあります。」

では、いつ抽象化し、いつスイスの時計を分解しますか?それはあなたが時計をいつ着用しているのか、そしてあなたがそれを組み立てているのかに依存すると思います。私の意見では、どの分野でも最高の人は T字型 であり、より大きなコンテキストで作業を理解しているということです。つまり、抽象化によってのみ達成されるものですが、深く知る必要があることも知っています。 。

34
gwg

ソフトウェアを理解するには、3つの部分があります。

  1. まず、理解なぜソフトウェアの一部(アプリケーションと同じくらい大きいか、単一の関数と同じくらい小さい)が存在します。あなたはそれのポイント、なぜそれが書かれたのかを知る必要があります。
  2. 次に、コードの一部が理解するwhatを理解すると思います。
  3. 最後にhowコードの一部が機能すること、それが内部的にどのように動作するかを知っています。

ソフトウェアを理解するために把握する必要があるのは、そのコードをどのように処理するかによって異なります。

たとえば、.NETのString.ToUpper()メソッドを使用します。私はこのメソッドが何をするのか、なぜあなたがそれを使いたいのかを知っていますが、それがどのように書かれているのか(それは実装の詳細です)、私は本当に気にしません-私が適切に使用できる限り。このメソッドを変更する必要はないので、内部を理解する必要はありません。

インターネットからコードをコピーしていた場合は、コードの機能と理由を完全に確認する必要があります。私がそれを単にコピーしていて、決してそれを変更していない場合は、それがどのように機能するかを理解する必要はないと感じています。しかし、それを(おそらく)変更するつもりなら、それがどのように機能するかを知る必要があります。それ以外の場合は、当て推量を使用してコードを変更しているだけで、おそらくうまくいきません。

19
Jack Scott

私が他の答えに同意しないというわけではありませんが、私が線の間で読んだものに応答させてください。上司が何かがどのように機能するかを理解する必要がないことをアドバイスしている場合、何かを成し遂げるのに時間がかかりすぎるというフィードバックがあるかもしれません。一部の人々は、重要でない詳細に気を取られてしまいます。彼らにとっては、軌道に乗ることに取り組むことをお勧めします。

一方、プログラミングがあなたの選択された職業であり、あなたがあなたの仕事にとって重要であるいくつかのテクノロジーをより深く掘り下げることへの知的好奇心を持っているなら、私は可能な限りあなたの興味を追うために少し時間を取ることをお勧めします。あなたが得た洞察は、すぐに報われるわけではありませんが、長期的には利益をもたらします。これは、テクノロジーを理解し、多くの場合それを拡張する立場にあり、将来さらに深い理解ができるよう準備するのに役立ちます。時間が経つにつれて、これが専門家をカジュアルユーザーと区別するものです。

14
Paul Jackson

素晴らしい本の実用的なプログラマーでは、これは「偶然のプログラミング」と呼ばれています( http://pragprog.com/the-pragmatic-programmer/extracts/coincidence

これに関するより大きな問題は、このコードが何らかの理由で失敗したときに、そのコードが機能する理由がわからない場合、失敗する理由がわからず、修正できないことです。

6
AlfredoCasado

「コードの仕組みを理解しないと、コードをコピーして貼り付けることはできない」とは、完全に同意しません。

私の愚かさは許しますが、プログラムの観点からは、コードが自分のコードにコピー/貼り付けするのと本質的に同じように機能することがわからないメソッド/関数のライブラリを含めていませんか?

つまり、jQueryを使用してプログラミングしている場合は、jQueryライブラリを含めて使用します。 Robert Harveyの答えを使用すると、jQueryは自分でコードを記述したり、コードを完全に理解したりすることなく、使用する必要のあるものすべてを抽象化したので、これで問題ありません。 jQueryを使用する前に、舞台裏でjQueryがどのように機能するかを正確に知る必要がありますか?

そうは言っても、私は声明の背後にある原則に同意しますが、「完全な理解なしでの」コードの「コピー/貼り付け」の概念は実際には一般的なものであり、この声明ほど複雑ではありません。みたいだ。

3
reblevins

ほとんどの場合、それはすべて依存します。端的には、ライブラリの使用があります。あなたはそれがどのように機能するかを知っていたり気にしたりするべきではありません。何を入れて何が出てくるか、何ができるか、何ができないかを知っているはずです。

もう一方の端では、以前に実行したことがないため、いくつかのタスクを実行する方法がわかりません。インターネットで10行のコードを見つけます。これは、ドキュメントで適切な情報を見つけるよりも簡単に思えます(多くの場合そうです)。その時点で、私はnowがそのタスクの実行方法を学ぶのに適切な時期であることを強くお勧めします。したがって、コードを取得して理解し、独自のものにします。インターネット上の多くのコードが必ずしも利口な人によって書かれているわけではないので、弱点や誤解があるかもしれないことを理解してください。そこで学ぶことで、コードが機能することを確認できます。そして、プロジェクトにこれらの10行を含める時点で、それらはyourの責任です。コードが機能しない場合、それはあなたの責任です。まるでそれを書いたかのように、あなたはそれを理解しなければなりません。

では、ライブラリとの違いは何ですか?それもあなたの責任ではありませんか?ライブラリのコードはそうではありません。ライブラリのchoiceとライブラリの使用法は次のとおりです。ライブラリが1日に10回アプリケーションをクラッシュさせるのは、信頼できないライブラリを選択したためです。ライブラリのコードを理解する必要はありませんが、その信頼性の問題を理解して行動する必要があります。

2
gnasher729

上司のアドバイス可能性がありますうまく機能しますが、危険です。長期的にはより大きな問題に直面する危険があり、時間をかけて最初に物事を理解することでそれを回避することができます。これが1回限りの場合、リスクは比較的小さいです。この方法でソフトウェアシステム全体を構築すると、時限爆弾が発生します。理解していないことは、バグを引き起こさずに修正または変更する見込みがないことです。

一方、上司に逆らうと、自分の仕事が危険にさらされる可能性があります。仕事が好きなら、将来的には、技術的な問題を解決してから、彼が関与する必要があります。私はかつて、技術的な決定に関与するたびに物事を台無しにしてしまう上司がいました(ただし、彼は営業および顧客関係で優秀でした)。ほとんどの技術スタッフは、自分の言うことに耳を傾け、それから振り向いて別のことをすることを学びました。ソフトウェアが機能している限り、彼はフォローアップを行わず、技術的なアドバイスが実際に実装されているかどうかを確認しませんでした。仕事はうまくいきましたが、もういなくてよかったです。

この態度があなたの職場で広まっているなら、私は少なくとも他の仕事の選択肢を検討します。

1
Alex D