2012-03-15 11 views
1

別の質問が非常に広く尋ねられ一般的なようです。例えば、私はデータベースにいくつかのアカウントテーブルを持っています、それはアカウントテーブルと言うことができます。クライアント(デスクトップのwinformsアプリ)には、新しいアカウントを追加するための適切な機能があります。 UIの中には、テキストボックスとボタンがあります。DBとクライアント間のビジネスロジックの広がり

もう1つの要件は、アカウントの一意性です。だから私は2つの同じアカウントを追加することはできません。私の質問は、私はクライアント上でこのアカウントの存在を確認する(いくつかのクエリと結果を見て)か、新しいアカウントを追加してそこにアカウントの存在をチェックするためのストアドプロシージャを作成する必要があります。それは私のために、ちょうど格納されたprocを作る方が良いです、そこに私は必要なチェックをして、すべてのチェックの後に新しいアカウントを追加することができます。しかし、そこには長所と短所があります。例えば、procが生成すべきメッセージの言語を管理することは非常に困難です。私はすでに任意のデータベースの制約を持って


POSTのEDIT

、などの問題は、ユーザが存在アカウントを追加さ​​れているが、状況を処理する方法です。


POSTのEDIT 2

アカウントの一意性は、ビジネス・ロジックの単なる小さな一例として公開されます。私の質問は、そのアカウントドメイン上で複雑なビジネスロジックを処理することです。

どうすればこの誤解を管理できますか?

私の質問は基本的であり、実証済みの解決策であると信じています。私のツールはC#、.NET Framework 2.0です。事前に感謝、みんな!

+1

データベースの制約を使用して、アカウントの一意性を保証します。クライアントまたはストアドプロシージャのどちらでもありません。 –

+0

最初はデータベースの制約を使用していることがわかります。問題は、そこに存在するプロセス状況が存在アカウントを追加する方法です。 – kseen

+1

さて、いつでも 'System.Data.SqlClient.SqlException'をキャッチすることができます。ユーザーがデータを送信する前に確認したい場合(ユーザー名が使用されている場合は新しい電子メールを作成するとすぐに通知されます)、小さな関数や保存されたprocを作成して、ユーザーが離れるとすぐに確認する必要がありますテキストボックス –

答えて

0

このタイプのロジックは、通常、保守(テストを含む)のためにコードに保管されています。しかし、これが単なる使い捨てのアプリケーションであれば、最も簡単なものを実行してください。それが成長していくものなら、後でメンテナンスや変更を容易にするために、物事を現場に配置する方が良いでしょう。

私は、ストアドプロシージャの挿入/呼び出しを行ったAddAcountメソッドを持つAccountsRepositoryクラスを持っています。 HaLaBiが述べたように、データベース制約を使用すると、重複を挿入しようとすると失敗します。コード内でこの問題を処理する方法(メッセージを追加できないUIに戻す)を決定します。これにより、あなたはこのすべての周りにテストを置くことができます。あなたがdbで行った唯一の変更は、制約を追加することです。

Thrusdayの朝(私の緑茶の前)のちょうど私の2セント。多くのように - - データベースの方のように深く、できるだけロジックをプッシュすることは良いことであることを確認するために

「を、それが依存」です:)

+0

良い点。しかし、アカウントの一意性は非常に簡単なサンプルに過ぎません。ビジネスロジックのアカウントの複雑な要件はどうでしょうか?たとえば、クライアントコード(winformsアプリ)で実装しても問題ありませんが、別の(つまり、アプリケーションのコンソールバージョンやウェブサイトのように)私のアプリがこのアカウントで動作するようにしたい場合は、新しいアプリで再びロジック!だから、私は2つの側面(サーバーのDBサイトとクライアント側)からデータを保持するいくつかの方法を探しています。 – kseen

+0

あなたのDAO(データアクセスオブジェクト)からあなたのDBを分離する必要があります。3層。この方法では、データアクセスに関連するものを書き換えなくても、多くの異なるクライアント(コンソール、Webページ、Winform、WPFなど)を持つことができます。 –

+0

この3つの層をソリューションで異なるプロジェクトとして編成する必要がありますか? – kseen

0

私は答えはと思います。これは、ユーザーがそこにいかに侵入しようとしても、悪いデータを防ぎます。

これは、単純な言い方をすれば、無効なトランザクションを試行するときにTRY-FAIL-RECOVERが発生するアプリケーションになります。あなたは各呼び出し(ストアドプロシージャ、またはトリガされた挿入など)をチェックし、何か悪いことが起きた場合は、その状態から回復する必要があります。通常は、ユーザーに問題が発生したことを伝えたり、フォームや何かをリセットしたり、再試行したりするようなものです。

私は少なくとも、これは起こる必要があると思います。

さらに、ユーザーにとって本当に素晴らしい体験をするために、アプリは事前に特定のデータ条件を事前にチェックし、最初にユーザーが不正な挿入を行わないようにする必要があります。

これは当然困難であり、時にはビジネスルールの二重コーディングを意味します(アプリケーションで1つ、DB制約で1つ)。しかし、これは劇的に優れたユーザーエクスペリエンスを実現します。

0

ソリューションは、技術よりも系統的であることのより多くのです:

  • 実装 - 「守備プログラミング」&「契約による設計」
  • ビジネスルールの可能性が時間の経過とともに変更される場合が非常に小さいですデータベースレベルで制約を適用する
  • エンティティまたは特定のプロパティの条件または制約を管理する "検証または規則&アグリゲーションレイヤ(またはクラス)"を作成する
  • Aこれを行うよりスマートな方法は、内部で "検証または規則&アグリゲーションレイヤ(またはクラス)を使用するエンティティおよび/または特定のプロパティ(" Account-Code ")のユーザーコントロールを作成することですアプリケーションはクライアント - の検証を置くとともに、その後のウェブサイトである場合-の開発体系的ウェイ 『以上の『スケーラブル&保守し、』アプリケーション・アーキテクチャ
  • これは、あなたが確実にできるようになります』常にビジネス層やC#コードでも有効性を確認する方が良い
  • 検証が失敗すると、&メッセージコンテンツが標準であることを確認するために "カスタムエラーメッセージ"ライブラリを実装するACR oss the application
  • エラーがデータベース自体(ストアドプロシージャなど)から発生した場合は、SQL例外を固定または標準化されたメッセージ形式に変換するために同じ「カスタムエラーメッセージ」クラスを使用できます。

私はこれがすべてあまりにも多すぎることを知っていますが、将来的には常に良いことです。

これが役に立ちます。

0

プロのプロジェクトでは、特定のストレージプロバイダ(DB [mysql、mssql、...]、フラットファイル、xml、バイナリ、クラウドなど)に依存しないでください。ビジネスロジック(モデル)。

モデルは、ストレージプロバイダに関する情報を知っている必要はありません。

アンクルボブはアーキテクチャおよびデータベースについて何か言った:アプリケーションがマルチユーザー(つまり、だけではなく、単一のユーザーを持つ単一のデスクトップアプリが、アプリがクライアントとして動作して集中管理DBにする場合http://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html

1

をおそらく、多くのワークステーションで)、クライアント(アプリケーション)に依存して一意性、存在性、フリー番号などを確認することは安全ではありません。これはしばしば助けよりももっと問題になります!)。

もちろん、事前チェックしてから再チェックすることもできます(アプリケーションレベルでは、DBで再起動します)。ただし、これにより余分なDBトラフィックが発生するため、問題があるかどうかによって異なります。

私はアプリケーションに戻るSPROCを書くとき、私はいつも同じフレームワークを使用します - 私はリターンコードとメッセージのパラメータを含めて、常にそれらを設定します。次に標準ルーチンを使用してそれらを呼び出し、パラメータを自動的に追加することもできます。私は失敗したときにメッセージを直接表示するか、必要に応じてリターンコードを使用してローカライズしたり、応答を自動化したりすることができます。私はいくつかのDB(SQL Svrのような)がReturn_Codeパラメータを返すことを知っていますが、私は自分自身を念入りにしていますので、重大なシステムベースのエラーや予期しない失敗のために作り付けのものを残すことができます。また、リターンコードの独自のナンバリングシステムを使用できるようになりました(つまり、コード内のEnumをグループ化したり、重大度別にグルーピングすること)。

ウェブアプリケーションでは、時々別のコンセプトを使用しました。たとえば、新しいアカウントに対してリクエストが行われても、複数のページが必要な場合があります(プロファイルなど)。ここでは、要求された一意のユーザー名、タイムスタンプ、およびそれらを認識する(IPアドレスなど)に対して隠されたユーザーIDを生成するヘッダーテーブルを使用することがよくあります。 x時間後にそれが使用されていない場合、ヘッダーテーブルはその番号を解放する行を削除します(DBに応じて、この番号は再び使用可能になることはありません - これは本当に重要です。送信されます)とユーザー名。正しく完了すると、レコードは適切なアクティブなテーブルにコピーされます。

//編集 - 追加するには:

良い点を。しかし、アカウントの一意性は非常に簡単なサンプルに過ぎません。 ビジネスロジックのアカウントの複雑な要件はどうですか? たとえば、クライアントコード(winformsアプリ)で実装した場合、私は がOKになりますが、このアカウントで別の(私のアプリケーションのコンソールバージョンまたは ウェブサイト)種類のアプリケーションを動作させたい場合は、このすべてを新しいアプリで ロジック再び!だから、私はデータを正しく保持するいくつかの方法を探している (サーバーのDBサイトとクライアント側)両側から。 - 昨日昨日

もしmutiuseが必要な場合は、それを分離するのが最善です。それを別のクラスライブラリプロジェクトに入れることで、あなたのWinForm、コンソールプログラム、サービスなどでDLLを使用することができます。私はまだロックフェイスの検証(DBレベル)を優先しますが、幻惑される可能性が高い。

通常の方法は3つのプロジェクトに分かれています。表示レイヤー[DL](winformプロジェクト/コンソール/サービス/ etc)とビジネスアプリケーションレイヤー[BAL](DALへのすべてのビジネスルールと呼び出しを保持します)は、ディプレイメディアやデータベース技術については何も知らない)最後にデータアクセスレイヤー(これはすべてのデータベース呼び出しを持っています - これはSQLとSPROCレベルでの挿入/更新/選択/削除メソッドと、データを前後に渡すためのいくつかのクラスで非常に基本的です)。 DLは、DALを参照するBALのみを参照します。 DALは、アプリケーションの残りの部分に影響を与えることなく、各技術(SQL ServerからMySQLへの変更など)をスワップすることができ、DALに影響を与えずにBALで変更および設定できます。データ変更などによる要件変更の追加または表示)。このフレームワークは、すべてのアプリケーションで何度も何度も使用することができ、(DBトポロジーのような)非常に劇的な変更を加えるのは簡単です。

関連する問題