どのような設計上の決定を下し、どのように裏目に出たのか聞きたいです。悪い設計上の決定のため、私はその悪い決定を永遠にサポートしなければなりませんでした(私もそれに参加しました)。これにより、1つの設計ミスが永遠にあなたを悩ませることに気づきました。経験豊富な人々から、どんな種類の失敗を経験し、彼らから何を学んだかを学びたいです。
これらの決定を繰り返さないようにすることで、他のプログラマーにとってこれが多くの助けになると確信しています。
あなたの経験を共有してくれてありがとう。
どのような設計上の決定を下し、どのように裏目に出たのか聞きたいです。悪い設計上の決定のため、私はその悪い決定を永遠にサポートしなければなりませんでした(私もそれに参加しました)。これにより、1つの設計ミスが永遠にあなたを悩ませることに気づきました。経験豊富な人々から、どんな種類の失敗を経験し、彼らから何を学んだかを学びたいです。
これらの決定を繰り返さないようにすることで、他のプログラマーにとってこれが多くの助けになると確信しています。
あなたの経験を共有してくれてありがとう。
回答:
私の間違いの1つから、DBの正規化を盲目的に追跡すべきではないことを学びました。可能ですが、場合によってはテーブルをフラットにする必要があります。
最終的には(モデルを介して)テーブルの負荷を管理することになり、テーブルのフラット化を少し行ってもパフォーマンスはそれほど良くありませんでした。
データベースで単一の文字をステータスなどに使用します。これにはまったく意味がありません。長いchar()またはnvarchar2()を使用するオーバーヘッドは、ネットワークおよびSQL呼び出しによって発生する解析に比べてわずかですが、文字は常に終了しますかなり難読化されているか、不足しています(ステータスではなく、その他のもの)。人間が読めるバージョンを入れるだけで、Javaモデル(私の場合)に値が一致する列挙型を含める方がはるかに優れています。
これは、時期尚早で不必要で盲目的な最適化の一種だと思います。単一の文字を使用すると、最近では世界が救われるかのように。ブール値/ビットをサポートしないデータベースのY / Nブール値は別として。
適切なデータアクセスレイヤーを開発せず、コード内のあらゆる場所にsqlを配置することで、何かを「すばやく」実行できるようにします。その後、プロジェクトが拡大し始め、要件が変化したため、悪夢になりました。当時DALが何であるかは知りませんでした。
...過去20年以上の「経験」のあるプログラマーがこれを行っているのを今でも見ていますが、うれしいです。
私の決断ではありませんでしたが(やや遅れて入社しました)、どこかで仕事をしていましたが、すべてのログメッセージの翻訳を含めてi18nを少し使いすぎました。
結果:
おっと。
デザインをやりすぎる。多くのUML図、特にすべての単一操作のシーケンス図を作成しますが、その多くは最終的には役に立たないことが判明しました。最終的に、不必要に詳細な設計/図をスキップして直接コーディングを開始することで、かなりの時間を節約できたことがわかりました。
私の最悪の設計決定は?1980年代に私は、実行時に解釈されるデータ入力画面用のテンプレートを作成するという素晴らしいアイデアを得たプロジェクトに取り組んでいました。悪い決定ではありません。入力画面の設計が簡単になりました。基本的には、データ入力画面に似たファイルを作成します。ラベルと入力フィールドを識別し、入力フィールドが英数字かどうかを識別するための特別なコードを使用します。次に、これらのファイルにさらに特別なコードを追加して、実行する検証を特定することにしました。次に、画面の条件付きビルドを許可するコードを追加しました。フィールドXは、ある条件が満たされた場合にのみ含まれます。等 最終的に、画面テンプレートを新しいプログラミング言語に変換し、式、制御構造、およびI / Oライブラリを完備しました。そして何のために?FORTRANを再発明するために多くの仕事をしました。より良い設計とより良いテストが行われた言語用のコンパイラーがいっぱいの棚がありました。実際にある程度の専門知識を備えた製品を構築するためにそのような努力を捧げたとしても、その企業は今日も営業している可能性があります。
オーバー熱心な(と呼ばれるYAGNIのアプリケーション列挙して、デザインをして、オブジェクト指向開発の落とし穴いずれかの賢明な人は要件がされたことを言うことができる環境では)間違いなく変更するつもり。そして繰り返し変更します。
すべてを現在の要件に正確に(ハード)コーディングした場合、「これはもっと一般的ではないでしょうか?」YAGNIマレットを使用すると、要件が大幅に変更されます(ただし、合理的に予想できる方法で)。それは、2週間で調整するのと20分間で調整するのとの違いになります。
更新:明確にするために、ここで起こったことからそれほど遠くない架空の例を示します。Stack Overflowはバッジをサポートするように設計されていますが、最初は4つのバッジしか考えられないと仮定します。わずか4つなので、サイト内のすべてのロジックで正確に4つのバッジのサポートをハードコーディングしました。データベース内、ユーザー情報内、すべての表示コード内。あなたが考えることのできないバッジは「必要ない」からですよね?次に、サイトが公開され、人々が新しいバッジの提案を開始するとします。各バッジ追加するのに最大2週間かかります。これは、あちこちで微調整するハードコーディングが多いためです。それでも、今日のリストより多くのバッジは「必要ない」ので、バッジの一般的なコレクションをサポートするリファクタリングはありません。そのような一般的なコレクションは、事前にこれ以上の時間を要したでしょうか?あまりない、もしあれば。
YAGNIは価値のある原則ですが、貧弱なデザインと不適切なハードコーディングを弁解するために(ab)使用すべきではありません。バランスがあり、経験があれば、それに近づいていると思います。
私は最悪の敵にそれを望んでいません。
過去2か月間でいくつかのSSISパッケージをビルドした後、私が開発したパッケージが配布およびデプロイできないことを知りました。特に、非Web、非SQL Serverライセンス環境で。
48時間以内に純粋な.NET POCOコードでSSISパッケージを書き直すか、目標の期限を守れない場合は、非常に悪い状況です。
OLEDBアダプターとSQL Adapatersを使用して、純粋な.NETコードで12時間以内に3つのSSISパッケージ(テストと開発に2か月かかった)を書き換えることができたことに驚かされます。
SSISは、SQL Serverライセンス(具体的にはDTSPipeline.dll)がインストールされていない場合、配布できず、クライアントマシンからパッケージを実行しません。これは事前に知っておくといいでしょう。MSDNで免責事項を(細字で)今見ています。SQL-LICENSEDマシンのみのコードを使用してインターネット全体にサンプルコードがある場合、これは役に立ちません。基本的に、SSISパッケージをプログラムで実行するには、SQLサーバーと通信するWebサービスを作成する必要があります。実行中のマシンにSQLライセンスがインストールされていない限り、純粋な.NETコードからそれらを実行することはできません。それはどれほど非現実的ですか?Microsoftは、SQL Serverのインストールが必要なマシンからSSISを使用することを本当に期待していますか?なんと2ヶ月という無駄。
私の会社は、この小さな活字「落とし穴」のためにSSISを二度と使用しません。
展開メカニズム/モデルをできるだけ早く定義しない。
2週間の休暇に行く前に、「面白い」イースターエッグをコードに入れました。私が戻ってきたとき、私はそれを読む唯一の人だと思っていました。
言うまでもなく、上司は私が留守中にレビューしたときに感動しませんでした。また、「イースターエッグ」の1つがASCIIで面白く描かれた顔を含んでいたとき、彼はさらに感銘を受けませんでした。
うーん...
私の会社にはウォーターフォールのような開発モデルがあり、ビジネスユーザーとビジネスアナリストがプロジェクトの要件を定義します。「大きな」プロジェクトの1つで、要件のスタックを取得しましたが、実装の詳細、具体的には会計システムで使用されるデータベーススキーマに関連する情報を含む多くの要件に気付きました。
実装は私のドメインであり、要件に含めるべきではないことをビジネスユーザーにコメントしました。結局のところ、彼らはビジネスであり、会計士が会計ソフトウェアを設計することだけが理にかなっているため、彼らは要件を変更することを嫌がりました。トーテムポーリングをはるかに下回っている卑劣な開発者として、私はthinkの代わりにやりたいと思っています。戦いながらも、要件を書き直すように説得することはできませんでした。変更に関するペーパーワークと赤テープが多すぎて面倒です。
だから、私は彼らに彼らが求めたものを与えました。少なくとも、それはかなり動作しますが、データベースは奇妙に設計されています:
不要な正規化がたくさん。5つまたは10のフィールドを含む単一のレコードは、3つまたは4つのテーブルに分割されます。それに対処することはできますが、個人的には、1:1のすべてのフィールドを1つのテーブルに取り込むことを望んでいます。
不適切な非正規化がたくさん。請求書データ以上を保存する請求書データを保存するテーブルがあります。フラグがInvoiceDataテーブルに論理的に関連していない場合でも、InvoiceDataテーブルにその他の多くのフラグを格納します。これにより、各フラグにはマジック、ハードコーディングされた主キー値、およびInvoiceDataテーブル内の他のすべてのフィールドが空になります。フラグはテーブル内のレコードとして表されるため、フラグを独自のテーブルにプルすることをお勧めします。
より多くの不適切な非正規化。特定のアプリ全体のフラグは不適切なテーブルの列として保存されるため、アプリのフラグを変更するにはテーブル内のすべてのレコードを更新する必要があります。
主キーにはメタデータが含まれます。そのため、varchar主キーが「D」で終わる場合、1つの値セットを使用して請求書を計算し、そうでない場合は別のセットで計算します。このメタデータを別の列にプルするか、値のセットをプルして別のテーブルに計算する方が理にかなっています。
外部キーは複数のテーブルに移動することが多く、「M」で終わる外部キーは住宅ローン勘定テーブルにリンクし、「A」で終わる外部キーは自動勘定テーブルにリンクする場合があります。データをMortageDataとAutoInsuranceDataの2つのテーブルに分割する方が簡単です。
私の提案はすべて、多くの嘆きと歯ぎしりで撃ち落とされました。このアプリは設計どおりに機能し、泥だらけの大きなボールですが、厄介なハッキング、特殊なケース、奇妙なビジネスルールはすべてソースコードに皮肉とユーモラスに文書化されています。
大学に戻って、私はシニアデザインプロジェクトに取り組んでいました。別の人と私はウェブベースのバグ追跡システムを書いていました。(画期的なものはありませんが、私たちはWebエクスペリエンスを望んでいました。)Javaサーブレットを使用して適切に動作しましたが、何らかの理由で、エラー処理メカニズムとして例外を使用することを選択する代わりに、エラーコードを使用します。
私たちが学年のためにプロジェクトを発表したとき、教員の一人が避けられないことを尋ねました。私は即座に答えを知った:「私は例外を使うだろう、それは彼らがそこにいるものだ」。
私が選択した方法ではありませんが、行ベースのXMLファイルを列ベースのHTMLレポートに変換するXSLTを作成しました。
IEでのみ機能し、動作をデコードすることは完全に不可能でした。それを拡張する必要があるたびに、信じられないほど難しく、何年もかかりました。
結局、私は同じことをする小さなC#スクリプトに置き換えました。