かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

ポリシーベースのクラスの設計?

Modern C++ Designにある、C++のポリシーベースのクラス設計。
ポリシークラス - (hatena (diary ’Nobuhisa))」ここに触発されてC#でやるとしたら…と考えてたらこうなった。
C#3.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Policy
{
    class Program
    {
        static void Main(string[] args)
        {
            Manager m1 = new Manager{ Policy = new Policy1<Person>() };
            Manager m2 = new Manager{ 
                             Policy = new Policy2<Person>(new Person { 
                                                              Message = "はろう" }) };
            m1.Create().Greet();
            m2.Create().Greet();
        }
    }

    class Person : ICloneable
    {
        public string Message { get; set; }

        public Person() { Message = "Hello world"; }

        public void Greet() { Console.WriteLine(Message); }

        public object Clone()
        {
            return new Person { Message = this.Message };
        }
    }

    interface IPolicy<T>
    {
        T CreateInstance();
    }

    class Policy1<T> : IPolicy<T>
        where T : new()
    {

        #region IPolicy<T> Members

        public T CreateInstance()
        {
            return new T();
        }

        #endregion
    }

    class Policy2<T> : IPolicy<T>
        where T : ICloneable
    {
        private T instance;

        public Policy2(T instance)
        {
            this.instance = instance;
        }

        public T CreateInstance()
        {
            return (T) instance.Clone();
        }
    }

    

    class Manager
    {
        private IPolicy<Person> policy;

        public IPolicy<Person> Policy
        {
            get { return policy; }
            set { policy = value; }
        }

        public Person Create()
        {
            return policy.CreateInstance();
        }
    }
}

実行結果は↓

Hello world
はろう


C++のtemplateみたいに強力なのがC#には無いんで、結局のところStrategy patternを使うようになるかな…
面白くもなんとも無いことになってしまいました!