どのような「ベストプラクティス」が常にベストとは限らないか、そしてその理由は何ですか?[閉まっている]


100

「ベストプラクティス」は業界のいたるところにあります。「コーディングのベストプラクティス」のGoogle検索では、ほぼ150万の結果をアップになります。このアイデアは多くの人に快適さをもたらすようです。指示に従うだけで、すべてがうまくいきます。

ベストプラクティスについて読んだとき-たとえば、最近Clean Codeのいくつかを読んだだけで-緊張しました。これは、このプラクティスを常に使用する必要があるということですか?添付されている条件はありますか?それが良い習慣ではないかもしれない状況はありますか?問題についてさらに学ぶまで、どうすれば確実に知ることができますか?

Clean Codeで言及されているプラ​​クティスのいくつかは私と相性がよくありませんでしたが、それが悪い可能性があるからなのか、それとも私の個人的な偏見によるものなのかは正直わかりません。ハイテク業界の多くの著名人がベストプラクティスがないと考えているように思われることを知っているので、少なくとも私のしつこい疑念が良い会社に私を置きます。

読んだベストプラクティスの数は多すぎて、ここにリストしたり、個々の質問をしたりすることはできないため、これを一般的な質問として言いたいと思います。

「ベストプラクティス」として一般的にラベル付けされているコーディングプラクティスは、特定の状況下で次善または有害な場合があります。それらの状況は何ですか?なぜ彼らは練習を貧しいものにしますか?

具体的な例や経験について聞きたいです。


8
どちらがあなたの意見に合わないのですか?
セルジオアコスタ

誰でも本を書くことができ、私はそれに同意する必要はありません-それはそれと同じくらい簡単です。
仕事

Steve McConnellの本「Code Complete」について私が気に入っていることの1つは、彼がすべてのヒントを確固たる証拠と研究で裏付けていることです。Just sayin '
JW01

5
@Walter:これは何ヶ月も開いていますが、間違いなく建設的です、なぜそれを閉じるのですか?
11

2
ここで私の名前がどのように言及されているかを見て、私はチップを入れるべきだと思います:ここでの答えは価値があると信じていますが、答えを無効にすることなく、間違いなく世論調査のようなものに言い換えることができます。タイトルの例:「人気のある「ベストプラクティス」は有害な場合があり、いつ/なぜですか?」
アーロンノート

回答:


125

この声明であなたは頭に釘を打ったと思う

私は物事を額面どおりに受け取り、批判的に考えないことを嫌います

なぜ存在するかについての説明が付いていない場合、ほとんどすべてのベストプラクティスを無視します

レイモンド・チェンは、彼が言うとき、この記事でそれを最もよく述べます

良いアドバイスには根拠が付いているので、いつ悪いアドバイスになるかを知ることができます。なぜ何かを行うべきなのか理解していない場合、貨物カルトプログラミングのtrapに陥り、それが不要になった場合や有害になった場合でも、それを続けます。


4
素晴らしい引用。
デビッドソーンリー

そのレイモンド・チェンの引用の次の段落は、おそらくハンガリー語の表記法について説明しています!私が見ているほとんどの企業は、彼らが説明できる本当の正当な理由なしにそれを使用しています。
クレイグ

3
しかし、ベストプラクティスの背後にある理由が何であるかを調べない言い訳として人々がこれを受け取らないことを願っています。;)残念ながら、私は開発者がこのような態度でいるのを見てきました。
Vetle

3
根拠は良い。研究は優れています。
ジョンパーディ

7
絶対に本当です、そして私は以前同じことを言いました。おそらく、「標準」文書の最初の標準は、「知識を共有し、後で標準を無効にするために必要な情報を提供するために、すべての標準にその存在理由を含める必要があります。」
スコットホイットロック

95

これをリングに投げ込むこともできます:

Premature optimization is the root of all evil.

いいえ、ちがいます。

完全な引用:

「私たちは小さな効率を忘れて、時間の約97%を言うべきです。時期尚早な最適化はすべての悪の根源です。しかし、その重要な3%で機会を逃すべきではありません。」

つまり、設計プロセス全体を通じて、特定の戦略的なパフォーマンス強化を活用できます これは、パフォーマンス目標と一致するデータ構造とアルゴリズムを使用することを意味します。これは、パフォーマンスに影響する設計上の考慮事項を認識していることを意味します。ただし、最適化を行うと保守性が低下しますが、軽微な最適化は行われません。

アプリケーションは適切に設計されている必要があります。そのため、アプリケーションに少しの負荷をかけたときに最後に落ちないようにしてから、書き直します。省略された引用符の危険性は、多くの場合、開発者はそれを何もするのが遅すぎるかもしれない最後までパフォーマンスについて全く考えない言い訳としてそれを使用することです。細かい点に焦点を合わせていない場合は、最初から良いパフォーマンスを構築することをお勧めします。

組み込みシステムでリアルタイムアプリケーションを構築しているとします。「早すぎる最適化はすべての悪の根源である」ため、プログラミング言語としてPythonを選択します。今、私はPythonに対して何もありませんが、それインタプリタ言語です。処理能力が制限されており、一定量の作業をリアルタイムまたはほぼリアルタイムで実行する必要があり、作業に必要以上の処理能力を必要とする言語を選択した場合、あなたは非常に頭がおかしくなります。今、有能な言語でやり直す必要があります。


4
強いために+1 いいえ、そうではありません。
スティーブン

21
しかし、1つの特定の最適化がその重要な3%以内にあることを既に認識している場合、それを最適化するのは時期尚早ですか?
ジョン

7
@Robert:それでは、「時期尚早な最適化はすべての悪の根源である」という声明との意見の相違点は何ですか?
ジョン

8
高度な設計と言語選択などの技術的決定を最適化するのは決して早すぎることではありません。しかし、多くの場合、非効率性が親になるのは設計をほぼ完了した後であるため、ほとんどのチームは意図するかどうかにかかわらず、ほとんどのチームが使い捨てバージョンを作成すると言っています。プロトタイピングのもう1つの議論。
ドミニクマクドネル

8
@ロバート、クヌースの引用は時期尚早に最適化されました

94

関数/メソッドごとに1つの戻り。


7
これを入れようとしていました。私はいくつかの早期返品ステートメントが大好きです。
カーソンマイヤーズ

4
絶対に!人々は、初期のreturn声明を避けるために、かなり興味深いプログラムフローを考案しています。深くネストされた制御構造または継続的なチェック。これは、if returnこの問題を本当に単純化できる場合に、メソッドを実際に肥大化させる可能性があります。
snmcdonald

4
関数に複数のリターンが必要な場合(ガードを除く)、おそらく関数は長すぎます。
EricSchaefer

18
複数の場所に表示することを意図していない限り、returnキーワードを使用しても意味がありません。早く戻り、頻繁に戻ります。コードをさらに簡素化するためだけに役立ちます。人々がブレーク/継続ステートメントがどのように機能するかを理解できる場合、なぜ彼らはリターンに苦労していますか?
エヴァンプライス

7
これは非常に時代遅れのベストプラクティスだと思います。私はそれが現代のベストプラクティスだとは思わない。
スキルドリック

87

車輪を再発明しないでください、広く誤用された教義です。そのアイデアは、適切なソリューションが存在する場合、独自のソリューションを作成する代わりにそれを使用することです。労力を節約することに加えて、既存のソリューションは、最初に思いついたものよりも実装(バグがなく、効率的、テスト済み)のほうが適切です。ここまでは順調ですね。

問題は、100%の適切なソリューションがほとんど存在しないことです。80%の適切なソリューションが存在する場合がありますが、それを使用することはおそらく問題ありません。しかし、どのように60%が適切でしょうか?40%?どこで線を引きますか?線を引かないと、「ホイールの再発明」を避けたいという理由だけで、その機能の10%を使用しているため、プロジェクトに肥大化したライブラリを組み込むことになります。

車輪を再発明すれば、まさにあなたが望むものを手に入れることができます。車輪の作り方学びます。実践することで過小評価されるべきではありません。最終的に、カスタムホイールは市販の汎用ホイールよりも優れている可能性があります。


3
私はこれを他の方法で起こりました。当時私が望んでいたことをするものがなかったので、独自のajaxグリッドコンポーネントを作成しましたが、後でそれをExt JSグリッドに置き換えました。最初からディスプレイレイヤーが置き換えられるという仮定を立てることができました。
ジョーリSebrechts

20
同意した。もし誰も車輪を再発明しなかったら、私たちはみんな木製のタイヤで車を運転していたでしょう。
ワイリー博士の見習い

6
BoostをC ++プロジェクトに追加すると、常に10%の例のように感じます。私はいつも直接、それの10%未満を必要とするが、もちろん、私は必要な機能は、他のモジュール...インポートし、他のモジュールをインポート
ローマStarkov

3
+1:今週、私は車輪を再発明し(たとえば、私たちが使用した肥大化した人気のあるjqueryプラグインを、私たちのニーズに合ったものに置き換えます)また、仕事は文字通り車輪を再発明することです。ミシュランを例にとると、タイヤを改良するために研究開発を行います。
ワイルドピーク

2
@Dr。賢明なことに、これらのホイールは再発明されず、リファクタリングされました!

78

「すべてを単体テスト」。

私は、すべてのコードがユニットテストを持つべきだとしばしば言ったと聞いていますが、これは私が同意しない点です。メソッドのテストがある場合、そのメソッドの出力または構造への変更は2回(コードで1回、テストで1回)行う必要があります。

そのため、私の意見では、単体テストはコードの構造的安定性に比例する必要があります。レイヤードシステムをボトムアップで記述している場合、データアクセスレイヤーはwazooをテストします。私のビジネスロジックレイヤーはかなりよくテストされ、プレゼンテーションレイヤーにはいくつかのテストがあり、ビューにはほとんどテストがありません。


7
「時期尚早の最適化」の引用のように、「Unit Test Everything」は決まり文句になったと思います。私は一般的にあなたの割合に同意し、開発者がアプリケーション層オブジェクトをモックするために途方もない努力をしている例を見てきました。
ロバートハーベイ

36
メソッドの構造の変更がテストの変更を引き起こす場合、間違ったテストを行っている可能性があります。単体テストでは、実装のみを検証し、結果のみを検証する必要があります。
アダムリア

7
@Anna Lear:彼は設計/構造の変更(リファクタリング)について話していたと思います。設計が十分に成熟していないため、より良い方法を見つけた場合、多くのテストを途中で変更する必要があるかもしれません。あなたがより熟練したテスターである場合、テストが悪いアイデアである場所にもっと簡単に気付くかもしれないことに同意します(この理由などのため)仕方。
n1ckp

13
これが、「最初にテストを行う」というアイデアが機能しない理由でもあると思います。最初にテストを行うには、設計を正しく行う必要があります。しかし、設計を正しく行うには、物事を試し、それらがどのように機能するかを確認して、改善することが必要です。そのため、設計する前にテストを実際に実行することはできません。設計を正しく行うには、コードを作成してそれがどのように機能するかを確認する必要があります。本当に優れた建築家がいなければ、そのアイデアがどのように機能するかはわかりません。
n1ckp

13
@ n1ck TDDは、実際には設計演習と同じくらいテスト演習ではありません。アイデアは、既存の設計にテストを適合させるのではなく(テストが不適切/不十分である可能性があるため)、テストを通じて設計を進化させることです(これにより、適切なAPIがすぐに公開されます)。そのため、最初にテストを実行するための設計権は必要ありません。
アダムリア

57

常にインターフェイスにプログラムします。

実装が1つしかない場合もあります。インターフェースの抽出プロセスを、その必要性がわかるまで遅らせると、多くの場合、それが不要であることがわかります。


4
同意すると、インターフェイスが必要なときにインターフェイスにプログラムできます(つまり、動作する安定したAPI)。
ロバートハーベイ

45
私の読書では、このルールは言語構成要素としてのインターフェースに関するものではありません。これは、メソッドを呼び出すときにクラスの内部動作について何も仮定しないでください。APIコントラクトのみに依存する必要があります。
ゾルトテレック

2
ここで興味深い質問があります-私は主に.NET開発者なので、私のインターフェースはIBusinessManagerまたはIServiceContractのように見えます。私にとって、これは非常に簡単にナビゲートできます(そして通常、インターフェイスを別の名前空間(または別のプロジェクト)に保持します)。Javaを使用したときに、この混乱を実際に発見しました(通常、インターフェイスの実装には.implの接尾辞が付いており、インターフェイスには線引きがありません)。これはコード標準の問題でしょうか?もちろん、Javaのインターフェースにより、コードが散らかったように見えます-一見すると、通常のクラスとまったく同じに見えます。
ワトソン

5
@ワトソン:1つのコストは、Eclipseのメソッド呼び出しでF3(「宣言にジャンプ」)を押すたびに、1つの実装ではなく、インターフェイスにジャンプすることです。次に、Tキーを押しながら下矢印キーを押して、実装に戻る必要があります。また、いくつかの自動リファクタリングもブロックします。たとえば、インターフェイス定義全体でメソッドをインライン化することはできません。
トムアンダーソン

4
@Tom:ええと、私は喜んでその戦争に参加します、Eclipse vs. ブーム。私はEclipseが悪いと言っているわけではありません。もしAxisの勢力がEclipseを使って戦争マシンを構築または設計していたら、第二次世界大戦は「2日間のkerfuffle」として知られるでしょう。しかし、真面目なことに、市販のIDE(Intellij / VS + ReSharper)で得られる洗練度が不足していることがわかりました。何度も戦っているのに気づきました。
ワトソン

46

オープンソース(またはMicrosoft以外の.NET開発者)を使用しないでください。

Microsoftが開発しなかった場合、ここでは使用しません。ORMを使用する-EF、IOCを使用する-Unity、ログに記録する-エンタープライズロギングアプリケーションブロック。非常に多くの優れたライブラリが存在しますが、私は常に開発の世界のドルメニューからの注文にこだわっています。マイクロソフトのベストプラクティスを聞くたびに、「マクドナルドの栄養ガイドライン」と思います。確かに、あなたがそれらに従うならおそらく生きますが、あなたはまた栄養失調と太りすぎになります。

  • これはあなたのベストプラクティスではないかもしれないことに注意してください。しかし、これは私が働いたほぼすべての場所で一般的なものです。

13
恐ろしいですね... =(私は反対側に、おそらくあまりだ、しかし、私はM $をできるだけ避ける。
Lizzan

それはそうではないはずです。誰が作ったのかを考えるだけでなく、ライブラリはその価値のために選ばれるべきです。たとえば、私はEFが大好きですが、Enterprise Libraryの経験が乏しく、FluentValidation、log4net、Elmahなどの検証およびログ記録のためのより良いツールを見つけました。
マッテオモスカ

4
IBM ^ wMicrosoftを購入しても解雇されない
クリストファー・マーハン

17
また、鏡像バージョンもあります。つまり、Microsoftを使用したり、支払いが必要なものを使用したりしないでください。
リチャードガズデン

5
私は幸運にも、これが広く受け入れられている教義ではない組織で働くことができますが、私たちが商用ソリューションを採用した場所では、確かに大きな痛みがあります。問題は、商用ソリューションの一部がまったく機能しない場合に発生します。オープンソースの場合は、ソース(究極のドキュメント)を見て、何が問題なのかを調べることができます。クローズドソースでは、あなたがしている製品についてあまり知らない技術サポートの知識にアクセスする特権にお金払わなければなりません。そして、それが唯一の利用可能な「修正」です。
SingleNegationElimination

40

オブジェクトの向き

コードが「オブジェクト指向」であるという理由だけで、魔法のように優れているという仮定があります。したがって、人々は機能をクラスとメソッドに絞り込み、オブジェクト指向にするだけです。


7
Object Orientationが提供する組織を利用せずに、かなりの規模のソフトウェアシステムを構築することは想像できません。
ロバートハーベイ

18
ロバート。Unixはオブジェクト指向ではなく、確かにかなりのサイズのソフトウェアシステムとして適格です。また、非常に人気があるようです(Mac OSX、iPhone、Androidフォンなどを考えてください)
クリストファー・マーハン

7
私が意味したのは、最も適切な方法論を使用すべきだと思うことです。「オブジェクト指向」だからといって、面倒であまり意味のないメソッドやクラスを使用する人を見てきました。それはカルトカルトです。
LennyProgrammers

8
特効薬はありません。関数型プログラミング(Haskell)は、オブジェクト指向ではなく非常に成功しています。一日の終わりには、複数のツールがあり、手元のタスクに最適な品揃えを選択するのがあなたの仕事です。
マチューM.

9
面白いことは、クラス、ポリモーフィズムなどを使用することに加えて、オブジェクト指向コードのほとんどが実際には手続き型コードであることです。
オリバーワイラー

35

すべてのコードにコメントを付ける必要があります。

いいえ、ありません。明らかなコードがある場合があります。たとえば、セッターは特別なことをするまでコメントしないでください。また、なぜ私はこれをコメントする必要があります:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
すべてのコードは理解可能である必要があります。コメントはそのための主要なツールですが、唯一のものではありません。
トレバー

当然、コードは理解できるものでなければなりません。しかし、たとえばメソッド名に何も追加しないコメントを書く理由は1つもありません。あなたが書くなら/** sets rank. */ void setRank(int rank) { this.rank = rank; }、私はコメントを愚かなものと仮定します。なぜ書かれているのですか?
ウラジミールイワノフ

2
生成されたドキュメント。これ/** */が、/* */フォーマットのコメントではなく、フォーマットの目的です。または、.NETの場合は///
Berin Loritsch

10
、を使用すること}//end if}//end for}//end whileこれまで出会った無駄なコメントの最良の例です。私はこれを何度も見ましたが、オープニングブレースは上の2行以下です。あなたがあればIMHO 必要なこれらのコメントを、あなたのコードが必要と再ファクタリング...またはあなたは$ 20までポニーと一致する括弧を強調IDE /テキストエディタを購入する必要があります。
-scunliffe

7
コードは「方法」と言います。コメントは「なぜ」と言う必要があります。

32

方法論、特にスクラム。大人が「スクラムマスター」というフレーズを使っているのを聞いたとき、私はまっすぐな顔を保つことができません。開発者が抗議するのを聞くのにうんざりしているのは、Methodology Xのある側面が彼らの会社のために働いていないということです。方法論Xの「スクラムをもっと難しくしてください、私のパダワンの学習者でなければなりません!」

アジャイル方法論には知恵のナゲットがあります---それらの多くは---しかし、それらはしばしば私が私のギャグ反射と戦うことができないほど多くの肥料で覆われています。ウィキペディアのスクラムページからこのビットを取ります

スクラムでは多くの役割が定義されています。すべての役割は、開発プロセスへの関与の性質に基づいて、豚と鶏の2つの異なるグループに分類されます。

本当に?豚と鶏、あなたは言う?魅力的!これを上司に売り込むのが待ち遠しい...


面白い。ある程度同意します。ただし、最後の部分では、必要なものを呼び出すと、ニーモニックになります。それだけです。
スティーブンエバーズ

12
+1 ...あなたは正しい、それを真剣に受け止めるのは難しい。<大きなブームの声> *私はスクラムマスターです* </ voice>
グランドマスター

2
そしてたとえ話。それは教会の説教、または自助教祖(およびコメディアン)が有名な種類の逸話を思い出させます。「私の友人スティーブを連れて行ってください。これらの種類の教訓的な糸は、他の分野では私を悩ませませんが、工学科学でそれらが増殖するのを嫌います。
evadeflow

2
スクラムニンジャはどうですか?
ベリンロリチュ

1
私は「豚と鶏肉」の比較に同意しません...それはアジャイル宣言に直面して直接飛びます。つまり、「契約交渉を介した顧客コラボレーション」。顧客は、プロジェクトチームとして、プロジェクトの成功に(もしそうでなければ)既得権を持っています。いくつかの役割を豚と呼び、他の役割を鶏と呼ぶと、「私たち対彼ら」の考え方が確立され、IMHOがプロジェクトの成功の最大の障害になります。
マイケルブラウン

25

オブジェクトリレーショナルマッピング... http://en.wikipedia.org/wiki/Object-relational_mapping

データから抽象化されたくないし、その正確な制御と最適化を失いたくもない。これらのシステムでの私の経験は非常に貧弱です...これらの抽象化レイヤーによって生成されたクエリは、オフショアリングで見たものよりもさらに悪いです。


19
早すぎる最適化は、すべての悪の根源です。遅いコードは、実際には、保守できないコードと比較した場合、問題になることはめったにありません。ORMを使用し、必要な場合にのみ抽象化を切り抜けます。
フィッシュトースター

28
ORMは80〜20のツールです。彼らは80%のCRUDを処理することを意図しており、しばらくするとそのような無限の配管コードをすべて書くのは非常に面倒になります。他の20%は、ストアドプロシージャの使用や通常のSQLクエリの作成など、より「従来の」方法で実行できます。
ロバートハーベイ

18
@Fishtoaster:「小さな効率を忘れて、97%の時間を言うべきです。時期尚早な最適化がすべての悪の根源です。しかし、その重要な3%で機会を
ロバートハーベイ

5
@Robert Harcey:直接引用を使用しなかった理由があります。私は、ほとんどのプログラマーが効率性に集中しすぎていると思います。それは彼らが本当に解決する必要のある問題です。確かに、他のドメインよりも重要な特定のドメインがありますが、保守性と拡張性はどこでも問題です。もう一つは、変性引用:「それを動作させることは、保守作る、それが読みやすく、それが拡張可能にする、それがテスト可能にする、そしてその後、あなたは時間を持って、それはあなたがそれを必要と判明した場合、それは速いします。」
フィッシュトースター

12
@クレイグ:あなたの声明で皮肉をどのように認識しなかったのですか?ORMから優れたパフォーマンスを得る方法を学ぶのに1年かかることは、ORM に対する優れた議論です。また、SQLを「制御」してストアドプロシージャを注入する必要もあります。そのための知識があれば、ORMを完全にバイパスする知識があります。
ニコラスナイト

22

まるで英語の文であるかのように関数名を書く:

Draw_Foo()
Write_Foo()
Create_Foo()

これは素晴らしいように見えるかもしれませんが、APIを学習しているときは苦痛です。「Fooで始まるすべて」のインデックスを検索するのはどれくらい簡単ですか?

Foo_Draw()
Foo_Write()
Foo_Create()


2
TMの関数リストにFooと入力するのと同じくらい簡単でしょう。
ジョシュK

68
あなたが実際にそれになりたいと思いますのような音Foo.Draw()Foo.Write()そしてFoo.Create()あなたが行うことができるように、Foo.methods.sortまたはFoo.methods.grep([what I seek]).sort
Inaimathi

7
「Get」で始まる別の例です。
ジェフ

1
私はObjective-Cの世界から来ましたが、Java(他の人生)を行うとき、冗長なメソッド名と中置表記法を大いに見逃しています。コード補完が機能し始めてから、余分なタイピングの問題も見つかりませんでした。

2
@Scottホイットロックは:ないそのいくつかの.NET開発者のための日付のうち、IIRC、VS 2008はそれをしませんでした。2010年もそうですが、素晴らしいです。
スティーブンエバーズ

22

MVC-多くの場合、Webデザインの多くの問題をMVCアプローチに組み込むことは、単純さや構造よりもフレームワーク(レールなど)を幸せにすることの方が多いと感じています。MVCは、単純さよりも過剰な足場を重視しているように見える「建築宇宙飛行士」のお気に入りです。ymmv。

クラスベースのオブジェクト指向-私の意見では、可変状態の複雑な構造を奨励しています。私が長年にわたってクラスベースのオブジェクト指向で見つけた唯一の説得力のあるケースは、オブジェクト指向の本の第1章を形成する「シェイプ->長方形->正方形」の例です。


4
私はASP.NETおよびASP.NET MVCでWeb開発を行ってきましたが、MVCは足場のように見えますが、多くの理由でASP.NETよりもMVCを好んでいます。単純さ、保守性、マークアップの非常にきめ細かい制御です。すべてにその場所があり、すべてが少し反復しているように見えますが、それは維持する喜びです。完全にカスタマイズ可能であるため、すぐに使用できる動作が気に入らない場合は、変更できます。
ロバートハーベイ

1
オブジェクト指向に関する限り、それを行うには良い方法と悪い方法があります。継承は過大評価されており、現実の世界では、ほとんどの本で信じられないほど控えめに使用されています。現在、オブジェクト指向の世界でさえ、より機能的で不変の開発スタイルに向かう傾向があります。
ロバートハーベイ

1
MVCに言及する場合は+1。MVCの概念(データレイヤーロジック、プレゼンテーションロジック、およびバックグラウンドロジックを分離することは良い考えです)が、コードスニペットを含むファイルのミッシュマッシュで複雑なフォルダー階層に物理的に分離するのは愚かなことです。私は、この現象全体をPHPの名前空間のサポートの欠如と、数十年前の技術を「最新のもの」として賞賛する初心者開発者のせいにします。データベースアクセサ、GUI、およびバックグラウンドロジック(および必要に応じてサブ名前空間)の名前空間を作成するのは簡単です。
エヴァンプライス

3
オブジェクト指向に関しては、プロジェクトが複雑さを管理することが重要になるサイズまでプロジェクトが大きくなるまで、その利点を実際に目にすることはありません。可能な限り単一の責任原則に従い、コードが公開されている場合(.dllなど)、可能な限りクラス/メソッド/プロパティの内部実装を非表示にして、コードをより安全にし、APIを簡素化します。
エヴァンプライス

1
個人的には、shape-> rectangle-> squareの例は、oop に対する最もエレガントな議論の1つである思います。たとえば、Square(10).Draw()それだけで十分Rectangle(10, 10).Draw()です。正方形は長方形のサブクラスであることを意味すると思います。しかしmySquare.setWidthHeight(5,10)、ナンセンスです(つまり、リスコフの置換原理に失敗します)、正方形は異なる高さと幅を持つことはできませんが、長方形はできるので、長方形は正方形のサブクラスであることを意味します。これは、「円、楕円の問題」として他の文脈で知られています
-SingleNegationElimination

22

ヤグニ

あなたはそれを必要としません

このアプローチは、既存のコードベースに機能を実装する必要があり、慎重な計画がこれらの機能を事前に含んでいた場合、何時間もかかりました。

私の考えはしばしばYAGNIのために拒否され、ほとんどの場合、誰かがその決定に対して後で支払わなければなりませんでした。

(もちろん、適切に設計されたコードベースでも機能を後から追加できると主張することができますが、現実は異なります)


15
私はYAGNIに同意しますが、あなたが何を得ているかわかります。YAGNIのポイントは、すべてを前もって詳細に計画したい人に対処することです。ただし、10回のうち9回は、コードを技術者の下に置いたり、計画を完全にスキップしたりする言い訳として使用されます。
ジェイソンベイカー

12
P.Floyd、@ Jason Baker:+1絶対に正しい。古い言葉はここに当てはまります。「ラボでの月は図書館で時間を節約できます」
スティーブンエバース

多くの場合、仕様は実装の大部分を残し、一部のインターフェイスは開いたままにします(ほとんどの場合はそうする必要があります)。仕様に直接含まれていないものの、仕様を実装するために必要なものはすべて、実装の決定、ユーザーが表示可能なインターフェースなど、仕様の間接的な要件でもあります。機能が仕様に含まれておらず、仕様によって暗示されていない場合、その機能は必要ありません。これはどのように混乱する可能性がありますか?
SingleNegationElimination

1
@TokenMacGuyの重要な側面は、仕様によって暗示されています。それは意見が大きく異なるところです。
ショーンパトリックフロイド

20

SQLの場合

  1. トリガーを使用しないでください
  2. ビューの後ろにテーブルを常に隠す

順番に:

  1. それらは場所がある機能です。テーブルへの複数の更新パスがあるか、100%監査が必要ですか?

  2. なんで?契約を維持するためにリファクタリングを行っていたとしても、テーブルの変更に合わせてビューを変更している人を読んだときはそうではありません

編集:

番号3:EXISTSによる*の回避。1/0を試してください。できます。列リストは、SQL標準に従って評価されません。さちえ191


3
#2はベストプラクティスですか?
ホーガン

2
@ホーガン:はい、それは多くの場所で文書化されていますvyaskn.tripod.com/sql_server_security_best_practices.htmおよびflylib.com/books/en/3.404.1.34/1 そしてここではそれほど簡単ではあり ません:simple-talk.com/community/blogs/tony_davis/アーカイブ/
2009/08/06

1
@Hogan:単にベーステーブルをミラーリングするビューでは、ベーステーブルを直接使用する場合のセキュリティは追加されません。securityuserテーブルに参加する場合、または一部の列をマスクする場合は十分に公平です。しかし、テーブルまたはビューからすべての列を選択します。違いはありません。個人的には、とにかくストアドプロシージャを使用します。
gbn

3
@Hogan:SQL Serverについて何か知っている:-) stackoverflow.com/users/27535/gbn つまり、テーブルのGRANT SELECTは、ビューがSELECT * FROM TABLE
gbn

1
@gbn:同意します。そこに違いはありません。同じことを言っているのではないかと思います。私のオリジナルのコメント(「#2はベストプラクティスですか?」)は、ビュー(トリガーなど)が正しく使用されるよりもよく使用されないという個人的な経験に基づいていると思います。したがって、このようなベストプラクティスは、機能強化ではなく虐待につながるだけです。ベストプラクティスと見なされる場合、100%正しいことは悪いことです。
ホーガン

20

主にデザインパターン。それらは過剰に使用され、十分に活用されていません。


13
+1デザインパターンがどのように美しいまたはエレガントなソリューションであるかはまだわかりません。それらは言語の欠陥の回避策であり、それ以上のものではありません。
オリバーワイラー

2
言語自体を使用して言語の臭いを根絶する努力としてそれを見てください。
フィリップデュパノビッチ

15

単一責任の原則

(「すべてのクラスに1つの責任のみを持たせる必要があります。言い換えれば、すべてのクラスに1つだけの変更理由を持たせる必要があります」)

同意しません。私が考える方法を変更する唯一の理由があるはずであり、クラスのすべてのメソッドが持つべき1-別の論理的な関係を、しかし、クラス自体は実際にあります行う、いくつかの(関連)のものを。

私の経験では、この原則はあまりにも熱心に適用されすぎており、多くの小さな1つのメソッドクラスになってしまいます。私が働いたアジャイルショップは両方ともこれを行っています。

.Net APIの作成者がこの種のメンタリティを持っているとしたら、 List.Sort()、List.Reverse()、List.Find()などではなく、ListSorter、ListReverser、およびListSearcherクラスがあると想像してください!

SRP (それ自体は理論上ひどいものではありません)に反論するのではなく、長年の逸話的な経験をいくつか紹介します。


私が働いたある場所で、ノード、グラフ、グラフ作成者、グラフソルバー、グラフ作成者/ソルバーを使用して問題を解決するクラスの5つのクラスで構成される非常にシンプルな最大フローソルバーを作成しました実世界の問題。特に複雑なものや長いものはありませんでした(ソルバーは、最大で150行まで)。ただし、クラスには「責任」が多すぎると判断されたため、同僚はコードのリファクタリングに取り掛かりました。それらが完了すると、私の5つのクラスは25のクラスに拡張され、コード行の合計は元の3倍以上になりました。コードの流れはもはや明らかではなく、新しい単体テストの目的でもありませんでした。私は自分のコードが何をしたかを理解するのに苦労しました。


同じ場所で、ほぼすべてのクラスには1つのメソッドしかありません(「責任」のみ)。プログラム内のフローを追跡することはほぼ不可能であり、ほとんどの単体テストは、このクラス別のクラスのコードを呼び出したことをテストすることで構成されていました。文字通り数百のクラスがあり、そこには数十のクラス(IMO)しかありませんでした。各クラスは「もの」を 1つだけ実行しましたが、「AdminUserCreationAttemptorFactory」のような命名規則を使用しても、クラス間の関係を伝えることは困難でした。


別の場所(クラスは1つだけのメソッドを持つという考え方もあります)で、特定の操作中に95%の時間を費やすメソッドを最適化しようとしました。(少し愚かな)最適化を少し行った後、なぜそれが何千回も呼ばれている理由に注意を向けました。それはクラスのループで呼び出されていました...そのメソッドは別のクラスのループで呼び出されていました..これもループで呼び出されていました..

すべてのことを言って、13のクラスに(真剣に)広がる5つのレベルのループがありました。あるクラスが実際に何をしていたかは、それを見ただけでは判断できませんでした。クラスが呼び出したメソッド、それらのメソッドが呼び出したメソッドなどのメンタルグラフをスケッチする必要がありました。すべてが1つのメソッドにまとめられていた場合、問題のメソッドはすぐにわかる5つのレベルのループ内にネストされているため、長さは約70行でした。

これらの13のクラスを1つのクラスにリファクタリングするという私の要求は拒否されました。


6
誰かがその仕事で「パターンフィーバー」またはこの場合「プリンシプルフィーバー」を獲得したように聞こえます。リストクラスはSRPに違反しません。その機能はすべて、オブジェクトのコレクションを操作するという1つの目的を果たします。クラスに関数が1つしかないことは、やり過ぎのように思えます。SRPの背後にある原則は、コードの単位(メソッド、クラス、またはライブラリ)に、簡潔に述べることができる単一の責任を持たせることです。
マイケルブラウン

3
私は、純粋で機能的なコードを書くことが不可能であると感じる人々から、この種の狂気を見始めました。世界のすべての問題をパターンの本から解決できることを教育しすぎています。プラグマティズムについて十分に考えていません。あなたのように、私はクラスベースのオブジェクト指向コードを見てきました。そしてその巨大で肥大化した。
すぐに

3
2番目のコメントはこちら。多くの「原則」が過剰に適用されています。良いアイデアはたくさんありますが、正反対のことが適切な場合もあります。優れたプログラマーは、いつルールを破るかを知っています。ルールは「ルール」ではないので、「ほんとうに愚かなアイデアを除いて、ほとんどの場合グッドプラクティス」のステートメントです。
すぐに

「.Net APIの作成者がこの種のメンタリティを持っていると想像してください。List.Sort()、List.Reverse()、List.Find()などではなく、ListSorter、ListReverser、およびListSearcherクラスがあります。 !」。これはまさにC ++で行われていることであり、素晴らしいことです。アルゴリズムはデータ構造から分離されているため、独自のコンテナを作成すると、標準ライブラリで機能するすべてのアルゴリズムが新しいコンテナで機能します。.Net landでは恐ろしくなければならず、ソートする新しいコンテナーごとに新しいソート関数を作成します。
マンカルス

14

Clean Codeに言及しましたが、いくつかの優れたアイデアが含まれていますが、すべてのメソッドをサブメソッドにリファクタリングしたり、サブメソッドなどにリファクタリングしたりすることへの執着は行き過ぎだと思います。いくつかの10行のメソッドの代わりに、20の(おそらく適切に命名された)ワンライナーを好むことになっています。明らかに誰かがそれはきれいだと思っていますが、私には元のバージョンよりもずっと悪いようです。

また、次のような単純な基本的なものを置き換える

0 == memberArray.length

クラス内で次のようなクラス独自のメソッドを呼び出します

isEmpty()

疑わしい「改善」私見です。追加:違いは、最初のチェックで正確に言うことです:配列の長さが0であるかどうかをisEmpty()チェックします。配列の長さもチェックするかもしれません。ただし、次のように実装することもできます。

return null != memberArray ? 0 == memberArray.length : true;

つまり、暗黙的なnullチェックが含まれています!これは、パブリックメソッドの場合は正常な動作かもしれません-配列がnullの場合、何かが確実に空になります-しかし、クラス内部について話しているとき、これはそれほどうまくありません。外部へのカプセル化は必須ですが、クラス内部はクラス内で何が起こっているかを正確に知る必要があります。クラス自体をカプセル化することはできません明示的は暗黙的よりも優れています。


これは、長いメソッドを分解したり、論理的な比較を伴うことは良くないと言うことではありません。もちろんそうですが、それをどの程度行うか(スイートスポットの場所)は、明らかに味の問題です。長いメソッドを分解すると、より多くのメソッドが作成されますが、それは無料ではありません。実際に何が起こっているのかを確認するには、ソースコードを飛び回らなければなりません。そのすべてが単一のメソッドに含まれている場合、一目でそれを見ることができます。

場合によっては、1行のメソッドは短すぎてメソッドに値しないと言うことさえできます。


6
これが問題となることはめったにありません。ほとんどの場合、私は通常、1つのメソッドで見た目が少なすぎず多すぎます。ただし、いくつかの研究によると、メソッドの非常に低い複雑さは、適度に低い複雑さよりもわずかに高いバグ率も持っています。enerjy.com/blog/?p=198
MIA

ええ、これは間違いなくClean Codeのみの問題です。あなたが言ったように、実際の方法では方法が長すぎる傾向があります。しかし、その曲線を見るのは面白いです!確かに、物事は可能な限りシンプルにすべきですが、シンプルにするべきではありません。
ジョナスプラッカ

1
2番目の例を非常に読みやすくしており、公開する場合はそのフォーム(またはクラス自体のLengthプロパティのようなもの)が必須です。
ロバートハーベイ

@Robert Harvey:2番目の例はすばらしいパブリックメソッドですが、実装方法を見る前に何をするのか正確にはわからないため、クラス自体から呼び出すのは疑問です。たとえば、nullをチェックできます。上記の私の追加を参照してください。
ジョナスプラッカ

@Joonas:結構です。
ロバートハーベイ

13

「コメントで寛大に」

コメントは間違いなく良いことですが、あまりにも多くのコメントは、十分でないというよりも悪くないとしても同じくらい悪いです。どうして?不要なコメントが多すぎる場合は、コメントを調整する傾向があります。完全に自己文書化できるコードを作成できると言っているわけではありませんが、説明のためにコメントが必要なコードの方が望ましいです。


1
自己文書化コードは間違いなく素晴らしいです。ただし、単純な計算(return-typeまたはreturn-valueが何であるかを表すため)のようなものと一緒にコメントを付けるのが好きです。ただし、コメントにコード自体よりも多くの単語が必要な場合は、おそらくコードを書き直す時期です。
-sova

6
sovaがこれを置く方法に同意しなければなりません。コメントよりもクリーンなコードが望ましいです。
リウォーク

4
あなたはまだそこにある「なぜ」が必要です!

理由を説明するコメントが欲しいです。つまり、コードの意図をリバースエンジニアリングする際に考える必要が少なくなります。
すぐに

12

有害と見なされるGoTo

ステートマシンを実装している場合、GOTOステートメントは、「構造化プログラミング」アプローチよりも理にかなっています(読みやすさと効率的なコード)。新しい仕事で書いた最初のコードに1つだけでなく複数のgotoステートメントが含まれていたとき、同僚を本当に心配していました。幸いなことに、彼らはそれが実際にこの特定のケースで最良の解決策であることに気付くのに十分な知性を持っていました。

ルールに対する賢明で文書化された例外を許可しない「ベストプラクティス」は、単に怖いだけです。


16
単一のgotoステートメントなしでプログラミングを9年間続けています(先ほど述べたように、いくつかのステートマシンを含みます)。心を新しいアイデアに広げてください。
リウォーク

3
@Mathieu M.-同意-GOTOと構造化制御ステートメントを混在させることは賢明ではありません。(これは純粋なCであり、問​​題ではありませんでした。
MZB

1
@ Stargazer2-シンプルなFSMでは、状態を変数に入れ、プロシージャを呼び出すためのインデックスとして使用するかどうか(計算されたGOTOと同じではないかどうか)は、プログラムカウンターを使用するよりも明確/高速なコードを提供するかどうかに依存しますFSM状態として。私はこれをほとんどの状況で最善の解決策として主張するのではなく、状況によっては最善の解決策であると主張しています。別のアプローチに心を広げてください。
MZB

5
@MZB、関数呼び出しも単に計算されたGOTOであることに同意しませんか?同じことがfor / while / if / else / switchコンストラクトにも当てはまります。言語デザイナーは、理由のためにプログラムカウンターへの直接の変更を抽象化します。gotoを使用しないでください。
リウォーク

3
ステートマシンを直接実装することは、おそらくアンチパターンです。ステートとトランジションを文字通り表現せずにステートマシンを使用する方法はたくさんあります。たとえば、import re
SingleNegationElimination

12

コードをテスト可能にするための犠牲

私はコードをテスト可能にするために多くのフープを飛び越えますが、選択肢が与えられないならふりをしません。しかし、これらは「ベストプラクティス」であるという考えを推進している人々をよく耳にします。これらのプラクティスには以下が含まます(.Netの言語で記述されていますが、他の言語にも適用されます)

  • クラスごとにインターフェイスを作成します。 これにより、処理するクラス(ファイル)の数が2倍になり、コードが複製されます。はい、インターフェースプログラミングは良いですが、それはパブリック/プライベート指定子が意図しているものです。
  • 起動時にインスタンス化されないすべてのクラスには、ファクトリが必要です。 明らかに、new MyClass()ファクトリを書くよりもはるかに簡単ですが、今ではそれを作成するメソッドを単独でテストすることはできません。この事実がなければ、私が今やるファクトリークラスの数は1/20になります。
  • すべてのクラスをパブリックにします。これにより、クラスでアクセス指定子を使用するという目的が失われます。ただし、非パブリッククラスは他のプロジェクトからアクセス(したがってテスト)できないため、他の唯一のオプションは、すべてのテストコードを同じプロジェクトに移動することです(したがって、最終製品でリリースします)。
  • 依存性注入。明らかに他のすべてのクラスにフィールドを使用する必要があり、コンストラクターパラメーターは、必要なときにそれらを作成するよりもはるかに多くの作業が必要です。ただし、このクラスを単独でテストすることはできません。
  • 単一責任の原則。これは非常に多くの頭痛の種を引き起こしたので、独自の回答に移しました。

これを修正するにはどうすればよいでしょうか?言語アーキテクチャを大幅に変更する必要があります。

  • クラスをモックする機能が必要です
  • 別のプロジェクトから、内部クラスのプライベートメソッドをテストする機能が必要です(これはセキュリティの脆弱性のように思えるかもしれませんが、テスト対象者にテスタークラスの名前を強制する場合、問題は発生しません)
  • 依存性注入(またはサービスの場所)、および既存のファクトリパターンと同等のものは、言語の中核部分である必要があります。

つまり、テスト容易性を念頭に置いてゼロから設計された言語が必要です。


TypeMockについて聞いたことがないと思いますか?クラス、プライベート、静的(ファクトリー)、何でもモックできます。
アロングラネク

@Allon:私は持っていますが、それは無料とはほど遠い、ほとんどの人にとっては選択肢ではありません。
BlueRaja-ダニーPflughoeft

多くのファクトリクラスを記述する必要がある場合、何か間違ったことをしていることになります。スマートDIライブラリ(C#のAutofacなど)は、ボイラープレートを自分で記述することなく、Func <T>、Lazy <T>、デリゲートなどを工場で利用できます。
gix

10

アプリケーションを層に分離します。データ層、ビジネス層、UI層

私がこれを嫌う主な理由は、この方法に従うほとんどの場所が、それを実現するために非常に脆弱なフレームワークを使用することです。IE UIレイヤーは、ビジネスレイヤーオブジェクトを処理するために手動でコーディングされます。ビジネスレイヤーオブジェクトは、ビジネスルールとデータベースを処理するために手動でコーディングされます。

なぜこれが悪いのですか?最も一般的な拡張要求は、おそらく「画面XにYを持つフィールドが必要です」です。バング!すべてのレイヤーに影響を与える新機能があり、異なるプログラマーでレイヤーを分離すると、非常に簡単な変更のために、複数の人やグループが関与する大きな問題になりました。

さらに、私はこのようなことをする議論に何回参加したかわかりません。「名前フィールドの最大長は30に制限されています。これはUIレイヤー、ビジネスレイヤー、またはデータレイヤーの問題ですか?」そして、100の議論があり、正しい答えはありません。答えは同じです。すべてのレイヤーに影響します。UIをバカにしてすべてのレイヤーを通過する必要はなく、データベースで失敗します。これは、ユーザーがエントリが長すぎるとわかるためです。変更すると、すべてのレイヤーなどに影響します。

「レイヤー」も漏れる傾向があります。レイヤーがプロセス/マシンの境界(IE Web UIおよびビジネスバックエンドロジック)によって物理的に分離されている場合、ルールが複製され、すべてが適切に機能するようになります。つまり、ユーザーが応答するUIを必要とするため、一部のビジネスロジックは「ビジネスルール」であるにもかかわらず、UIで終了します。

使用するフレームワーク、または使用するアーキテクチャが、小さな変更や漏洩に対して耐性があり、つまりメタデータに基づいており、すべてのレイヤーで動的に調整されていれば、それほど苦痛はありません。しかし、ほとんどのフレームワークは王室の痛みであり、小さな変更ごとにUIの変更、ビジネスレイヤーの変更、データベースの変更が必要であり、この手法が想定しているよりも多くの作業と少ないヘルプを引き起こします。

私はおそらくこれに非難されますが、そこにあります:)


+1、私の雇用の最後の場所のように聞こえます。私は原則として階層型アプリケーションを尊重しますが、あまりにも多くの人がそれが意味をなさないときそれを特効薬のように扱います。ほとんどのビジネスソフトウェアのビジネスロジックの量は驚くほど少なく、その機能は比較的単純です。これにより、階層化ビジネスロジックが定型コードの悪夢になります。クエリはビジネスロジックであるため、多くの場合、データアクセスとビジネスロジックの間の線がぼやけることがあります。
maple_shaft

...さらに、ほとんどのショップはUIロジックまたはプレゼンテーションロジックの認識に絶対に失敗します。彼らは典型的なCRUDアプリケーションにビジネスロジックがどれだけ存在するかを理解していないため、ロジックの大部分がプレゼンテーションロジックとしてプレゼンテーションレイヤーに存在する場合、何か間違っている必要があると感じています。ビジネスロジックとして誤って識別された後、ユーザーはさらに別のサーバー呼び出しのためにサーバーにプッシュします。シンクライアントは、プレゼンテーションロジックを使用できます。(dropDown3でoption1が選択されている場合、textField2を非表示にします)。
maple_shaft


7

ユーザーストーリー/ユースケース/ペルソナ

 

あなたが慣れていない業界向けにプログラミングしているとき、これらの必要性を理解していますが、完全に実装された場合、それらは企業になりすぎて時間の無駄になると思います。


7

80文字/行の制限は馬鹿で​​す

GUI側の最も遅いランナーのペースに合わせていくつかの妥協を行う必要があることを理解しています(画面解像度の制限など)が、その規則がコードのフォーマットに適用されるのはなぜですか?

参照...右端のピクセル境界の外側の仮想画面スペースを管理するために作成された水平スクロールバーと呼ばれるこの小さな発明がありました。構文の強調表示やオートコンプリートなどの優れた生産性向上ツールを作成した開発者は、なぜそれを使用しないのですか?

確かに、VT220端末の疲れた古い制限に従う* nix恐竜によって宗教的に使用されるCLIエディタがありますが、なぜ私たちの残りは同じ標準に拘束されていますか?

私は言う、80文字の制限をねじ込みます。恐竜が1日中emacs / vimをハッキングするのに十分なほど壮大である場合、CLI IDEに自動的に行を折り返すか、水平スクロール機能を提供する拡張機能を作成できないのはなぜですか?

1920x1080ピクセルモニターは最終的には標準になり、世界中の開発者はまだ同じ制限の下で生活していますが、それ以外の理由は関係ありません。それは、プログラミングを始めたばかりの年長者から言われたものです。

80文字の制限はベストプラクティスではありませんが、ごく少数のプログラマーにとってはニッチなプラクティスであり、そのように扱われるべきです。

編集:

多くの開発者がマウスジェスチャーを必要とするため、水平スクロールバーを好まないことは理解できます。現代のディスプレイを使用している私たちにとって、列幅の制限をより大きな数(80以上)に増やしてはどうでしょうか。

800x600のコンピューターモニターがほとんどのユーザーの標準になったとき、Web開発者は大多数に対応するためにWebサイトの幅を増やしました...開発者が同じことをできないのはなぜですか。


1
ニースGWBロジックを___で@Orblingするのは悪角度です。hScrollが嫌いです。col-widthを80文字に制限する正当な理由はありますか?なぜ160または256ではないのですか?ほとんどの開発者はVT220ターミナルを廃止し、puTTYに置き換えたため、プログラムで幅を拡張できると想定できると思います。
エヴァンプレイス

4
80文字の制限に従うことをお勧めします。水平方向のスペースを増やしてすぐに、他のドキュメントと並べて追加のドキュメントを開くようにします。4方向にスクロールするのは嫌だ。また、80文字の大文字で読みやすいコードを書くことを余儀なくされることにしばしば気付きました。
フィリップデュパノビッチ

2
どのように印刷しますか?

5
申し訳ありませんが、これに反対する必要があります。私は本当に長い長い線が嫌いです-それはより多くの目の動きを必要とします、それはスクロールするためにマウスジェスチャーを必要とします、それは線の終わりに少し微妙なものを見るのがより困難です。約99%のケースでは、いくつかの(より短い)行に物を走らせる明確な方法があり、より明確で読みやすくなっています。80文字はarbitrary意的であり、「パンチカードの時代にはそうだったから」ですが、上記の理由により、ほとんどの場合、内部で動作するのに妥当なフレームワークです。
すぐに

3
2スペース分インデントします。また、自動インデントトラッカーを備えたエディターを使用します。私は何年もそのようにしてきましたが、大したことはありません。(適切なモードのEmacsがここで役立ちます。)
すぐに

5

測定、測定、測定

結構ですので、離れて測定してください。しかし、パフォーマンスのバグを分離するために、測定は連続的な除去と同様に動作します。ここに私が使用する方法があります。

私は、メジャーとメジャーの「知恵」の源を突き止めようとしてきました。背の高い十分な石鹸箱を持っている人がそれを言って、今では旅行します。


5

私の先生は、すべての識別子(定数を含まない)を小文字で始めるよう要求していますmyVariable

些細なことのように思えますが、多くのプログラミング言語で大文字で始まる変数が必要です。私は一貫性を大切にしているので、すべてを大文字で始めるのが私の習慣です。


9
私は、キャメルケースを必要とする教師がいました。彼は、それがrealWorldで使用するものだと主張したからです...同時に、仕事で2つの異なるグループでプログラミングしていました。両方のグループがunder_scoresを主張しました。重要なのは、グループが使用するものです。彼は自分を主任プログラマーと定義することができ、すべてが私の本で大丈夫だったでしょう-私たちは彼の慣習に従います-しかし、彼は他の有効なものがないかのように常に「現実世界で物事が行われる方法」として彼の意見を与えていました仕方。
xnine

@xnineこのサイトにはまだあなたのコメントを評価するのに十分な担当者がいないので、この承認のコメントで
Maxpm

5
キャメルケース(最初の文字は小文字)は、Pascalのケース(大文字で始まるすべての単語の最初の文字)と同様にかなり一般的な規則です。ほとんどの言語では、キャメルケースはプライベート/内部変数で使用され、PascalCaseはクラス、メソッド、プロパティ、ネームスペース、パブリック変数で使用されます。別の命名スキームを使用する可能性のあるプロジェクトにすぐに慣れることは悪い習慣ではありません。
エヴァンプライス

2
参考までに。一部の言語は、変数の最初の文字が大文字かどうかから意味を推測します。そのような言語では、最初の文字が大文字の場合、変数は定数として扱われます。変数を変更しようとするとエラーがスローされます。
ベリンロリチュ

1
行く、パブリックメソッドやクラスのメンバは大文字で始まります。小文字のプライベートなもの。
ジョナサンレフラー

5

シングルトンを使用する

何かのインスタンスを1つだけ持つ必要がある場合。私はこれ以上反対できない。シングルトンは決して使用せず、一度だけ割り当てて、必要に応じてポインター/オブジェクト/参照を渡します。これをしない理由はまったくありません。


2
それは、シングルトンに対するあなたの実際のスタンスに関して私をかなり混乱させたネガティブなものです。
ポール・ブッチャー

1
@Paulブッチャー:私はシングルトンを嫌い、それは使用しないでください

1
@rwong:個人的には、どんな理由も正当な理由だとは思いません。通常のクラスとして記述してください。実際、怠zy以外にシングルトンを使用し、悪い習慣やデザインを促進する理由はありません。

6
Singeltonsの使用がベストプラクティスであると言うのは誰ですか?
フィルマンダー

2
特に、起動時に運用構造が割り当てられて満たされ、基本的にプログラムの実行中は読み取り専用になる場合に、シングルトンには場所があります。ただし、その場合、ポインタの反対側のキャッシュになります。
ティムポスト

5

反復子としてunsigned intを使用する

彼らはいつsigned intを使用するほうがはるかに安全でバグが少ないことを知るでしょう。配列インデックスが正の数値のみであることが非常に重要であり、4-5が4294967295であるという事実を見落として喜んでいるのはなぜですか?


さて、今私は興味があります-なぜあなたはそれを言うのですか?私は少し馬鹿げていると感じています-あなたのステートメントをバックアップするためにいくつかのコード例を提供できますか?
ポールネイサン

4
@Paul Nathan:バグが発生する限り、ここに1つの例があります:for(unsigned int i = 0; i <10; i ++){int crash_here = my_array [max(i-1,0)];}
AareP

@AareP:確かに-私はあなたがunsigned int型のときという事実参照していると推定0することによりデクリメントされ1、あなたが実際に終わる正の最大値 unsigned int型に格納してもよいということを?
アダムペインター

1
@Adam Paynter:はい。これはc ++プログラマーにとっては普通に思えるかもしれませんが、「unsigned int」は正の数のみの悪い「実装」です。
AareP

小型の組み込みマシンではお勧めできません。頻繁に署名されていないintは、より小さく高速なコードを生成します。コンパイラとプロセッサに依存します。
すぐに

4

メソッドは1つの画面より長くしないでください

私は単一責任の原則に完全に同意しますが、なぜ人々はそれを「機能/メソッドは論理的な粒度の最高レベルで単一の責任しか持ち得ない」ということを理解しているのでしょうか?

アイデアはシンプルです。関数/メソッドは1つのタスクを実行する必要があります。その関数/メソッドの一部を他の場所で使用できる場合、それを独自の関数/メソッドに切り分けます。プロジェクトの他の場所で使用できる場合は、独自のクラスまたはユーティリティクラスに移動して、内部でアクセスできるようにします。

コード内で1回だけ呼び出される27個のヘルパーメソッドを含むクラスを作成するのは愚かであり、スペースの無駄遣い、不必要な複雑さの増加、膨大な時間の無駄遣いです。忙しいリファクタリングコードを見たいが、あまり生成しない人にとっては、より良いルールのように思えます。

これが私のルールです...

何かを達成するための関数/メソッドを書く

コードをコピー/貼り付けようとしている場合は、そのコードの関数/メソッドを作成する方が良いかどうかを自問してください。関数/メソッドが別の関数/メソッドで一度だけ呼び出される場合、そもそもそれを持っていることに本当にポイントがありますか(将来より頻繁に呼び出されるでしょうか)。デバッグ中に関数/メソッドのジャンプを追加または追加することは価値がありますか(つまり、追加されたジャンプはデバッグをより簡単または難しくしますか?)

200行を超える関数/メソッドを精査する必要があることに完全に同意しますが、一部の関数は同じ行で1つのタスクのみを実行し、プロジェクトの残りで抽象化/使用できる有用な部分が含まれていません。

API開発者の観点から見ます...新しいユーザーがコードのクラス図を見る場合、その図のどの部分がプロジェクト全体の中で意味を持ち、いくつだけが次のように存在するでしょうか。プロジェクト内部の他のパーツのヘルパー。

私が2人のプログラマーから選択する場合:最初のプログラマーは、やり過ぎを試みる関数/メソッドを作成する傾向があります。2番目は、すべての関数/メソッドのすべての部分を細かく細分化します。私は最初の手を選びます。1つ目はより多くのことを実行し(つまり、アプリケーションのより多くの部分を書く)、彼のコードはデバッグしやすくなり(デバッグ中の関数/メソッドのジャンプの回数が少なくなるため)、コードの見た目とコードの動作の完璧さ。

不要な抽象化を制限し、オートコンプリートを汚染しないでください。


この。私はかつていくつかの長い関数をいくつかにリファクタリングしましたが、それらのほとんどすべてが元のコードのほとんどすべてのパラメーターを必要としていたことを理解するためだけでした。パラメーターの処理は非常に苦痛だったため、古いコードに戻る方が簡単でした。
l0b0

3
これに対する1つの反論は、大きなメソッドの一部を個別の呼び出しにリファクタリングすると、大きなメソッドが読みやすくなるということです。メソッドが一度だけ呼び出された場合でも。
ジェレミーハイラー

1
@ジェレミーどうやって?コードのセクションを抽象化して独自のメソッドに配置すると、コードのチャンクの先頭にそれが何であるかを説明する1行のコメントを配置するよりも読みやすくなりますか?コードブロックがそのコードセクションで1回だけ使用されると仮定します。それは本当にそのほとんどのプログラマは、彼らはそれを読んでいる間、コードの作業の部品を分解および/または少数の1行が、それは彼らができない場合は何をするか、それらを思い出させるコメント配置するのは難しいですか?
エヴァンプレイス

4
@Evan:コードの一部を関数に入れると、効果的に名前が付けられます。うまくいけば、そのコードが何をするのかをうまく説明できます。これで、そのコードの一部が呼び出されるたびに、アルゴリズム自体を分析して理解する代わりに、コードの機能を説明する名前見ることができます。うまく行けば、これによりコードの読み取りと理解が非常に容易になります。
sbi

1
+1して、できればもっとあげます。単一の関数で1000行のCコードの塊(たとえば、大規模なswitch()を持つパーサー)には何の問題もありません。意図は明確でシンプルです。すべての小さな破片をつぶし、それらを呼び出すと、物事を理解するのが難しくなります。もちろん、これにも制限があります。...賢明な判断がすべてです。
すぐに
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.