PR

【App. Design】ファイル入出力の処理をどう配置するか

プログラミング
スポンサーリンク

はじめに

プログラムを作成しているとファイルを読んだり書いたりする処理が、頻繁に必要になります。

ファイル入出力というのは外部の環境に左右される処理です。
ファイルの中身に正しいデータが入っているかもそうですし、そもそも目当てのファイルが存在しているかについても作成しているプログラムでは責任を持てないケースが多々あります。

では、階層型のアーキテクチャにした場合、このような外部の環境に左右される処理を、どのように配置すると良いのでしょうか?
考えてみようと思います。

外部環境に左右されやすい処理とプログラムの構造

よくある仕様として、画面からの操作で、ファイルの中身を読み込む処理を考えてみましょう。
ユーザーが画面のボタンをクリックすると、ファイルを読み込んでデータを取得し、そのデータを画面に表示するといった処理になります。

まず、処理の流れをシンプルに考えていくと、画面からファイルを入力する処理を呼び出してデータを取得し、コアにあるクラスに格納する。コアと画面をバインドしていればそのまま画面にも反映されます。
次の図でいうとAですね。

Aはこれでも動くのですが、欠点があるので実際にはあまり用いられません。

その欠点とは、アプリが扱う主要な値とその取り扱いルールや属性など重要なコードを画面に配置することになるという点です。

なぜ、重要なコードが画面にあるとNGなのか?
それは重要なコードが、あちこちに散在することになるからです。大きなアプリになれば画面は1つとは限りません。そうすると画面毎にバラバラと重要なコードが散らばってしまいます。
重要な物はまとめて置かないとマズいですよね。例えば改訂を入れる時にモレが出るとマズい事態に、、、

また、また画面は、コアなど他に依存しているのでテストしづらい場所です。重要な部分がテストしづらければメンテナンスで苦労します。
画面には重要なコードを置かない方がいいのです。

ではBの流れに改良してみましょう。
Aは処理開始の合図をするだけにして、ファイル入出力などAでは画面がやっていたことをコアにおまかせします。
これなら、コアが主要な処理を実行するので、重要なコードもコアに移るので欠点を改善できます。

ただし、別の問題が発生します。依存関係です。
③の矢印部分ですが、コアがファイル入出力を参照しています。つまり、コアはファイル入出力に依存してしまう。
重要なコードが詰まったコアの独立性が落ちる、つまり安全性が低くなる。
これはマズい設計です。

そこで、さらに改善してCの流れが考えてみます。
BとCの違いは③の矢印の方向、参照の方向が逆になっている点です。つまり、ファイル入出力からコアを参照させる。
この方法なら問題ありません。

どうやって逆転させるかは、このあと説明します。

Dependency Injectionで依存の逆転

コアの部分をファイル入出力に依存させないために、依存の逆転を行う。その方法を説明します。

上の図の一部を詳しくしてみましょう。

Bは逆転前ですが、コアにある処理(Aクラス)が直接ファイル入出力の処理(Bクラス)を参照しています。
この状態から、抽象型であるインターフェイスを間に置き、双方からこの抽象型を参照するように変更します。
コアからファイル入出力への参照がなくなります。
そしてインターフェイスをコアの中に置けば、赤い矢印のように参照の方向が逆になります。

具体的には、
・コアにインターフェイスを定義する。
・ファイル入出力のクラスで、インターフェイスを実装する。
・コアのクラスでは、コンストラクタの引数などとしてファイル入出力のオブジェクトを受け取り利用する。
という方法になります。

ちなみに、この方法は Dependency Injection(依存オブジェクトの注入)と呼ばれています。
今回の例では、Dependency(依存オブジェクト)というのは ファイル入出力のクラスのオブジェクトです。
それをコアのクラスにコンストラクタの引数を経由して、Injection (注入) しているというわけです。

まとめ

ファイル入出力など外部の環境に左右されやすい処理は、コアから分離して依存を逆転させると、重要なコードの独立性を高めて、プログラムの品質を向上させることができます。

ファイル入出力の他に、通信など外部の機器とのデータ送受信なども、外部の環境に左右されやすい処理になります。プログラミングでは「インフラストラクチャ(インフラ)」と呼ばれることが多い処理です。

インフラというと一般には水道や電気などのライフラインだし、その他の分野でも設備のような意味合いで使われることが多い用語ですね。
IT分野でもプログラミング以外では設備の意味合いで使われることが大半ですが、プログラミングでは少し意味合いが異なります。

なお、実際にどのように実装するのかについては「こちら」で説明しますので、ご覧ください。

コメント

スポンサーリンク
タイトルとURLをコピーしました