「賢い」コードを書かないように自分を訓練する方法は?[閉まっている]


75

s で新しいトリックを披露したり、3つの異なる手順を一般化したりする必要があるときの気持ちを知っていExpressionますか?これはArchitecture Astronautの規模である必要はなく、実際に役立つかもしれませんが、他の誰かが同じクラスまたはパッケージをより明確で率直な(そして時には退屈な)方法で実装することに気づかずにはいられません。

私はしばしば問題を過剰に解決することによってプログラムを設計することに気づきました。時には故意に、時には退屈から。どちらの場合でも、反対の証拠を見るまで、私のソリューションは非常に透明でエレガントであると正直に信じていますが、通常は手遅れです。また、コードの重複よりも文書化されていない仮定を好み、単純さよりも賢いことを好む私もいます。

何をするために行うことができ、「cleverish」のコードを記述する衝動に抵抗してたときにベルリングをすべきであること、私はそれは間違ってやっていますか

私は今、経験豊富な開発者のチームと協力しているため、問題はさらに押し進められています。スマートコードを書くという私の試みは、時間が優雅さの幻想を払拭した後でも自分にとっては愚かに思えます。


5
トピックから少し外れていますが、thedailywtf.com

@ジョー:これは非常に話題です、ありがとう!私は記事を読みましたが、今それを再発見できてうれしいです。
ダン

33
巧妙なコードをたくさんデバッグしてください...これでうまくいくはずです。
ダン・オルソン

@Joeは、その記事のデータベースリンクのデータベースが死ぬことになっています。
jnewman

短い答え:最短で最も単純なコードが勝ちます。重複を排除しますが、「理由」だけでレイヤーを追加しないでください。ファウラーのリファクタリングは洞察を与えるかもしれません。
ケビンクライン

回答:


54

私は今、経験豊富な開発者のチームと協力しているため、問題はさらに押し進められています。スマートコードを書くという私の試みは、時間が優雅さの幻想を払拭した後でも自分にとっては愚かに思えます。

あなたの解決策はここにあります。この文脈で「経験した」とは、「あなたよりも経験が豊富」を意味すると推測しています。少なくとも、あなたは明らかにそれらを尊重します。これは貴重な学習の機会です-あなたのエゴがヒットすることを前提としています。(面倒なもの、エゴ。私たちがそれらを必要とするのは残念です。)

これらの人々とコードレビューはありますか?もしそうなら、彼らはまだそれをしていない場合、あなたのでたらめであなたに電話するように明示的に依頼してください。シンプルな爪ハンマーで十分すぎる場合に、細心の注意を払って設計された最上位の空気圧式ジャッキハンマー(何らかの自動ロードワーカーAndroidを使用することが望ましい)を使用するという過剰設計の傾向に気づいたことに言及してください。

コードレビュー中に顔が赤くなると、座席で身動きが取れなくなることがよくあります。耐える。あなたは学んでいます。

次に、これらのいくつかを手に入れたら、おそらく過剰に設計していると思われる瞬間に注意を払ってください。これらの瞬間が来たら、「コードレビュー中に誰かが私にこれを呼びかけたら、私のソリューションを最高のソリューションとして擁護できますか?または、私が見捨てているもっと簡単なソリューションはありますか?」

時々、ピアレビューはあなた自身の仕事をよく見るための最良の方法です。


本当に良い答えをありがとう。いいえ、主にプロジェクトが大きく、顧客のリソースが非常に限られているため、コードレビューはありません。しかし、毎日の終わりに「自分のソリューションを最高のソリューションとして擁護できますか」と尋ねることで、自分自身をテストできると思います。
ダン

7
コードレビューはありませんか?ウルク。私はすべて独善的で恐ろしいものを書きますが、私はその環境でも働いています。それらは時間のかかるものであり、すべての人の苦痛の種ですが、手元のプロジェクトとあなた自身の個人的な開発の両方にとって本当に貴重です。「コードレビューを行うべきでしょうか?」表示されたら、「地獄はい!」そして、彼らが彼ら自身の迫り来る締め切りに非難されていないなら、あなたはあなたが尊敬する同僚に、あなたが非公式のコードレビューライトについて確信を持っていない仕事をするよう頼むことができます。
BlairHippo

1
まあ、プロジェクトは一種のスタートアップであり、クライアント側でもいくつかの計画ミスのために、私たちは本当に迅速に配信する必要があるか、そうでなければ努力する価値がないときに状況に陥ります。私は私たちのPMに話しましたが、彼は積極的な締め切りが、少なくとも今のところコードレビューを行わない唯一の理由であることを確認しました。スタートアップが成功し、時間の制約がより緩和された場合、今後レビューを行う可能性があります。
ダン

2
あら エキサイティングに聞こえます-言葉が持っているすべての良い意味と悪い意味合いがあります。:-)幸運を祈ります。あなたが素晴らしい何かの始まりにいることを願っています。
BlairHippo

8
@BlairHippo:私はあなたのアドバイスに従い、落ち着いて、私の変更によってもたらされた問題を指摘した同僚に私と非公式のレビューをするように親切に頼み、彼は同意しました。これは、会話から特定の厄介さを取り除くのにも役立ちました(「複雑なコードを書いて修正する必要があります」など)。ありがとう!
ダン

20

最善の方法は、Brian Kernighanの格言に留意することです。

「デバッグは、最初にコードを書くよりも2倍難しいです。したがって、コードを可能な限り巧みに記述すると、定義上、それをデバッグするのに十分ではありません。」


1
私は心から引用に同意しますが、問題は賢い少年になる誘惑をどのように克服するかです。病気のときはアイスクリームを食べないように言われることもありますが、助けにならないこともあります。
ダン

13
すべてのコードモンキーが心で知っておくべき格言については+1ですが、OPにそれを自分の作品に適用する方法についての洞察を提供していないことについては-1です。したがって、矢印をクリックすることなくすべて均一になります。
BlairHippo

2
素晴らしい引用ですが、OPの質問に対する答えではありません。
ジムG.

5
こんにちはダニエル、私たちは引用よりもはるかに多くを探しています:サイトは、質問が経験、事実、および参照で満たされた長く思慮深い答えと組み合わされた場合にのみ有用です。あなた自身の経験から、他に何か追加できますか?

2
-1:OPの質問には少しでも答えません。
トーマスエディング

15

通常、重要なソフトウェアの問題には少なくとも3つの解決策があります。明白な方法、非自明な複雑な方法(賢い)、および非自明な単純な方法(エレガント)です。著者についての引用はここに適用されます:

頭に浮かぶものをすべて書き留めれば、あなたは作家になります。しかし、著者とは、同情せずに自分のものの価値を判断し、その大部分を破壊することができる人です。—コレット

同情せずに自分のコードの価値を判断し、そのほとんどを破壊するまで、エレガントなコードを書くことはできません。最終結果でエレガントなコードを判断すると、一見簡単に見えますが、スローダウン、多くのドラフトを通過し、他の人のアドバイスを求め、ページ上にないものを削除する必要があります。つまり、コードが完全に機能していても、答えに満足するまで、自分または同僚に、なぜ何かが正しくないと感じるのかを尋ねます。おそらく、長すぎたり繰り返したりしていると感じたり、コンパイラが特定の種類のバグを捕らえるべきだったと感じたりするかもしれません。わずかな経験を持つほとんどのプログラマーは、洗練されていないコードを簡単に認識できます。トリックは理由を理解することです。

これは、よりエレガントなコードを書くための系統的な方法です。また、多くの場合、問題を新しい方法で見るのに役立つ洞察のフラッシュが必要です。これを達成するのはより困難ですが、コーディングに飛び込む前に速度を落として問題を考えるのに役立ちます。良い解決策を見つけたら、より良い解決策を探してください。他のコードを読むと役立ちます。クラスを受講したり、ベストプラクティスに関する本を読んだりすると役立ちます。他のプログラミングパラダイムを学習すると役立ちます。尊敬するコードを持っている同僚からアドバイスを求めると役に立ちます。


3
それは古い数学者の引用を思い出させます:「すべての問題には、シンプルでエレガント、そして間違った解決策があります。」
ジョリスティマーマンズ

9

既存の回答に追加し、TDD方式で開発するので、最初にコードの実行内容に関するテストを作成し、次にテストをグリーンにするために実装します。この方法では、テストが課している要件を満たすだけです。テストを作成するので、自己啓発的な開発アプローチへの良い方法です。


私は間違いなく、時間があるときはいつでも自分にこれを押し付けようとします。
jnewman

後でテストを書くことは、コードの大きな間違いを見つける良い方法でもあります。それはどういうわけか自己レビューです。ただし、TDDは、新たに始めようとしている場合、明らかに最適なアプローチです。
ヴァンナ

6

多くのさまざまなスキルセットと年にまたがる大規模でダイナミックなチームで働く場合、開発は、現在または過去のチームの最も保守的または最も知的に欠陥のあるメンバーの最低レベルに「下がって」自然に進行します。

賢いコードはデバッグが難しく、技術仕様を伝えるのが難しく、書くのに時間がかかり、開発時間が遅くなるので、これは必ずしも悪いことではないかもしれません。

賢いコードが重要になる場合があります。たとえば、賢いコードがパフォーマンスを必要とするソフトウェアの成熟サイクルの後半で効率とパフォーマンスを向上させる場合などです。

巧妙なコードは、新しい言語機能やライブラリ呼び出しにさらされていない可能性のあるチームに、より迅速に開発され、より読みやすく、理解しやすいコードを伝える方法も備えています。たとえば、私がジュニア開発者から最初にLinqを紹介されたとき、私は不必要で、デバッグが難しく、愚かで、「賢い」とすぐに嫌悪感を抱きました。自分で遊んで、Linqクエリがどれほど便利で強力なものであるかを発見した後、私はそれを学ぶ時間を費やし、DALコードはこれまで以上にクリーンで読みやすく、デバッグや拡張が容易になりました。

私は以前にオープンマインドを持っていなかったことを後悔しており、そのような「賢い」ジュニア開発者に対してそれほど厳しくないことを願っています。

私の要点は、「賢い」コードは疑わしいべきであるということですが、創造性と革新を妨げる可能性があるので、私たちはそれに反対するべきではありません。

編集:私はあなたの質問に完全に答えていないことに気付きました。あなたのプロジェクトに賢いコードを非常に簡単に書く能力があるなら、おそらくチームはより厳格なコーディング標準を採用して、統一された明確なテンプレートとスタイルに従うべきです。これにより、サンドボックスの線が引き出され、ボールを追いかけて通りに迷い込むことがなくなります。


6

20%(%は異なる場合があります)または追加した行の多くがドキュメントである必要がある場合-戻って考え直してください

私はあなたが賢くなるよう努力するべきだと本当に思います。それはより熟練することの自然な副作用です。自分自身を明確にするために必要なコメントの割合などの一般的なガイドラインを与えることは、学習した新しいものを使用することが賢明な選択であるか、単に新しいおもちゃを誇示するための方法であるかどうかを自分自身に後押しして評価させる良い方法です。


3
私はドキュメンテーション/コメントを失敗と考える傾向があります。何かを文書化/コメントする必要がある場合、そもそもコードが明確でないことを意味します。不幸なことに、これは非現実的な目標であり、ある時点で文書を作成する必要があります。コードのこの部分は最小限に抑える必要があることに注意してください。
deadalnix

@deadalnix:悪い点ではありません。私は通常、そうでなければ死んで非常にマクロ化されたアセンブリ言語でコーディングするため、私の%はほとんどよりも高いと思われます。読みづらく、新しい雇用者は言語を学ぶ必要があり、結果としてより多くのコメントが必要です。
DKnight

2
@deadalnix-あなたのコードが不明確なサインの仕方を説明するドキュメント。理由を説明するドキュメントが非常に必要です。私は彼らが何をしたのか理解できるが、なぜ彼らがその直感的でない方法でそれをすることを決めたのか理解できないコードの断片をすべて見ました。そのため、保守が非常に難しくなります。
HLGEM

@HLGEMこれは議論の余地があります。コードの不明瞭さは、不適切に設計されたlibs / APIに起因する可能性があります。懸念の分離が不適切であるという概念自体の中の不明瞭さに起因する可能性があります。私たちは現実の世界に住んでおり、その能力は有限であるため、明確にドキュメントが必要ですが、必要になるたびに、誰かが不完全なコードを書いたことを意味します。文書化はあなたがすべきことではありません-それについても考えないでください、しかしあなたは正しい方向に改善し続けるために常に考えなければならないものです。
deadalnix

@deadalnix-完全なコードは、現実の世界では決して実用的なソリューションではありません。
JeffO

4

私は何か賢いものを試して抵抗することはできません。

だから、私は自分の時間に、自宅でおもちゃのプロジェクトでそれをします。

目新しさがなくなると、問題は解決しました。


3

コードが「賢い」かどうかを確認する1つの方法は、一歩下がって次のことを自問することだと思います。

このプロジェクト/コードで作業したことのない人にこのコードの印刷物を渡すと、彼らはそれを読んで、機能が何であるかを説明することができますか?そうでない場合、どの程度説明する必要がありますか?CS101を服用している人にこれをどのように説明しますか?

メソッドまたはクラス内のすべての行またはほとんどの行を誰かに説明する必要があることが判明した場合、おそらくあまりにも賢いでしょう。言語構成要素(たとえばLINQ)を、それに慣れていない人に説明する必要がある場合は、おそらく大丈夫です。説明する前に行を見て少し考えなければならない場合は、コードをリファクタリングする必要があります。


問題解決に適用されたとき、これは「ラバーダッキング」と呼ばれています。困ったときは、それについて何も知らない人(ゴム製のダッキーなど)に問題を説明して、解決策が膝に落ちないかどうかを確認してください。これでもうまくいくと思います。
BlairHippo

2

1)悪いことだとわかるように、前もってそれに火傷してください。賢く書かれたものをずっと前からデバッグしようとするのはとても楽しいです。あなたはそれをカバーしていると思います。
2)コードをコメント化し、コードの各セクションの前に何をしているのかを説明します。
3)それを説明するのに苦労している、または図を挿入する必要があると感じたら、あなたがやったことはあまりにも賢く、おそらくもっときれいに行うことができます。

問題の巧妙な解決策は、デバッグや拡張が必要になるまで、素晴らしいものになります。時々それが唯一の解決策です。地獄が何をするのか、どのようにそれを行うのかを正確に説明できれば、賢い解決策は受け入れられるでしょう。

私は通常、コメントを使用して、コードのセクションで行っていることを説明します。混乱が最も少ないと思われる場合は、その方法についても説明します。理想的には、コードは単純明快で自明であるべきです。しかし、私が今やったことをどのようにしたかを説明するのに苦労するなら、それは私が後退して再試行する必要があるという明確な兆候です。


2
コメントトリックは私にも役立ちます。他の理由の中でも、私は常に最終的な健全性チェックの一種として、重要なサブルーチンの上にコメントブロックを常に含めています。コードの複雑なセクションや曖昧なセクション、または奇妙な入力パラメーターなどをたくさん説明する必要がある場合(または、場合によっては謝罪する必要がある場合)、それはソリューションを少し再考する必要がある警告サインです。
BlairHippo

@BlairHippo HA!「最終的な健全性チェック」私はそれが好きです。
フィリップ

2

おそらく簡単なコードを書き始める良い方法は、賢さ求めるプロジェクトに賢さへの情熱リリースすることです。残りの答えは.NET固有のものですが、他の言語でも同様のレベルのプロジェクトを見つけることができると確信しています。

動作するオープンソースの依存性注入フレームワークがあり、Expressionトリックの知識を要求するだけです。F#と、試してみたいタスクの素晴らしい範囲があります。

あなたが数学に興味があるなら(そしてそれは言語にとらわれない)、あなたのためのProject Eulerがあります。

最後になりますが、少なくとも.NETの世界には、開発者の注意を必要とする多くの領域を持つMonoプロジェクトがあり、その一部はかなり複雑です。オープンソースの静的.NETコードアナライザーツールに貢献してみませんか?高度なものだけでなく、IL分析も含まれます。Jb Evainは、Cecilのリフレクションライブラリ、サポート、.NETデコンパイラなど、常に興味深いものに取り組んでいます。Expression

適切なものがない場合は、独自のモックフレームワークを開始するだけです:-)


2

Expressionsでその新しいトリックを披露したり、3つの異なる手順を一般化したりする必要があるときの感覚を知っていますか?

番号

これは、新しい開発者が文書化されていない膨大な数の混乱に巻き込まれ、保守およびリファクタリングされるときに良いことだといつも言っている理由の1つです。彼らが書いていない過度に「賢い」コードを維持することの現実を彼らに教え、5年後にコードをデバッグしなければならない貧しいシュマックに共感を植え付けることを願っています。


これは彼らを苛立たせ、彼らのコードはこの混乱を書いた初心者よりもはるかに良くエレガントになると思うでしょう。保守を難しくする意図でコードを作成する人はいません。
サラ

2

トピックは適切に選択されていると思います。一度に1万のことを行うPerlの行を書くのは「クール」ですが、それを再検討する必要があるときはそれは面倒です。

別の注意事項では、賢い、または賢明ではない、コードを文書化する必要があります。業界で受け入れられているプログラミング言語と、人間として私たちが思考で慣れている高レベルの概念との間には、固有のインピーダンス不整合があります。自己文書化コードは単純に実現できません-それが自然言語になるまで、つまり。高レベルであっても、Prologコードでさえ文書化する必要があります。

細粒度の命令型コードは、粗粒度の計画を実装するのに役立ちます。これは文書化する必要があります。簡単な3行のロードマップコメントが実行されるときに、メソッドの50行すべてを読み通す必要はありません。

後の編集:より雄弁な例は、コンピューターを超越した例です。本は非常によく書かれているかもしれませんが、しばしば抽象化の異なるレベルで処理したいと思います。多くの場合、この本の要約が役立ちます。それがコメントがコードに提供できることです。もちろん、適切に抽象化されたコードは、自己文書化には大いに役立ちますが、すべての抽象化レベルを提供することはできません。

また、本文中の主張の背後にある推論プロセスを説明する必要がある場合、コメントは本の副注のようにも機能します。

この文脈では、コメントの必要性を超えた自然言語に関する私の以前の声明は間違っていることがわかりました。本のように自然言語でさえ、文書に役立ち、テキストで具体化された抽象化をまばらに説明したり、本文を脱線せずに迂回したりすることができます。十分に抽象化されたコードは、すでに自己文書化に向けて長い道のりを進んでいる可能性があることに注意してください。

最後になりましたが、コメントは、コーダーが高レベルの抽象化を維持するのに役立ちます。多くの場合、ステップのリストに含まれる2つの連続したコメントが同じレベルの抽象化で語られていないことに気付きます。

特定の問題は、コーディングを超えて、他のアクティビティと同様にコーディングに影響します。コメントは、コードの背後にある理論的根拠とファセットを明確にするのに役立つことができます。そして、私は彼らが変化のために人に利益をもたらすより柔らかい言語を話す心地よい仲間だと思います。


1

どうやって?経験豊富な開発者にコードを見せ続けてください。そして、あなたがソフォモリックで派手であることを責められたら、それを吸い上げて、彼らがそれをどうするのか、そしてなぜ(もちろん非対立的な方法で)尋ねます。

-1を考慮して編集します。

多くの月前、私は同じ状況にありました-Delphiまたは「コンストラクト」でポインターを使用するたびに縮むボスが1人いました0-1で、すべての場所で1文字の変数を使用します。

理由を尋ねたので、私が学んだのは、彼らが私が何かに値するかもしれないと思ったので、説明するのに苦労しました-LOL ....


1
こんにちは、マイキー、私たちはワンライナー以上のものを探しています:このサイトは、質問が経験、事実、参考文献で満たされた長い思慮深い回答と組み合わされている場合にのみ役立ちます。あなた自身の経験から、他に何か追加できますか?

1

誇示する必要性を感じますか?いいえ、もうありません。どうやってそれを乗り越えましたか?ほとんどの人が他の悪い習慣を乗り越えるように...適切なテクニックの意識的で意図的な練習。ベストプラクティスの価値を十分に理解し、継続的に使用することで、良い習慣を身に付けることができます。

また、機能的なソフトウェアに焦点を合わせると、時間通りに維持され、簡単に保守できるため、求める認識が得られることも理解してください。経験豊富な開発者があなたのところに来て、「あなたが書いたモジュールはうまく設計されていた。私のプロジェクトにプラグインするために1つのコンポーネントを実装するだけでよい」と言うでしょう。「別のコンポーネントで使用するために、作成したモジュール全体を作り直さなければなりませんでしたか?ボブ・マーティンやワード・カニンガムについて聞いたことはありますか?」

TLDR:あなたは一人ではありません。スキルの認識は、問題をスマートに解決する副産物として最もよく達成されます。


0

私にとって、非常に巧妙なコードは、今日の要件に焦点を当てるのではなく、架空の将来の要件を解決しようとすることがよくあります。ビッグトラップ!

0%の複雑すぎるコードは達成可能な目標ではありません。たぶん努力するための最良の目標でさえありません。複雑すぎるコードは悪いですが、プログラマーとして成長するには新しいことを試してみる必要があります。回避できる場合は、運用コードで試してはいけません。機械とは異なり、人間は間違いを犯します。

コードレビューのヘルプ。他の人の「賢い」コードを修正するのに何年も費やすことが役立ちます。今日クライアントが本当に必要としているものに集中することは助けになります。

学校とビジネスには、清掃とメンテナンスのスタッフがいます。コードもクリーンアップとメンテナンスが必要です!可能であれば、混乱(特にあなた自身)を片付けてください!これが最善の方法だと思います。


-2

これまでに与えられた良いアドバイス(コードレビュー、デバッグ、TDDアプローチ)に加えて、適切なコーディングプラクティスに関する(ベストブック)を時々(再)読む必要があります。

  • 実用的なプログラマー
  • コード完了
  • きれいなコード

その他、使用するテクノロジーに応じて。


-2

YAGNIを覚えていてください-あなたはそれを必要としないでしょう

プログラマーは、必要と判断されるまで機能を追加しないでください...

YAGNIは、「動作する可能性のある最も単純なことを行う」(DTSTTCPW)のXPプラクティスの背後にある原則です。継続的なリファクタリング、継続的な自動化された単体テスト、継続的な統合など、他のいくつかのプラクティスと組み合わせて使用​​することを意図しています。継続的なリファクタリングなしで使用すると、厄介なコードと大量のリワークが発生する可能性があります...

YAGNIアプローチを支持する人々によると、現時点では必要ではないが、将来的には必要になる可能性があるコードを記述する誘惑には、次のような欠点があります。

  • 費やされる時間は、必要な機能の追加、テスト、または改善に費やされます。
  • 新機能は、デバッグ、文書化、およびサポートする必要があります。
  • 新しい機能は、将来何ができるかに制約を課します。そのため、不必要な機能は、必要な機能が将来追加されることを妨げる場合があります。
  • 機能が実際に必要になるまで、何をすべきかを完全に定義してテストすることは困難です。新しい機能が適切に定義およびテストされていない場合、最終的に必要になったとしても、正しく機能しない可能性があります。
  • コードの膨張につながります。ソフトウェアがより大きく複雑になります。
  • 仕様とある種のリビジョン管理がない限り、この機能はそれを利用できるプログラマーには知られていません。
  • 新しい機能を追加すると、他の新しい機能が提案される場合があります。これらの新しい機能も実装されている場合、機能のクリープに向かって雪だる​​ま効果が生じる可能性があります...

3
これは真実かもしれませんが、詳細になればなるほど、より良い答えになるでしょう。
ChrisF
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.