1. 程式人生 > >反射技術與工廠方法 (using C#)

反射技術與工廠方法 (using C#)

讓我們看這樣一個例子,我們需要建立一種交通工具,可以是汽車、火車或者輪船,結構如下:
我們可以採用簡單工廠,通過引數告訴建立工廠我們所需要的物件型別。如果我們增加子類,比如卡車、轎車等等,我們必須增加引數和相應的程式碼,如果子類層次很多,就會使程式變得難以維護。如果用簡單工廠實現上面的結構顯然很煩瑣。 當然,我們可以採用工廠方法來實現,我們可以定義一個產生交通工具的介面,然後在子類中實現建立具體的子類: '採用介面定義了抽象的工廠方法 Public Interface CreateVehicle     Function CreateAVehicle() As Vehicle '建立一個交通工具 End Interface '具體的建立由子類決定 Public Class
CreateCar
    Implements CreateVehicle     Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle         Return New Car     End Function End Class 這就是工廠方法。但如果我們希望增加一個新的交通工具,不僅需要實現交通工具介面,還需要實現產生交通工具的工廠方法。下面是船的具體工廠方法: Public Class CreateBoat     Implements CreateVehicle
    Public Function CreateAVehicle() As Vehicle Implements CreateVehicle.CreateAVehicle         Return New Boat     End Function 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();
        }

    }

}


在使用時,只要在建立時帶入需要建立的類的型別就可以了。