反射技术与工厂方法 (using C#)
2006-08-10 17:15
441 查看
反射技术与工厂方法 (using C#)
Posted on 2004-11-17 14:20 HelloSnoopy 阅读(284) 评论(0) 编辑 收藏 引用 收藏至365Key 所属分类: 设计模式
看了http://www.cnblogs.com/zhenl/archive/2004/10/27/57456.aspx,觉得不爽,改了一下顺便装成C#了.
让我们看这样一个例子,我们需要创建一种交通工具,可以是汽车、火车或者轮船,结构如下:
我们可以采用简单工厂,通过参数告诉创建工厂我们所需要的对象类型。如果我们增加子类,比如卡车、轿车等等,我们必须增加参数和相应的代码,如果子类层次很多,就会使程序变得难以维护。如果用简单工厂实现上面的结构显然很烦琐。
当然,我们可以采用工厂方法来实现,我们可以定义一个产生交通工具的接口,然后在子类中实现创建具体的子类:
[align=left]'采用接口定义了抽象的工厂方法 [/align]
[align=left]Public Interface CreateVehicle [/align]
[align=left] Function CreateAVehicle() As Vehicle '创建一个交通工具 [/align]
[align=left]End Interface [/align]
[align=left] [/align]
[align=left]'具体的创建由子类决定 [/align]
[align=left]Public Class CreateCar [/align]
[align=left] Implements CreateVehicle [/align]
[align=left] Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle [/align]
[align=left] Return New Car [/align]
[align=left] End Function [/align]
End Class
这就是工厂方法。但如果我们希望增加一个新的交通工具,不仅需要实现交通工具接口,还需要实现产生交通工具的工厂方法。下面是船的具体工厂方法:
[align=left]Public Class CreateBoat [/align]
[align=left] Implements CreateVehicle [/align]
[align=left] Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle [/align]
[align=left] Return New Boat [/align]
[align=left] End Function [/align]
End Class
显然,如果我们需要产生几十种交通工具的话,就需要有几十个具体的工厂类,而这些工厂类的区别仅仅是返回相对应的类的实例。这为维护带来了麻烦,如果需要在接口中增加一个带参数的创建方法,则所有的子类都需要修改。
采用抽象工厂如何呢?在这个场合下,抽象工厂与工厂方法没有什么区别,因为这里并不涉及产品线,抽象工厂并不能解决这里的问题。当然,如果每种交通工具都要有对应的车站的话,就要使用抽象工厂,但那样将更复杂。
有没有可能将需要创建的类的类型传递到工厂方法中,由工厂方法根据类型返回相应的实例呢?
解决上面的问题的关键是需要动态决定需要创建的类,这不是设计模式能解决的问题,属于软件平台的功能范畴。好在.net可以提供相应的功能,这就是反射技术。
看一下采用反射技术实现的实例:
using System;
using System.Reflection;
namespace ConsoleApplication1
{
//交通工具的统一接口
public interface IVehicle
{
string Color
{get;}
}
//一辆汽车
public class Car : IVehicle
{
public Car()
{}
public string Color
{
get
{
return "Blue";
}
}
}
//一艘船
public class Boat : IVehicle
{
public Boat()
{}
public string Color
{
get
{
return "RED";
}
}
}
//交通工具制造工厂
public class VehicleFactory
{
public static IVehicle CreateVehicle(Type vehicleType)
{
//自己写构造参数哦!
ConstructorInfo construct
= vehicleType.GetConstructor(Type.EmptyTypes);
IVehicle v = (IVehicle)construct.Invoke(null);
return v;
}
}
}
在使用时,只要在创建时带入需要创建的类的类型就可以了。
using System;
namespace ConsoleApplication1
{
/**//// <summary>
/// TestFactory 的摘要说明。
/// </summary>
public class TestFactory
{
[STAThread]
static void Main(string[] args)
{
IVehicle b = VehicleFactory.CreateVehicle(typeof(Car));
Console.WriteLine(b.Color);
Console.Read();
}
}
}
在使用时,只要在创建时带入需要创建的类的类型就可以了。
Posted on 2004-11-17 14:20 HelloSnoopy 阅读(284) 评论(0) 编辑 收藏 引用 收藏至365Key 所属分类: 设计模式
看了http://www.cnblogs.com/zhenl/archive/2004/10/27/57456.aspx,觉得不爽,改了一下顺便装成C#了.
让我们看这样一个例子,我们需要创建一种交通工具,可以是汽车、火车或者轮船,结构如下:
我们可以采用简单工厂,通过参数告诉创建工厂我们所需要的对象类型。如果我们增加子类,比如卡车、轿车等等,我们必须增加参数和相应的代码,如果子类层次很多,就会使程序变得难以维护。如果用简单工厂实现上面的结构显然很烦琐。
当然,我们可以采用工厂方法来实现,我们可以定义一个产生交通工具的接口,然后在子类中实现创建具体的子类:
[align=left]'采用接口定义了抽象的工厂方法 [/align]
[align=left]Public Interface CreateVehicle [/align]
[align=left] Function CreateAVehicle() As Vehicle '创建一个交通工具 [/align]
[align=left]End Interface [/align]
[align=left] [/align]
[align=left]'具体的创建由子类决定 [/align]
[align=left]Public Class CreateCar [/align]
[align=left] Implements CreateVehicle [/align]
[align=left] Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle [/align]
[align=left] Return New Car [/align]
[align=left] End Function [/align]
End Class
这就是工厂方法。但如果我们希望增加一个新的交通工具,不仅需要实现交通工具接口,还需要实现产生交通工具的工厂方法。下面是船的具体工厂方法:
[align=left]Public Class CreateBoat [/align]
[align=left] Implements CreateVehicle [/align]
[align=left] Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle [/align]
[align=left] Return New Boat [/align]
[align=left] End Function [/align]
End Class
显然,如果我们需要产生几十种交通工具的话,就需要有几十个具体的工厂类,而这些工厂类的区别仅仅是返回相对应的类的实例。这为维护带来了麻烦,如果需要在接口中增加一个带参数的创建方法,则所有的子类都需要修改。
采用抽象工厂如何呢?在这个场合下,抽象工厂与工厂方法没有什么区别,因为这里并不涉及产品线,抽象工厂并不能解决这里的问题。当然,如果每种交通工具都要有对应的车站的话,就要使用抽象工厂,但那样将更复杂。
有没有可能将需要创建的类的类型传递到工厂方法中,由工厂方法根据类型返回相应的实例呢?
解决上面的问题的关键是需要动态决定需要创建的类,这不是设计模式能解决的问题,属于软件平台的功能范畴。好在.net可以提供相应的功能,这就是反射技术。
看一下采用反射技术实现的实例:
using System;
using System.Reflection;
namespace ConsoleApplication1
{
//交通工具的统一接口
public interface IVehicle
{
string Color
{get;}
}
//一辆汽车
public class Car : IVehicle
{
public Car()
{}
public string Color
{
get
{
return "Blue";
}
}
}
//一艘船
public class Boat : IVehicle
{
public Boat()
{}
public string Color
{
get
{
return "RED";
}
}
}
//交通工具制造工厂
public class VehicleFactory
{
public static IVehicle CreateVehicle(Type vehicleType)
{
//自己写构造参数哦!
ConstructorInfo construct
= vehicleType.GetConstructor(Type.EmptyTypes);
IVehicle v = (IVehicle)construct.Invoke(null);
return v;
}
}
}
在使用时,只要在创建时带入需要创建的类的类型就可以了。
using System;
namespace ConsoleApplication1
{
/**//// <summary>
/// TestFactory 的摘要说明。
/// </summary>
public class TestFactory
{
[STAThread]
static void Main(string[] args)
{
IVehicle b = VehicleFactory.CreateVehicle(typeof(Car));
Console.WriteLine(b.Color);
Console.Read();
}
}
}
在使用时,只要在创建时带入需要创建的类的类型就可以了。
相关文章推荐
- 反射技术与工厂方法 (using C#)
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 select 标签的方法,不用 C# 中的反射技术
- 反射技术与工厂方法 (using C#)
- 反射技术与工厂方法 (using C#)
- (原创)利用扩展方法,给 IEnumerable<T> 增加一个生成 Html 的 CheckBox 标签的方法,不用 C# 中的反射技术
- 反射技术与工厂方法
- Net反射技术应用解决对象不同版本方法不同参数的问题 【转载】
- C#反射调用另外一个类中的私有字段和方法
- 使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型
- [转]C#反射技术之一读取和设置类的属性
- C# 如何利用反射来加载程序集,并调用程序集中有关类的方法
- C#抽象工厂方法
- c# 反射调用程序集方法、接口实例
- 根据反射技术得到jar包中所有类,以及方法
- C#中反射和扩展方法如何运用
- C# 使用反射技术实例化指定的类
- C# ASP.NET B/S模式下,采用lock语法 实现多用户并发产生不重复递增单号的一种解决方法技术参考
- C# 基础技术积累——反射
- C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍
- C#利用反射调用基类私有方法 及 Unity实现自定义InputField