「設定より規約」は基本的なプログラミングの原則に違反していませんか?


51

私はWPF MVVMフレームワークCaliburn.Microを見ていましたが、多くの標準的なものは命名規則に基づいていることを読みました。

たとえば、ViewのプロパティをViewModelのプロパティに自動バインドします。これは便利なように見えますが(定型コードを削除します)、私の最初の本能的な反応は、このコードを読む新しいプログラマーにとって完全に明白ではないということです。つまり、アプリケーションの機能は、独自のコードによって完全に説明されるのではなく、フレームワークのドキュメントによっても説明されます。

編集:

したがって、このアプローチは設定よりも規約と呼ばれます。これに関する質問が見つからなかったため、質問を変更しました。

私の質問は:

構成に対する規約は物事を単純化する正しい方法ですか、それともプログラミングの原則に違反していますか(もしそうなら、どの原則に違反していますか)?


8
ほとんどのアプローチ/原則は、他のアプローチ/原則にある程度違反しています。それは主に優先順位とトレードオフの問題です。
ヨアヒムザウアー

1
確かに、質問に記載されている違いは少し奇妙であるため、Convention over Configurationを使用する場合の特定のトレードオフと、おそらく違反する原則に興味があります。
Geerten

ここでは、ソフトウェアのトレーサビリティの概念が関連しています。プログラマはgrepなどのツールに依存していますが、生成されたコードの使用を追跡するためのより優れたツールが必要です。たとえば、ツールは、cssクラス「user-id」が生成されたメソッドgetUserId()およびテーブル列user_idに関連していることをより明確にする必要があります。
マクニール

回答:


49

「アプリケーションは独自のコードで完全に説明されるべきだ」と基本的なプログラミングの原則とは考えていません。アプリケーションのコードを見ただけでは説明できないことがたくさんあります。プログラミング言語自体の基本的な事項(構文とセマンティクス)を知ることとは別に、規則を知る必要があります。Javaの識別子が大文字で始まる場合、それは型です。知っておく必要があるこれらの規則はたくさんあります。

構成より規約は、プログラマーが物事について下さなければならない決定の量を減らすことです。これは明白なこともあります-型の大文字化をプログラムの先頭で宣言する必要がある言語を考えている人はいませんが、他のことについてはそれほど明白ではありません。

規則と構成のバランスを取ることは難しい作業です。規則が多すぎると、コードが混乱する可能性があります(たとえば、Perlの暗黙変数を使用します)。プログラマー側の自由が大きすぎると、システムを理解しにくくなる可能性があります。なぜなら、あるシステムから得た知識は、別のシステムを勉強するときにほとんど役に立たないからです。

Eclipseプラグインを作成するときは、コンベンションがプログラマーを助ける場所の良い例です。一度も見たことのないプラグインを見ると、すぐに多くのことを知っています。依存関係のリストはMANIFEST.MFにあり、拡張ポイントはplugin.xmlにあり、ソースコードは「src」の下にあります。これらのことを定義するプログラマ次第であれば、Eclipseプラグインはすべて異なり、コードナビゲーションははるかに困難になります。


4
+1:ソフトウェア開発はそのままで十分に複雑です。制御できるものの複雑さを回避できる場合は、そうしてください。絶対に必要な場所の複雑さを軽減します。
scrwtp

1
違いとバランスについての明確な説明をありがとう。
Geerten

3
「Javaの識別子が大文字で始まる場合、それは型です。」-型が命名パターンではなく構文コンテキストに依存するかどうかにかかわらず、Java命名規則は「コンパイル構成」に影響しません。有効な例ですか?最後の例も正しくありません-それは「設定規約」ではなく「設定規約」に関するものです。あなたは正しいことを言っていますが、彼らはsubjの原則とはほとんど関係がありません。
デン14年

4
例を分析しすぎないでください。それらは単なる例です。最初のものは慣例の単なる例であり、最後のものは慣例が良い例です。Perlの例は、規則(暗黙)が多すぎるのは悪いことです(IMO、追加する必要があります)。
JesperE

1
私が嫌いなのは、設定に対する慣習が設定なしの慣習になるときです...後者の場合、コードベースに閉じ込められる傾向があり、他のツールと統合するのが難しい場合があります。
アンディ

77

@JesperEに+1を付けて、何かを追加したい:

プログラミングの原則に違反していますか

はい、「設定より規約」は「暗黙よりも明示的である」という原則に違反しています(例えば、「Zen-Of-Python」をご覧ください)。

一方、反対の「規約よりも設定」は「単純なものは複雑なものよりも優れています」に違反する傾向があり、さらに悪いことに、設定でもコードで使用される名前を繰り返す必要があるため、DRY原則に違反します。


4
それが質問に対する最も直接的な答えです!
ヨアヒムザウアー

これは、最も支持された2つの中の実際の正解です。
デン14年

「明示的は暗黙的よりも優れている」ための+1
ジャスティンオーム14年

12
この答えについての私のお気に入りの部分は、良いソフトウェア開発の原則がしばしば互いに緊張しているよりも、暗黙のうちに現実を浮き彫りにしていることです。エンジニアリングとは、特定のコンテキストとアプリケーションに合わせてこれらの緊張を適切にバランスさせることです。
クリスクリチョ14

いい答えだ。@Chris Krychoのコメントを拡張するために、ソフトウェアの標準または原則の良い点は、選択できるものが非常に多いことです。:-)
user949300

9

「設定より規約」の一部は、適切なデフォルトに要約されています。標準以外の目的で使用するために何かを設定するだけでよいはずです。ここでStrutsとRailsを比較する必要があります。Railsでは、「アクション/画面」をフォルダーに入れる必要がありますが、それらは機能します。Strutsでは、それらをフォルダに配置する必要がありますが、アクション名、JSPファイル、フォーム名、フォームBeanを作成し、Struts-configでこれら3つがどのように連携するかを指定する必要があります。 xml ANDフォームがリクエストに属することを指定します(RESTful)。それだけでは不十分な場合、form / form-b​​eanマッピングにはStruts-configに独自のセクションがあり、同じファイル内のアクションセクションに個別にマッピングされ、すべて動作するためにJSPファイル内の手書き文字列に依存します正しく。各画面について、それは、あなたがする必要のない少なくとも6つのことであり、間違いを犯す多くの機会です。必要に応じてRailsでこれらのほとんどまたはすべてを手動で設定できると思いますが、Strutsの開発時間の2/3は、不要な複雑なレイヤーの構築と維持に費やされます。

公平を期すと、Struts 1は、人々がデスクトップとWebの間でアプリケーションを移植するときに設計されました。Strutsの柔軟性は、Railsが実行するすべての機能に加えて、デスクトップアプリケーションに必要なすべての機能に適しています。残念ながら、その柔軟性を可能にする構成の山は、Webアプリまたはデスクトップアプリだけを作成する必要がある人にとっては巨大なチェーンです。

私はどこかで次の一歩を踏み出し、「コードを介した構成」と主張しましたが、それが論理的に極端になったことを見た結果、構成は新しいコーディング言語になります。これは、重要な方法で飼い慣らされることなく、複雑さが押し進められるシェルゲームでした。また、適切に設計されたプログラミング言語が持つすべての型チェックやその他のセーフティネットに感謝しました。スペースやアポストロフィを追加してもエラーメッセージが表示されない中途半端な構成ファイル形式は、一連の編集ツールとそのために作成された高品質のコンパイラを備えた高品質のプログラミング言語の改善ではありません。

賢明なデフォルトを持つことは、拡張性とモジュール性に関する理論上の原則に違反することは想像できません。Ruby / Railsプログラマーは、すべての構成が複数のXMLファイルで明示的に行われるStruts 1のようなフレームワークに切り替えるよりも、すぐに注目を集めます。Rails vs. Struts in GENERALを主張しているわけではありませんが、その慣習は生産性の大きな勝利になる可能性があります。これら2つのテクノロジーは、私が出会った中で最も極端な現実世界の比較です。

まったくJavaで作業している場合は、Joshua Blochの「Effective Java」第2項「多くのコンストラクターパラメーターに直面したときにBuilderを検討する」pp。11-16を確認してください。ほとんどの場合、一部のパラメーター(構成)は必須で、一部はオプションです。基本的な考え方は、必要な構成のみを要求し、ユーザー(別のプログラムの場合もあります)に必要に応じて追加オプションを指定させることです。1か月前にこのパターンを使用して大量のコードを整理しましたが、確実に輝きます。


7

つまり、アプリケーションの機能は、独自のコードによって完全に説明されるのではなく、フレームワークのドキュメントによっても説明されます。

フレームワークを使用するアプリケーションの機能は常にフレームワークに依存しますが、構成に関する規約はその点で違いを生じません。

私の経験では、設定より規約によりコードが読みやすくなるだけでなく、微妙なバグ(特にコピー-貼り付け-バグ)を導入する可能性が減ります。

たとえば、フレームワークAで、イベントFooBarがの呼び出しをトリガーすると仮定しましょうhandleFooBar。別のフレームワークBでは、この相関はXMLファイルのどこかに設定されます。

だから、Aでは、単に

handleFooBar() {
   ...
}

また、FooBarのスペルミスがない限り、FooBarが発生するたびに呼び出されます。

Bでは、再び

handleFooBar() {
   ...
}

だけでなく

<eventconfiguration>
  <event>
    <type>FooBar</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

このように何百もの設定を行うと、次のような微妙なバグを偶然作成するのは非常に簡単です

<eventconfiguration>
  <event>
    <type>BarFoo</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

コピー&ペースト後、変更し<type>ただけで、変更を忘れたため<handler>です。

これらの構成ファイルは大きく単調なので、誰かが実際のプログラムコードで同様のバグを見つけるよりも、校正によってバグを見つける可能性は低くなります。


1
+1:繰り返し、退屈な書き込み、読みにくい、ほとんど常に明らかな構成を回避することはコンベンションオーバー構成の主な利点です。
ヨアヒムザウアー

-1

いくつかの原則に違反しているかもしれませんが、同時に最も基本的な設計原則の1つであるSRP(単一責任原則)に準拠しています。


2
規則の使用は、単一の責任とは関係ありません。コンベンションを使用して、100のことを行うことができます。
スアメア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.