日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式学习笔记六:.NET反射工厂

發布時間:2023/12/19 asp.net 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式学习笔记六:.NET反射工厂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 1. 簡述

????通過前面的學習,我們以傳統的方式實現了簡單工廠,工廠方法和抽象工廠,但是有些場合下如此處理,代碼會變得冗余并且難以維護。假設我們要創建交通工具。可以是汽車,火車,輪船等,其結構如下:


?????我們可以采用簡單工廠,通過參數指示創建所需要的對象類型。如果要增加子類,例如卡車和轎車,則必須增加參數和相應的代碼。如果子類層次過多,則會是程序變得很難維護。?
????但我們可以采用工廠方法模式來實現,即定義一個產生交通工具的接口,然后在子類中實現創建具體子類。代碼如下:
Code
public?interface?ICreateVehicle
????
{
?????????Vehicle?CreateCehicle();
????}
Code
?public?abstract?class?Vehicle
????
{

????}
Code
????public?class?Car:Vehicle
????
{
????????
public?Car()
????????
{
????????????Console.WriteLine(
"創建了一個Car");
????????}

????}
Code
????public?class?Boat:Vehicle?
????
{
????????
public?Boat()
????????
{
????????????Console.WriteLine(
"創建了一個Boat");
????????}

????}
Code
????public?class?CreateCar:ICreateVehicle
????
{
????????
ICreateVehicle?成員#region?ICreateVehicle?成員

????????
public??Vehicle?CreateCehicle()
????????
{
????????????Vehicle?vehicle
=new?Car();
????????????
return?vehicle;
????????}


????????
#endregion

????}
Code
????public?class?CreateBoat:ICreateVehicle
????
{
????????
ICreateVehicle?成員#region?ICreateVehicle?成員

????????
public?Vehicle?CreateCehicle()
????????
{
????????????Vehicle?vehicle?
=?new?Boat();
????????????Console.WriteLine(
"Car");
????????????
return?vehicle;
????????}


????????
#endregion

????}

這就是工廠方法。如果希望增加新的交通工具,不僅需要實現交通工具接口,還需要實現生產交通工具的工廠方法。

????顯然我們需要幾十種交通工具,則需要幾十個具體的工廠。而這些類的區別僅僅是返回相對應的類的實例,所以位維護帶來了很大的麻煩。如果需要在接口中增加一個帶參數的方法,則所有的子類都需要修改。
在這種場合下,采用抽象工廠與工廠方法沒有區別,因為這里并不涉及產品線,抽象工廠并不能解決其中的問題,如果每種交通工具都要有對應的車站,則要使用抽象工廠,但是將會跟復雜。

有沒有可能將需要創建類的類型傳遞到工廠方法中,由工廠方法根據類型返回相應的實例?解決這個問題的關鍵是需要動態的決定需要創建的類,這不是設計模式能解決的問題,屬于軟件平臺的功能范疇。.NET可以提供反射技術。

我們先看通過反射技術實現的簡化的工廠,代碼如下:

Code
?public?class?CreateVehicleByType:ICreateVehicle
????
{

????????
ICreateVehicle?成員#region?ICreateVehicle?成員

????????
private?Type?VehicleTYpe;

????????
public?CreateVehicleByType(string?strType)
????????
{
????????????Type?t?
=?Type.GetType(strType);

????????????VehicleTYpe?
=?t;
????????}

????????
public??Vehicle?CreateCehicle()
????????
{
????????????ConstructorInfo??objConstrutor?
=?VehicleTYpe.GetConstructor(System.Type.EmptyTypes);
????????????Vehicle?c?
=?(Vehicle)objConstrutor.Invoke(null);
????????????
return?c;
????????}


????????
#endregion


???????
????}

在使用是,只要在創建時帶入需要創建的類的類型:

Code
static?void?Main(string[]?args)
????????
{

????????????
string?strType?=?"Car";

????????????Vehicle?v;
????????????ICreateVehicle?f?
=?null;

????????????
if?(strType?==?"Car")
????????????
{
????????????????f?
=?new?CreateVehicleByType("FactoryVehicle.Car");

????????????}

????????????
else?if?(strType?==?"Boat")
????????????
{
????????????????f?
=?new?CreateVehicleByType("Boat");
????????????}

????????????v?
=?f.CreateCehicle();
????????????Console.ReadLine();

????????}


通過反射技術,我們將很多的具體的工廠類簡化為一個類,并且新增加類型時不需要新的工廠類,這樣我們得到簡化的工廠,可以稱其為“反射工廠”。

2.實例

???????? 先來看看,大話設計模式中的利用反射加抽象工廠的數據訪問程序。先來看看反射技術的基本格式:

Assembly.Load(“程序集名稱”).CreateInstance(“命名空間.類名稱”);

只要在程序頂端寫上using System.Reflection來引用Reflection,就可以采用反射工廠來克服抽象工廠模式的先天不足。下面我們來看通過反射技術實現不同數據庫的訪問程序.

???????? 先來看結構圖:



?

DataAccess類,用反射技術,取代了抽象工廠中的IFactory,SqlServerFactoryAccessFactory
????
具體代碼:
????

Code
public?class?User
????
{
????????
private?int?_id;
????????
public?int?ID
????????
{
????????????
get?{?return?_id;?}
????????????
set?{?_id?=?value;?}
????????}


????????
private?string?_name;
????????
public?string?Name
????????
{
????????????
get?{?return?_name;?}
????????????
set?{?_name?=?value;?}
????????}

????}


????
public?class?Department
????
{
????????
private?int?_id;
????????
public?int?ID
????????
{
????????????
get?{?return?_id;?}
????????????
set?{?_id?=?value;?}
????????}


????????
private?string?_deptName;
????????
public?string?DeptName
????????
{
????????????
get?{?return?_deptName;?}
????????????
set?{?_deptName?=?value;?}
????????}

????}


????
public?interface?IUser
????
{
????????
void?Insert(User?user);

????????User?GetUser(
int?id);
????}


????
public?class?SqlserverUser?:?IUser
????
{
????????
public?void?Insert(User?user)
????????
{
????????????Console.WriteLine(
"在Sqlserver中給User表增加一條記錄");
????????}


????????
public?User?GetUser(int?id)
????????
{
????????????Console.WriteLine(
"在Sqlserver中根據ID得到User表一條記錄");
????????????
return?null;
????????}

????}


????
public?class?AccessUser?:?IUser
????
{
????????
public?void?Insert(User?user)
????????
{
????????????Console.WriteLine(
"在Access中給User表增加一條記錄");
????????}


????????
public?User?GetUser(int?id)
????????
{
????????????Console.WriteLine(
"在Access中根據ID得到User表一條記錄");
????????????
return?null;
????????}

????}


????
public?interface?IDepartment
????
{
????????
void?Insert(Department?department);

????????Department?GetDepartment(
int?id);
????}


????
public?class?SqlserverDepartment?:?IDepartment
????
{
????????
public?void?Insert(Department?department)
????????
{
????????????Console.WriteLine(
"在Sqlserver中給Department表增加一條記錄");
????????}


????????
public?Department?GetDepartment(int?id)
????????
{
????????????Console.WriteLine(
"在Sqlserver中根據ID得到Department表一條記錄");
????????????
return?null;
????????}

????}


????
public?class?AccessDepartment?:?IDepartment
????
{
????????
public?void?Insert(Department?department)
????????
{
????????????Console.WriteLine(
"在Access中給Department表增加一條記錄");
????????}


????????
public?Department?GetDepartment(int?id)
????????
{
????????????Console.WriteLine(
"在Access中根據ID得到Department表一條記錄");
????????????
return?null;
????????}

????}


????
public?class?DataAccess
????
{
????????
private?static?readonly?string?AssemblyName?=?"抽象工廠模式";
????????
private?static?readonly?string?db?=?"Sqlserver";
????????
//private?static?readonly?string?db?=?"Access";

????????
public?static?IUser?CreateUser()
????????
{
????????????
string?className?=?AssemblyName?+?"."?+?db?+?"User";
????????????
return?(IUser)Assembly.Load(AssemblyName).CreateInstance(className);
????????}


????????
public?static?IDepartment?CreateDepartment()
????????
{
????????????
string?className?=?AssemblyName?+?"."?+?db?+?"Department";
????????????
return?(IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
????????}

????}

調用代碼:

Code
????????????User?user?=?new?User();
????????????Department?dept?
=?new?Department();

????????????IUser?iu?
=?DataAccess.CreateUser();

????????????iu.Insert(user);
????????????iu.GetUser(
1);

????????????IDepartment?id?
=?DataAccess.CreateDepartment();
????????????id.Insert(dept);
????????????id.GetDepartment(
1);

????????????Console.Read();
????????}


????現在我們要增加Oracle數據訪問,相關類的增加是不可避免的,這點是無論我們用什么方法都解決不了的,這是擴展,依照開發-封閉原則,對于擴展,我們開放,但對與修改我們關閉。就現在的代碼中,我們要換Oracle很容易,只需將db=”Sqlserver”換成db=”Oracle”
????
現在我們需要增加Product,只需增加三個與Product相關的類,再修改一下DataAccess,在其中增加一個創建Product的方法就可以了。
????
現在我們要更換數據訪問程序是,我們還需要修改程序,重新編譯,我們可以利用配置文件來解決這個問題,首先要在我們的項目中添加config文件,內容如下:

Code
<?xml?version="1.0"?encoding="utf-8"??>
<configuration>
????
<appSettings>
????????
<add?key="DB"?value="Sqlserver"/>
????
</appSettings>
</configuration>


再在項目中引用

System.configuration,并在程序頭增加using System.configuration;, 然后修改DataAccess類的字段db的賦值代碼:
Code
class?DataAccess
????
{
????????
private?static?readonly?string?AssemblyName?=?"抽象工廠模式";
????????
private?static?readonly?string?db?=?ConfigurationManager.AppSettings["DB"];
????????
????????
public?static?IUser?CreateUser()
????????
{
????????????
string?className?=?AssemblyName?+?"."?+?db?+?"User";
????????????
return?(IUser)Assembly.Load(AssemblyName).CreateInstance(className);
????????}


????????
public?static?IDepartment?CreateDepartment()
????????
{
????????????
string?className?=?AssemblyName?+?"."?+?db?+?"Department";
????????????
return?(IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
????????}

????}


3.總結

???????? 使用反射工廠的優點是極大的減少了工廠類的數量,降低了代碼的冗余,并且系統更容易擴展,增加新類型后,不需要修改工廠類。

???????? 使用反射工廠的代價是工廠與產品之間的依賴關系不明顯,由于動態綁定,因此理論上可以用一個工廠完成很多類型的實例化,從而使得代碼不容易理解。另外就是增加了測試難度,因為創建是動態完成的。

???????? 采用反射技術創建的反射工廠可以使系統更靈活,使工廠和產品之間的依賴關系更小。在.NET的項目中大量的使用了反射工廠取代的傳統的工廠。

總結

以上是生活随笔為你收集整理的设计模式学习笔记六:.NET反射工厂的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。