No more Death March

あるSEのチラシの裏 C# WPF

アダプターパターン

Gofデザインパターンの復習でアダプターパターンについて書きます。
書籍等で見ると最初は混乱したのですが、覚えるとデコレーターパターン同様、シンプルなパターンだと思います。

アダプターパターンとは

・ある型を別の型に適合させるパターン

アダプターパターンの構成

適合させたい型

・アダプターとなるクラスによって適合させる型、インターフェース推奨

    public interface ISample
    {
        void DoSomething();
    }

アダプター

・あるクラスを別のクラスに変換するためのクラス
・ラッパーとも言われる
・以下の例はstringをISampleインターフェースに適合させた場合

    public sealed class SampleAdapter : ISample
    {
        public SampleAdapter(string adaptee)
        {
            // 省略
        }

        public void DoSomething()
        {
            // 省略
        }
    }

使用例

    class Program
    {
        static void Main(string[] args)
        {
            new SampleAdapter("hoge").DoSomething();
        }
    }

アダプターパターンのメリット

・外部のライブラリや標準ライブラリを自作した型で抽象化するこで、ライブラリへの依存を軽減する
・異なる型を抽象的な型で同一視、抽象的な型に対するロジックを共有することが出来る

デコレーターパターン

Gofデザインパターンの一つ、デコレーターパターンについて復習します。
デコレーターパターンは比較的簡単で、デザインパターンの中で一番最初に覚えたパターンでした。
再利用しやすいコードを書く上で今でも欠かせないパターンだと思います。

デコレーターパターンとは

・デコレーターを日本語に訳すと「装飾者」
・ある型に対する拡張機能を同じ型で実装する

デコレーターパターンの構成

拡張する型の宣言

・デコレーターパターンで拡張機能を実装する型の宣言
・抽象クラスでも書けるがインターフェースの使用を推奨

    public interface ISample
    {
        void doSomething();
    }

装飾するクラス(デコレーター)

・デコレーターパターンで実装されたクラス
・コンストラクタで拡張する型を受け取る
・自身も拡張する型を実装する

    public sealed class SampleDecorator : ISample
    {
        public SampleDecorator(ISample decorated)
        {
            // 省略
        }
        public void doSomething()
        {
            // 省略
        }
    }

装飾されるクラス

・デコレーターのコンストラクタに渡されるクラス
・拡張対象の型を実装している
・デコレーター自身がデコレーターに渡されることもある

    public sealed class Sample : ISample
    {
        public void doSomething()
        {
            // 省略
        }
    }

使用例

    class Program
    {
        static void Main(string[] args)
        {
            new Sample().doSomething();
            new SampleDecorator(new Sample()).doSomething();
            new SampleDecorator(new SampleDecorator(new Sample())).doSomething();
        }
    }

デコレーターパターンのメリット

・既存のコードを変更せずに機能を追加することが出来る
・オープン・クローズドの原則の実現方法の一つ(拡張に対して開いていて、修正に対して閉じている)
・デコレーターを組み合わせ方を変えるだけで安全に機能のバリエーションを増やすことが出来る

プロジェクトの分離について

色んな書籍をみても、c#のプロジェクトやjavaのパッケージの分け方について深く言及しているものがあまり無い。

 

 

最近思うのは、プロジェクトやパッケージの分離方法の勘所を抑えていれば、自ずとメンテナンスが容易なシステムになるのではないかということ。

 

モデリングアーキテクチャに対する理解も必要だと思うのですが、個人の解釈次第なところが多いし、もっと具体的に、こういうクラスはこういう名前空間で、こうやってライブラリ分離します。そうするとこういうメリットやデメリットがありますよ。

 

こういう話題がもっと目についても良いと思っています。

 

今はまだ自習のなかでうっすら手応えを感じているレベルですが、この辺の考え方が上手くまとまれば設計の際に迷うことが無くなりそう。

 

 

 

C# 自作ライブラリの検討メモ

デザインパターンオブジェクト指向エクササイズの教材として自作ライブラリを作ろうと検討中。

名前空間についてメモ


Nmdm
 ⇒最上位の名前空間、ブログ名から

Nmdm.Pair
 ⇒ジェネリックインターフェースで二つのインスタンスのペアを表現

Nmdm.Collection
 ⇒IEnumerableを持つ拡張用インターフェース

Nmdm.Range
 ⇒ジェネリックインターフェースで型の範囲を表現

Nmdm.Comparer
 ⇒.NetのIComparer関連の拡張 インターフェースは不要

基本型を拡張する場合の名前空間(例:string)

Nmdm.String
 ⇒stringインスタンスを持つインターフェースIStringの宣言場所

Nmdm.String.Wrapper
 ⇒基本型のラッパー実装場所

Nmdm.String.Decorator
 ⇒単一のstring型インスタンスで成立する処理をデコレーターパターンで記述、IStringを返す。
  ToWide、ToNarrow、ToUpper 等

Nmdm.String.Comparer
 ⇒IComparerの実装場所

Nmdm.String.Adapter.Length
 ⇒(変換元の型).Adapter.(変換先の型)のルールで変換ロジックをアダプターパターンで記述


Pair、Collection、Rangeなど汎用的なデータ構造は型名の後に名前空間を入れる。
Nmdm.Int.Pair.Adapter.〇〇
 ⇒IPairに関する実装

Nmdm.Int.Range.Decorator.〇〇
 ⇒IRangeに関する実装



基本ルール
・完全コンストラクタパターン
・メソッドをアダプタパターンまたはデコレーターパターンで分離、ミックスインにする。
・処理を実装する箇所では全てのメンバーを使う。
・LengthやCount、Year、Monthといった用途が定まりそうなものは別途インターフェースを設け、IIntなどより抽象的な型に依存させる。

c# リフレクションの使いどころを考える

ソフト全体で使いたいインターフェースがある時、
インターフェースとその実装を同じプロジェクトに入れると実装部分をメンテナンスする度に大規模なビルドが必要になる。

そもそも抽象(インターフェース)に依存して処理を標準化するのに実装を直す度にビルドが走るのはおかしな話。

それを回避する方法として、インターフェースと実装を分離し、UnityなどのDIを使うのも良いのだけど、
粒度の小さく凝集度の高いものを毎回DIで実現しようとするとDIのためのコーディングだけで手間がかかってしまう。

そこでリフレクションを使ってインターフェースが宣言されているプロジェクト内でリフレクションを使って実装クラスのアセンブリを読み込んでしまう。

プロジェクトの依存関係は実装⇒インターフェースの向きなので依存関係に逆転した読み込みが行われることになる。

一見するとおかしな考え方に思えるが、こうすることによって実装以外のインターフェースに依存するプロジェクトから
インターフェースの実装プロジェクトに対する依存を完全に排除することが出来るし、実装をチューニングしたりリファクタリングしても、
クライアントプロジェクトのビルドが実行されることはなくなる。

ステートソーシングな設計をイベントソーシングな設計に

ステートソーシングな設計の「商品テーブル」をイベントソーシングな設計に置き換える時のイメージをメモ

「商品テーブル」
・ID
・コード
・名称
・登録担当者ID
・登録日時
・更新担当者ID
・更新日時
・削除担当者ID
・削除日時

手順1)ドメインに関する出来事を箇条書きにする

・新しい商品を登録した。
・商品の名前を変えた。
・商品のコードを変えた。
・商品を削除した。

手順2)出来事をテーブルに置き換える

・「商品が登録されましたテーブル」
・「商品の名前が変わりましたテーブル」
・「商品のコードが変わりましたテーブル」
・「商品を削除しましたテーブル」

手順3)各テーブルの列構成を考える。

「商品」
・ID

「商品登録されましたテーブル」
・ID
・商品ID
・担当者ID
・発生日時

「商品の名前が変わりましたテーブル」
・ID
・商品ID
・新しい商品名
・担当者ID
・発生日時

「商品のコードが変わりましたテーブル」
・ID
・商品ID
・新しいコード
・担当者ID
・発生日時

「商品を削除しましたテーブル」
・ID
・商品ID
・担当者ID
・発生日時

C# プロパティとメソッドの違い

プロパティとメソッドとの違いについておさらいします。

MSDNに掲載されている説明は以下の通り。

プロパティとメソッドの選択

一般的に、メソッドは操作を表し、プロパティはデータを表します。

例えば「人」オブジェクトがあれば、
「名前」や「性別」はデータで、
「歩け」や「走れ」といった操作(動作)はメソッドですよ。
ということだと。

お仕事プログラミングはVB6から入った身なので、
当時は疑うこともなくプロパティを使っていたけど、
オブジェクト指向設計の面で考えるとこのメソッドなのかプロパティなのかっていうのが、
返って話をややこしくしていると思う。

そもそもJavaだとかRubyだとか、C#で言うプロパティというのは無いわけで、
Microsoft系言語のガラパゴスな仕組みだと認識しています。

少しでも脳みその負担を減らすために、いっそプロパティを使わずにプログラミングした方がいいんじゃないかとすら思う。

Javaからプログラミングに入った人だとJavaC#と移った時に
プロパティ?なにそれ?プロパティファイルじゃなくて?ってなるんでしょうかね。