C#第五天综合练习,从多态到简单工厂

[ 1762 查看 / 5 回复 ]

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

namespace RefactorToDP
{
    /// <summary>
    /// 从Polymorphism到Factory Pattern的Refactoring
    /// </summary>
    public class 多态To简单工厂
    {
        public static void Main()
        {
            //开始,画画(笔 pen)的参数是通过里氏替代,new其子类
            new 画家().画画(new 毛笔());

            //演变为使用简单工厂模式,通过工厂得到笔,顺便结合单例
            string penName = System.Configuration.ConfigurationManager.AppSettings["className"].ToString();
           
            //人如果也可以克隆制作的话,可以搞个 画家工厂 ,专门出产画家小分队
            new 画家().画画(笔厂.Instance.GetaKindofPen("RefactorToDP." + penName));
        }
    }

    class 笔厂
    {
        //被readonly修饰的变量只有2个命运,要么在初始化的时候直接赋值,要么在静态构造函数中赋值,没第三条路
        private readonly static 笔厂 instance = null;

        private 笔厂() { }

        //vs2008还是比较智能的,在instance 前面增加了 readonly ,通过‘重构’生成的属性,只读不写。。聪明的IDE!回去做了实验,去掉后,同时生成getter&setter
        public static 笔厂 Instance
        {
            get { return 笔厂.instance; }
        }

        static 笔厂()
        {
            instance = new 笔厂();
        }

        /// <summary>
        /// 笔厂返回给客户一只笔。在编译时,客户程序来调用本方法,本方法只告知返回‘一支笔’ (言下之意,甭管我返回你什么笔,反正给你的是笔);只有到程序运行时才能知道到底是什么笔,是为晚期绑定。
        /// </summary>
        /// <param name="className">要通过反射得到的笔的类名全称DN:distinguished name</param>
        /// <returns>抽象的笔</returns>
        public 笔 GetaKindofPen(string className)
        {
            return System.Reflection.Assembly.Load("RefactorToDP").CreateInstance(className) as 笔;

        }

    }

    class 画家
    {
        public void 画画(笔 pen)
        {
            Console.WriteLine("我在用{0}画画!", pen.ToString());
        }
    }

    abstract class 笔
    {
        public override string ToString()
        {
            return base.GetType().Name;
        }
    }

    class 毛笔 : 笔 { }
    class 粉笔 : 笔 { }
    class 铅笔 : 笔 { }

}
1

评分次数

    本主题由 管理员 张波老师 于 2010-1-7 16:02:35 执行 设置精华/取消 操作
    TOP

    public void 画画(笔 pen)

    画家画画,这个动作需要一支笔,这支笔不是画家‘自备’,而是谁把画家new出来‘请’他画画的人负责‘注入’。画家此类,依赖于 笔 来画画,但却等待别人给自己注进这支笔来,才开始action。这是 依赖注入 的一种。
    TOP

    简单工厂,如果不用 反射 ,应该要在下面方法中使用switch-case语句,因为不可避免的会遇到‘客户究竟索要的是哪种产品?’这样的问题。

    public 笔 GetaKindofPen(string className) // 如不用反射,可能参数名会是 string PenName
    TOP

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

    namespace HWDay5
    {
        class Program
        {
            static void Main(string[] args)
            {
                //定义玩具(在配置文件中)
                string toyName = System.Configuration.ConfigurationManager.AppSettings["className"].ToString();

                //定义玩具店
                玩具店 toyStore = new 玩具店();

                //通过玩具店买到玩具
                玩具 aKindofToy = toyStore.出售玩具("HWDay5." + toyName);

                //定义小孩子
                小孩子 child = new 小孩子();

                //把买回的玩具给小孩子玩耍
                child.玩(aKindofToy);

            }
        }

        abstract class 玩具 { }
        class 坦克玩具 : 玩具 { }
        class 毛毛熊玩具 : 玩具 { }

        class 玩具店
        {
            //PPT中的参数名有意思, 莫非是暗示用反射?
            internal 玩具 出售玩具(string 类型)
            {
                玩具 retVal = System.Reflection.Assembly.Load("HWDay5").CreateInstance(类型) as 玩具;
                return retVal;
            }
        }

        class 小孩子
        {
            public void 玩(玩具 toy)
            {
                Console.WriteLine("我在玩玩具。偷懒起见,产品基类玩具的ToString方法没有重写,大家将看到的是妈妈给我买的玩具的全名称(带namespace)我玩的是\r\n{0}", toy);
            }
        }

    }
    TOP

    设计模式,一旦捅破那层纸,是不是海阔天空?思如泉涌一发而不可收拾?
    TOP

    是的。前人栽树,后人乘凉。就像看老师写3层的代码,一步步重构,最后用CodeSmith生成代码。这本身也是 一种 模式。老师摸索过了,然后把经验传授给我们,我们就像 设计模式 PPT中那个看书走路的人,遇到坑就不怕了。
    TOP