C#デザインパターン  - Prototype

ここに掲載したコードは、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』に掲載されているサンプルコードをC#に移植したものです。
解説らしい解説は載せていませんので、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』も合わせてお読みください。

※当ソースは、Visual C# 2008 Express Editionで動作を確認しています。
  Visual Studio 2005をお使いの方は、ブログの記事を残しておきますので、そちらをご覧ください。



■IProduct.cs
using System;

namespace Gushwell.DesignPatterns.Prototype.Framework {
    public interface IProduct : ICloneable<IProduct> {
        void Use(string s);
    }    
}



■ICloneable.cs
using System;

namespace Gushwell.DesignPatterns.Prototype.Framework {
    public interface ICloneable<T> : ICloneable {
        new T Clone();
    }
}


■Manager.cs
using System;
using System.Collections.Generic;

namespace Gushwell.DesignPatterns.Prototype.Framework {

    public class Manager {
        private Dictionary<string,IProduct> showcase = new Dictionary<string,IProduct>();
        public virtual void Register(string name, IProduct proto) {
            showcase[name] = proto;
        }

        // 複製を返すのが肝。Flyweightとはここが異なる。
        public virtual IProduct Create(string protoname) {
            IProduct p = showcase[protoname];
            return p.Clone();
        }
    }
}





■MessageBox.cs
using System;
using System.Text;
using Gushwell.DesignPatterns.Prototype.Framework;

namespace Gushwell.DesignPatterns.Prototype {

    public class MessageBox : IProduct {
        private char decoChar;
        public MessageBox(char decochar) {
            this.decoChar = decochar;
        }

        public virtual void Use(string s) {
            int length = Encoding.GetEncoding("shift-jis").GetByteCount(s) + 4;
            Console.WriteLine(new string(decoChar,length));

            Console.WriteLine("{0} {1} {0}",decoChar,s);

            Console.WriteLine(new string(decoChar, length));
        }

        public IProduct Clone() {
            return (IProduct)MemberwiseClone();
        }
        object ICloneable.Clone() {
            return this.Clone();
        }
    }
}



■UnderlinePen.cs
using System;
using System.Text;
using Gushwell.DesignPatterns.Prototype.Framework;
using System.Linq;

namespace Gushwell.DesignPatterns.Prototype {
    public class UnderlinePen : IProduct {
        private char ulchar;
        public UnderlinePen(char ulchar) {
            this.ulchar = ulchar;
        }

        public virtual void Use(string s) {
            int length = Encoding.GetEncoding("shift-jis").GetByteCount(s);

            Console.WriteLine("\"{0}\"",s);

            Console.Write(" ");
            Console.WriteLine(new string(ulchar,length));
        }

        public IProduct Clone() {
            return (IProduct)MemberwiseClone();
        }

        object ICloneable.Clone() {
            return this.Clone();
        }

    }
}





■Program.cs
using System;
using Gushwell.DesignPatterns.Prototype.Framework;

namespace Gushwell.DesignPatterns.Prototype {
    public class Program {
        [STAThread]
        public static void Main(string[] args) {
            // 準備
            Manager manager = new Manager();
            UnderlinePen upen = new UnderlinePen('~');
            MessageBox mbox = new MessageBox('*');
            MessageBox sbox = new MessageBox('/');
            manager.Register("strong message", upen);
            manager.Register("warning box", mbox);
            manager.Register("slash box", sbox);

            // 生成
            IProduct p1 = manager.Create("strong message");
            p1.Use("Hello, world.");
            IProduct p2 = manager.Create("warning box");
            p2.Use("Hello, world.");
            IProduct p3 = manager.Create("slash box");
            p3.Use("Hello, world.");

        }
    }
}