「3層構造」のお話をしていきたいと思います。プログラマーになりたてのころなど,先輩プログラマーなどに,よくこういう話を聞いたことがあるのではないかと思うのですが,「なんでもかんでも,画面のプログラムに,全部の機能入れては駄目だよ」と。「画面」と「ビジネスロジック」と「データアクセス」という,「3層に分けて書くのがいいのだよ」みたいなことを聞いたことがある人もいるかもしれません。
これもこの単一責務の原則に由来しているというか,この辺の原則に従うことで,導き出しているような作りになっています。
現状私が推奨しているパターンとしては,この3層構造というよりは,もう少し違ったかたちで,ドメイン駆動開発とかでは推奨していますけど(C#ドメイン駆動開発等を参照方)例えばこんな感じということですね。データアクセスとかビジネスロジックとか画面とかいうのは,大きく分けると,「最低限ここが分かれてくるよね」というようなことですね。
1.1 データアクセス
・永続性のあるシステムはあまり変化しない
・ビジネスルールとまったく関係ない次元で変化する(SQLServerのバグや仕様変更など)
例えばデータアクセスですね,SQLServerとかOracleとか,ファイルとかというところは,基本的にそんな大きな変更というのは頻繁に起こるわけじゃないわけなのですが,ビジネスルールとは全く関係ない次元で,変化するという性質がありますね。
例えばSQLServerのバージョン上がったよとか,バグが出たよとか,仕様変更したよとかというのがたまにありますね。SQLServerでも文字列を扱う時は,「実はここにこういう感じでアクセスしてくれないとちょっと文字化けします」とか,「日本語だったらいいのだけど中国語のOSでやったらここがこうなるのでここはこうしておいてください」みたいな不具合報告などが,たまに発見されたり,意図的な仕様変更がされたりといったことが,たまにあります。
そういう場合というのは,SQLServerにアクセスしているところを全部探して,修正していかないといけないのですが,こういうものが受注画面や発注画面,在庫画面などの画面ロジックに書き込まれていると,いたるところで画面からSQLServerに接続されるコード入ることになり,しらみつぶしに探して,ロジックを修正していかないといけないという事態になってしまいます。
そうならないように,データアクセスする箇所を独立させて,「データアクセスはここでやっているよね」みたいな感じで,受注テーブルはこことか,発注テーブルはこことかいう感じで,クラスを分割し,独立して作っておけば,このファイルとこのファイルとこのファイル,このクラスとこのクラスとこのクラスみたいな感じで限られたクラスの修正だけで済むようになります。そうなると,修正箇所も少なく,影響箇所も限定的になるため,テスト工数も最小限に抑えることが出来ます。
1.2 ビジネスロジック
ビジネスロジックは頻繁に変化する
・取得したデータの編集など,自分で仕様を調整する部分
ビジネスロジックというのは業務ロジックのことです。例えば何かビデオレンタルシステムとかだったら,お客さんのカードをピッと読み込んで,こんな感じで出てくるからとかという,システム独自の仕様です。こういった業務ロジックは,業務の都合等で,頻繁に変わることがあります。要はポイント5倍デー始めようかとなったら,追加仕様として改造が必要になるかもしれないし,今までの「この割引率はちょっと変えよう」とか,「このチェック処理をちょっとこう変えた方がいいよね」という,我々がというか,ユーザーがというか,そのシステムでやりたいことというのを,自分で考えてやるので,SQLServerの仕様とか,マイクロソフトとか全然関係ない次元で,自分たちで考える仕様の変更ということになります。
だから業務ロジックは,業務の都合でどんどん変わっていくので,そこはそこで独立しておかないといけないといけないわけです。だからこのビジネスロジックとデータアクセスというのが一体化しているということは・・・
マイクロソフトの仕様とか,Oracleの仕様とかと,我々が独自で勝手にやっている業務ロジックの仕様とを,混ぜちゃっていることになるので,非常にこの結び付きがひどくて,使いづらいものになっていく訳ですね。マイクロソフトとかOracleの仕様変更と,我々が勝手にやる仕様変更とどっちが起きても,ソースコードをいじらないといけなくなるので,「どういう変更に対してこれは変えるクラス」みたいな感じで,独立して作っていくということが重要になってきます。
1.1 画面
データを取得してリストに表示
→グラフに表示する場合
データを取得する部分は関係ない
画面にしても,画面とビジネスロジックで言うと,画面というのは,Windowsフォームだったり,WPFだったり,Web画面だったり色々ある訳なのですが,その画面のテクノロジーに起因しますね。例えば,画面だったら,マイクロソフト標準のテキストボックスを貼り付けるのか,グレープシティのInputManを貼り付けるのか,そういったサードパーティーのコントロール貼り付けたり,時代の流れに伴って変化していったりしますね。例えばユーザーコントロールに不具合があったり,バージョンが変わったり,「テキストボックスでこういう処理をしたいね」とかという,画面は画面の事情の変更が出ますね。それとビジネスロジックとは関係ないわけです。
例えば定期的に温度を計測し,ある特性があれば検知するロジックを作ったとしますね。それとテキストボックスのチェックとか,グラフの見せ方とか,そういったこととはまた別の話なわけですよね。だから,そこは画面の技術とビジネスロジックというものは,切り離しておかないと,グラフの見せ方変えたいだけなのに,画面ロジックに精密なロジックまで同じクラスに入っていたら,画面事情の修正でも,同じクラスをいじってしまうみたいな感じになるわけですね。だから「このクラスをいじるってことはこういう変化が起きた時」とか,「ここをいじるってことはここに影響してくるね」というのが,分かるように作っておかないと,全部が1個のクラスにあったら,どこかを修正したら,別の関係ない部分がおかしくなっているかもしれないですね。そういう事にならないように,精密なロジックなどは,それはそれで独立してポンっと置いておきたいわけです。そういうような感じで,「画面」「ビジネスロジック」「データアクセス」というのは,結構昔からこのように分けて実装されることが一般的です。
「アジャイルソフトウェア開発の奥義」では,「ビジネスルールと永続性のあるシステムを結合するのは,自らトラブルに飛び込むようなものだ」というふうに書かれています。
これは,今言ったように,関係ないロジックが,他のロジックの修正に引っ張られてしまうので,他の変更理由に引っ張られてしまうので,無駄にクラスをいじることになりますね。だからそっとしておけるクラスというのは,できるだけ多い方が良くて,「これが変わったらここだけ変える」みたいな感じで,作っておくというのが理想ということです。
Udemyの非売品コース「C#14新機能」という80分の動画レクチャーを
無料でプレゼントしています。
こちらからご覧になってみてください。
A01_はじめに
B01_メッセージを出すレイアウトの作成
B02_pタグを使ったメッセージ表示
B03_ポップアップメッセージを表示する方法
B04_問い合わせメッセージを表示する方法
B05_ユーザーの入力を受けるメッセージ
B06_インラインJavaScript非推奨
B07_Javascriptを分離してアクセスする方法
B08_MessageServiceを作成する
B09_自作Serviceの依存性注入をする方法
C01_EditFormを使った入力検証
C02_ValidationSummary
C03_ValidationMessage
C04_入力コンポーネント_InputText
C05_InputNumber
C06_未入力を許容する方法
C07_InputNumberで対応している型
C08_InputDate
C09_InputSelect
C10_入力コンポーネント_InputCheckbox
C11_InputRadioとInputRadioGroup
C12_InputTextArea
C13_InputFile
C14_ファイルの上限を設定する
C15_フォーカスをあてる方法_標準編_ElementReference
C16_フォーカスをあてる方法_Razorコンポーネント編
D01_StringLength
D02_RegularExpression_正規表現
D03_EmailAddress
D04_Compare
D05_ViewModelに分ける方法
D06_依存性注入を利用したViewModelの生成
D07_CustomValidation1
D08_CustomValidation2
D09_プロパティレベルのCustomValidation
D10_ValidationContext
D11_処理をViewModelに移す書き方
D12_ViewModelに移せないロジック
D14_ShouldRender
D15_ViewModelに書かないほうがいいもの
D16_エラー箇所にフォーカスを当てる方法
E01_Azureにデプロイするための事前作業
E02_Azureにアップするアプリの作成
E03_Azureへの公開準備
E04_Azureへの公開
E05_データベースの作成
E06_データベースのデータを取得する
E07_データベースの値を画面に表示する
E08_Azureのデータベースを作成する
E09_Azureのデータベースにポータルサイトからログインする
E10_AzureのDBにテーブルを作成する
E11_BlazorアプリからAzureDBに接続する
E12_SQLデータベース料金の注意
E13_AzureSQLデータベースの無料オファーを受ける
F01_依存性注入のライフサイクル
F02_クラウドでのAddSingletonの動き
Udemyの非売品コース「C#14新機能」という80分の動画レクチャーを
無料でプレゼントしています。
こちらからご覧になってみてください。