最近、開発者間の意見の対立のため、オフィスで話し合いがありました。一方(サイドS)は技術的解決策を-一般的に-可能な限り具体的にする必要があると主張し、他方(サイドG)は一般化された解決策が好ましいと主張しました。
短くするようにします。ファイル転送を処理し、転送ごとに3つのファイル(log.txt、details.txt、receive.pdf)の保存を開始する必要があります。使用するファイルテーブルはすでにありますが、転送とファイルの間に1対多の関係を作成するには別のテーブルが必要であることに同意します。
サイドGは、あらゆるタイプのリソースにファイルを添付できる一般的なresource_attachmentsテーブルを作成することを提案しました。
resource_attachments
-id:int
-entityId:int
-entityType:文字列
-fileId:int
-種類:文字列
サイドSはこれに同意せず、次のような特殊なtransfer_attachmentsテーブルの作成を提案しました。
transfer_attachments
-id:int
-transferId:int
-fileId:int
-種類:文字列
サイドSの1つの議論は、リソースは可能な限り具体的である必要があり、その役割と属性、および可能な値が明確であるため、新しい開発者は問題なくリソースを理解できるということです。
サイドGの議論は、より一般化されたアプローチはより幅広い機能を提供するというものでした。役割が何であれ、どのリソースにもファイルを添付できます。
実際の違いは非常に小さいですが、ここで起こっているいくつかの基本的なことがあります(これは哲学的になるところです)。部屋の1人が、ジェネラライザーはRubyの専門家であり、スペシャライザーはJavaの専門家であることをはっきりと観察しました。 Rubyは動的型付けのインタープリター言語であり、Javaは静的型付けのコンパイル言語です。
私はその問題が非常に興味深いことに気付き、どちらのアプローチが好ましいか疑問に思いました。専門的または一般化されたソリューション、および考慮すべき問題は何ですか?
ソリューションの技術的な部分についてのみ話していることに注意してください。これは、エンドユーザーエクスペリエンスとは関係ありません。
いつものように、答えは次のとおりです。考慮すべき問題はたくさんあります。
より一般的なソリューションが実装が簡単で、追加コストが最小限でリスクがゼロの場合は、必要性がわかっていない場合でも、それを実行することをお勧めします。 OTOH一般的なソリューションのコストが大幅に高い場合は、十分に強力な正当化(=顧客の付加価値)が必要です。そうでない場合は、 投機的な一般性 になります。
通常、より一般的なソリューションは(常にではありませんが!)より複雑なコードを意味するため、長期的には理解と変更が困難であることを常に心に留めておく必要があります。したがって、考慮すべき要素は実装コストだけではありません。ライフサイクルが長い製品のメンテナンスコストは、開発コストの多様性を上回っています。 OTOHは、1度だけまたは短時間で使用することを目的としており、明らかにより一般的にすることは無意味かもしれません。 (ただし、ソフトウェアの実際の寿命は、当初の計画よりも大幅に長くなることがよくあります。)
また、上記の「常にではない」ケースには、問題を注意深く分析した結果、既知の解決策が存在する、より一般的でよく知られている問題のサブケースまたは別のビューであることが明らかになった場合、またはソリューションの実装が大幅に容易な場合も含まれます。 。このような場合、余分な分析と設計の労力は、より単純でクリーンなコードで報われるだけでなく、より高速で、リソースの消費が少なくなる可能性があります。これらのケースは、ルールではなく例外ですが、それでも言及する価値があります。
私が言及するのを忘れたもう1つの側面は、ソリューションを将来より一般的にするための潜在的なコストです。多くの場合、コードを今一般的にするよりも後でリファクタリングする方が大幅にコストがかかるわけではありません。これは、決定をできるだけ遅くすることを示唆しています。そのような決定の経済は現在100ドルを節約しており、最悪の場合、数年後に110ドルを支払う必要があるというリスクがあります(しかし、あなたはその100ドルを投資し、それ以来それ以上の収入を得ているかもしれません)、しかし、最良の場合、あなたは何も支払わない。
ただし、最初から一般的なソリューションを設計するよりも、後でリファクタリングを行うとコストが高くなり、リスクが高くなり、困難になる領域が(少なくとも)1つあります。それはデータベースです。テーブルの構造を変更し、ビジネスに不可欠な大量のデータを新しい構造に移行することは、単純な場合でも簡単なことではなく、場合によってはまったく不可能です。そのため、DBスキーマを設計するときは、より一般的なソリューションに移行することをお勧めします。これには、将来の拡張の可能性を幅広く含めることができます。
読み始めるための良いスタートについては、 このウィキペディアのリスト を参照してください。理想的には、あなたは 懸念の分離 を見ています。より一般的なソリューションにはプロジェクト間での再利用には利点がありますが、問題があります。
データベースはデータの保存に関係しているため、データが何であるかを知るのはデータベースの仕事です。データを保持する1つのフィールドと説明を保持する1つのフィールドを持つものを格納できるテーブルは必要ありません。
表現のルール に従います。データはそれが何であるかを言う必要があります、さもなければそれは役に立たないです。データが実際に一般的である場合にのみ、一般的なものとして扱う必要があります。
最後に、 悪い方が良い 。最初にソリューションを構築するときに、ソリューションの一般化についてすべてを知ることはできません。実際に何が必要かわからないので、そうしようとするソリューションを構築することは、ほんのわずかな利益のためにはるかに多くの作業です。
私の答えは、一般化されたソリューションを実装するための追加の労力と複雑さに依存すると信じているという点で、最終的にはペーテル・トロクの答えと似ています。
これを実装の引数としてフレーミングすることは誤りですが、プログラミング言語によって反対側の2つにラベルを付け、論理的で前向きな考え方のステレオタイプを作成するのに危険なほど近いと彼らが考えるように定義しますRuby =開発者とトロリー、頑固で愚か者Java開発者。
これは、クライアントのニーズを満たす方法についての技術的な議論ではなく、クライアントが自分の欲しいものを本当に知ることはほとんどなく、頻繁に考えを変えることはほとんどなく、考えを変えても結果が出ないことを期待することもできます主要なリファクタリングの努力で。この問題は、私の心の中の関心の分離(それ自体のメリットで重要です)ではなく、現実の現実的な解釈の1つです。
マヤのカレンダーの厳密な解釈をモデル化し、それを厳密に設計して実装している場合は、おそらく設計を具体的にするのが正しいでしょう。特にマヤの人々がこの地球上にもはや存在しないことを考えると、マヤの暦が変わらないことは事実上保証されています。一方、ドキュメント管理システムを設計していて、保存したいドキュメントはJPEGファイルだけだと言われた場合は、画像の特殊性に基づいてテーブルを設計しないほうが賢明でしょう。デモを行うと、彼らはおそらくPDFも保存したいと思うでしょう。私はそこで自分のためにもっとたくさんの仕事を作成しました。
これは、言語とは関係なく、急速に変化するビジネス要件と落ち込みがちで信頼性の低いクライアントのソフトウェア開発の現実とは関係ありません。