利用反射实现工厂方法

        最近正在看四人帮写的Design Patterns,偶有心得,于是写了一个利用反射实现工厂方法的小程序,这是书里面没有的,也不知道有没有人比我先想到。
        工厂方法经常使用参数的方法实现Creator。这里也使用了参数的方法,但是和传统的参数截然不同。

        新建一个C#工程,在窗体里面放一个ComboBox,一个Button, 并且在ComboBox的Items属性里面输入MyProduct和YourProduct,我们以后就是通过这两个string来创建对象的。窗体如图所示。将项目的属性中的输出改成控制台应用程序。


        然后在Form类的外面输入下面的代码。

public class Creator
{
        public static Product CreateProduct(string ProductName)
        {
                Product product = null;

                // 你也可以自己继承Pruduct接口,生成dll,然后在这里加载dll
                Assembly a = Assembly.GetCallingAssembly();
                // 类的全名
                string s = @"ReflectingFactoryMethod." + ProductName;
                // 创建对象
                object o = a.CreateInstance(s);
                // 将对象转化为Pruduct接口
                product =  o as Product;
                return product;
        }
}

public class TheirCreator : Creator
{
        override public static Product CreateProduct(string ProductName)
        {
                Product product = null;

                // 你也可以自己继承Pruduct接口,生成dll,然后在这里加载dll
                Assembly a = Assembly.LoadFile(@"c:/windows/system32/a.dll");
                // 类的全名
                string s = @"SomeNameSpace." + ProductName;
                // 创建对象
                object o = a.CreateInstance(s);
                // 将对象转化为Pruduct接口
                product =  o as Product;
                return product;
        }
}

public interface Product
{
        void ShowProduct();
}

public class MyProduct : Product
{
        public void ShowProduct()
        {
                // TODO:  添加 MyProduct.ShowProduct 实现
                Console.WriteLine("My Producted");
        }
}

public class YourProduct : Product
{
        public void ShowProduct()
        {
                // TODO:  添加 YourProduct.ShowProduct 实现
                Console.WriteLine("Your Producted");
        }
}

        最后在Button的Click事件里面输入下面的代码。

private void button1_Click(object sender, System.EventArgs e)
{
        Product product = Creator.CreateProduct(this.comboBox1.Text);
        product.ShowProduct();
}

        从这里我们可以看到,我们是从 this.comboBox1.Text 来创建对象的,这是一个string。也可以读入另外一个dll,从那里创建对象。
        如果我们这样来写Creator类:
public class Creator
{
        public static Product CreateProduct()
        {
                Product product = null;
                StreamReader sr = new StreamReader("config.txt");
                string AssemblyName = sr.ReadLine();
                string NameSpaceName = sr.ReadLine();
                string ProductName = sr.ReadLine();
                Assembly a = Assembly.LoadFile(AssemblyName);
                string s = NameSpaceName + ProductName;
                object o = a.CreateInstance(s);
                product =  o as Product;
                return product;
        }
}

        这个Creator也可以实现刚才的功能,而且不需要写Creator的子类就可以实现功能扩展。只需要继承Product接口,编译成dll,然后适当的修改config.txt配置文件,就可以轻松实现。程序供应商可以只提供Product接口,却不需要提供Creator的接口。客户只需要根据自己的需要继承Product接口,而且不需要更改原有的可执行发布。虽然这个Creator也有一些缺陷,比如对于实现变化特别多的构造函数就比较困难,但是如果是统一的构造函数却能实现无穷的扩展能力。
        但是这个Creator却和经典的工厂方法相矛盾了,经典的方法需要编写Creator的子类来实现扩展,而这个Creator却不需要。这个是由于引入了反射造成的。在没有反射这个功能之前,我们必须知道我们需要创建对象的类型,也就是说,在一个特定的Product类出现之前是不可能有一个Creator类能够创建这个类的对象的,而使用了反射的Creator可以创建所有的Product,即使这个Product的出现时间比Creator还要晚。
        利用反射实现工厂方法只是第一步,利用反射还可以实现更多的模式。把新鲜技术和公认的经典模式相结合也许会嘣出新的火花。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值