MVCモデルだ、とか三階層分離だ、などと難しく考えないで役割の視点でみれば楽だと思います。
.netでの業務アプリの大半は非接続型アプリです。DataTable(もしくはDataSet等に相当するものに)一旦読み込み加工して書き戻します。
読み込むときは複数レコードを抽出するSQL文で引用し、書き戻すときは、単Tableの Update文/Insert文/Delete文を介して操作します。
このDaTaTableの項目要素と画面のコントロールを結びつけるのにBinding機能で結合するのが簡単なのですが、Bindingでは間に合わないケースが多々あります。
数個のDB項目を結合したり、他の画面項目の要素と結合して表示内容を確定したりします。
このように考えただけでも役割が幾つかの部分に分かれているのが解ります。
1-a. DBからDataTableに引用する部分
1-b. DataTableからDBに書き戻す部分
2-a. DataTableから画面コントロールに引用する部分(帳票の時はこのケースのみ)
2-b. 画面コントロールからDataTableに書き戻す部分
3. 画面の操作する部分
ビジネスルールは 2の部分のみ書き込むことで3つの部分の独立性を保ちます。
ここまでは入門書レベルなのですが、ここから先でつまづく人が時折います。
1.と2.の結合という言葉から一対一で結びつく、2.と3.の結合も一対一で結びつくものと短絡的に理解して混乱するようです。
具体的に言いますと、DBの項目には存在しないが画面には登場する項目があったときどうすれば良いのか不明になって、その項目に作用するビジネスルールを画面モジュールに記述していき、結果的にモジュールの粗結合性を崩すようです。
例) 受注伝票入力画面を考えたとき、受注入力画面に過去の取引額を表示する要件だったとします。
① ② ③
DB DataTable 画面
受注Table ====> 受注DataTalbe => 受注入力画面
ここまでは良いのですが,前述の誤解から ①、②、③は対になると誤解して結果として①と③が対になると考えてしまって、ここに登場しない過去履歴の部分を組み入れる箇所が不明になって結果として③に記述してしまうようです。
対にする必要はなく、②の部分は ①の要素を含むし, ③の要素も含むと考えればスッキリすると思うのです。
荒っぽく言えば、 ②は①と②を継承しているようなものです。
ビジネスルールは②にカプセル化できます。ビジネス以外のルーチンも③から切り離すと更にスッキリします。
UIに伴う定型処理としては、日付の妥当性チェック、文字列制約や入力可能文字などのチェックなどがあります。
このチェックも③にハードコーディングしないで、モジュール化して継承するようにします。
このように役割を切り分けていくと③の部分は画面定義のみになります。
最初は取っ付き難く手間がかかるので嫌になりがちなのですが、そこをグッと我慢して製造するようにすれば、3、4回目からは製造が楽になったと実感できると思います。