『Adaptive Code』の感想その2

はいどーもこんばんは、無職オブ無職の無職です。
本日も引き続き『Adaptive Code』の感想記事を書いていこうと思いますよ。

依存関係の管理

例えばAというクラスがBというクラスを使用している場合、AというクラスはBというクラスに依存していると言います。
これはアセンブリAがアセンブリBを使用している場合にも当てはまります。
本書によれば、依存関係を適切に管理しないと「一時的に開発のペースが上がるかもしれませんが、長期的にはプロジェクトを破綻させる可能性があります。つかの間の生産性の向上が、コードの量やモジュールの数の増加によってすぐ帳消しとなる」とのことです。
適当に実装したコードがのちのち破綻をきたし、結局最初から時間をかけて丁寧に実装していた方がよかった、という話と似ていますね。
最悪の依存関係の一つは、クラスAがクラスBを利用し、クラスBもクラスAを利用しているようなパターンでしょう。
「依存関係が漏れ出す」という表現もなるほどなあと思いました。
普段はあまり意識したことがありませんでしたが、依存関係の管理についても今度から意識してみようと思いますよ。

2層アーキテクチャ

2層アーキテクチャには「ユーザーインターフェイス層」と「データアクセス層」が存在します。
ユーザーインターフェイス層はデータアクセス層を知っている必要がありますが、データアクセス層はユーザーインターフェイス層を知っていてはなりません。
ただ実際はデータアクセス層と一口に言っても、データアクセス層のインターフェイスと、データアクセスの実装を用意します。
インターフェイスには例えばデータベースに対する追加機能のAddがあるとします。これはあらゆるテクノロジに依存しません。
それに対して実装はMySQLやMongoDBなどの具体的な個々のテクノロジに依存します。
ユーザーインターフェイス層はデータアクセス層のインターフェイスを利用しますが、データアクセスの具体的なテクノロジには依存しません。
つまり個々のテクノロジはインターフェイスに覆い隠されます。
こうすると、様々なデータベースに対して個々の細かいAddの仕方を意識する必要がなくなり(実装する必要があるのとは別の話)、Addは全てAddとして扱えるのです。
まあ、ごく一般的なインターフェイスの使い方という感じですね。
注意点としては「アプリケーションに重要なロジックがある、またはロジックの変更の対象となる」場合、2層アーキテクチャはあまりよくないようです。
というのも、ユーザーインターフェイス層やデータアクセス層はその名の通り、本来ロジックを配置するための層ではないからです。
つまりAdaptiveではないコードとなります。

3層アーキテクチャ

先ほどの2層アーキテクチャとは違って、3層アーキテクチャには「ビジネスロジック」というものが存在します。
本書によれば、このビジネスロジックの実行責任は以下の2つです。

・ユーザーインターフェイス層からのコマンドを処理する
・ビジネスプロセス、ルール、ワークフローのモデルとしてビジネスドメインを作成する

正直後者がなんのことなのかよくわからないのですが、前者は例えばRPGを想像してみてください。
戦闘中に特技コマンドを選んだりしますよね(ユーザーインターフェイス層)。
この選ばれた結果(コマンド)をビジネスロジック層が処理し、データアクセス層(敵のHP情報とか)へと伝達するのです。

注*僕はこういう認識で読みましたが、あんまり自信ナシ。

またコマンド/クエリ責務分離(CQRS)ではビジネスロジックを介するのはコマンドの処理のみで、クエリは直接データ層にアクセスすることもあるようです。
具体例がよくわからなかったので、この辺は要追加学習ですかねえ……。

コマンド/クエリ分離

『オブジェクト指向入門 第2版』の中で「オブジェクトメソッドはすべてコマンドがクエリのどちらかにすべきである」ことが書かれているらしいです。
このコマンドとクエリを簡単にまとめると、以下のようになります。

・コマンド:状態を変更できる
・コマンド:値を返さない
・クエリ:状態を変更しない
・クエリ:値を返す

これを守るとAdaptiveなコードになる場合があるようですよ(詳しくは本書をご覧ください)。
僕に使いこなせますかねえ……。

PostSharp

アスペクト指向プログラミング(AOP)についても本書は触れています。
そのAOPを実現するライブラリの一つとして、PostSharpが紹介されています。
PostSharpを使うと、例えばLogged属性を使用して、メソッド呼び出しに関する情報をログに書き込むことが可能になるようです。
これの何がよいかと言えば、本来の処理Aとは無関係なロギング処理をコードから分離できることです。
また、この属性は「すべてのメソッドに適用できるほど汎用的で、繰り返し再利用できること」も素晴らしい点です。
僕も使おうかなあとチラッと思いましたが、使いこなせるかどうか(ちゃんと実践的に利用できるかどうか)が不安なので、現在ちょっと考え中です。

Null Objectパターン

本書ではデザインパターンがいくつか紹介されています。
その中の一つがNull Objectパターンです。
詳しくは別の記事で取り扱ったので、そちらをご覧ください。

テストについて

テストは何のためにするのでしょうか。
本書では「テストはソフトウェアの品質を確保するために使用できるプラクティスの1つです」と紹介されています。
他には安全にリファクタリングをおこなうためにテストを活用する場合もあるようです。
僕もテストをちゃんとやりたいなあと思いつつも現実としてあまりできていない(実機で試さないとテストしにくいやつとかは設計がそもそも悪いんですかね……)ので、本書を通じてテストの真髄というものを知りたかったのですが……ウーン。
テストの効用はよくわかったのですが、実際に適用する方法がちょっと難しいですね。
慣れですかねえ……。

テスト駆動開発

テスト駆動開発の方法についてかなり具体的に書かれています。
特に何の用意もしなくても可能な方法(手動でのフェイク)から、モックフレームワーク(Moq)を使った方法まで説明されています。
「テストテスト言うけど、具体的にどうすればええねん」という方の役に立つのではないでしょーか。
こっちも僕にはちょっと難しそうですねえ……。
もう少し大きな規模の開発チームだとテスト駆動開発を徹底しているんでしょうか。よくわかりません。
ちなみに本書ではテスト駆動開発とテストファースト開発を明確に区別していました。

終わりに

第5章までの感想をまとめてみました。
最後の方に「ソフトウェア開発においては、失敗することに不安を抱いてはなりません。失敗を恐れずにはいられない場合、イノベーションは不可能です。そうではなく、失敗するとい事実と向き合い、リリースをロールバックすることを受け入れてください」と書かれています。
人生は失敗したら取り返しのつかないことが多いので、失敗することに不安を抱くことも多いと思います。
僕のように失敗したことに気がつかず人生を進め、すでに手遅れな感じの人もいるかなと思います。
ですがソフトウェア開発においては、ものによっては存分に失敗してもいいんだなあとよくわかりました。
これからドンドン失敗していこうと思いますよ。

さて本書は全部で13章まであります。つまりまだ半分も読んでいないことになりますねw
まだ少し時間がかかりそうですが、これからもチマチマとまとめていきます。
ほなそんな感じでまた。

フォローする