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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#设计模式之:抽象工厂模式与反射

發布時間:2025/4/16 C# 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#设计模式之:抽象工厂模式与反射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

抽象工廠模式【實例】:
定義一個用于創建對象的接口,讓子類決定實例化哪一個類

UML

?

代碼
class User
{
? ? private int _id;
? ? public int Id { get => _id; set => _id = value; }

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

interface IUser
{
? ?void Insert(User user);
? ?User GetUser(int id);
}

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

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

class SqlServerFactory : IFactory
{
? ? public IUser CreateUser()
? ? {
? ? ? ? return new SqlserverUser();
? ? }
}


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

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

class AccessFactory : IFactory
{
? ? public IUser CreateUser()
? ?{
? ? ? ? return new AccessUser();
? ?}
}

// test
User user = new User();
//IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);

// result
在Access中給User表增加一條記錄
在Access中根據ID得到User表一條記錄

抽象工廠模式(Abstract Factory)
提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類

UML

?


代碼
class Department
{
? ? ? private string name;
? ? ? private string id;

? ? ? public string Name { get => name; set => name = value; }
? ? ? public string Id { get => id; set => id = value; }
}

interface IDepartment
{
? ? ?void Insert(Department department);
? ? ?Department GetDepartment(int id);
}

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

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

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

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

class SqlServerFactory : IFactory
{
? ? public IUser CreateUser()
? ? ?{
? ? ? ? return new SqlserverUser();
? ? ?}

? ?public IDepartment CreateDepartment()
? ?{
? ? ? return new SqlserverDepartment();
? ?}
}
class AccessFactory : IFactory
{
? ?public IUser CreateUser()
? ?{
? ? ? ?return new AccessUser();
? ?}

? ?public IDepartment CreateDepartment()
? ?{
? ? ? ? return new AccessDepartment();
? ?}
}


// test
User user = new User();
Department dept = new Department();

//IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);

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


// result
在Access中給User表增加一條記錄
在Access中根據ID得到User表一條記錄
在Access中給Department表增加一條記錄
在Access中根據ID得到Department表一條記錄

IFactory 就是一個抽象工廠接口,它里面應該包含所有的產品創建的抽象方法
通常在運行時再創建一個ConcreteFactory類的實例,這個具體的工廠再創建具有特定實現的產品對象,也就是說為創建不同的產品對象,客戶商應使用不同的具體工廠

優點
便于交換系列產品,由于具體工廠類,在一個應用中只需要在初始化時出現一次,這使得改變一個應用的具體工廠變得很容易,它只要改變具體工廠即可使用不同的產品配置
它讓具體的創建實例過程與客戶端分離,客戶端是通過它們的抽象接口操縱實例,產品的具體類名也被具體的工廠實現分離,不會出現在客戶代碼中

缺陷
1,添加新的表,要更改多個工廠類
2,程序中有多個地方使用了

IFactory factory = new AccessFactory();
1
現在換個數據庫

IFactory factory = new SqlServerFactory();
1
你也要更改多個地方

總結:

簡單工廠模式:管理對象類 調用接口

抽象工廠模式:接口實現類 調用接口

用簡單工廠改進其缺陷
去除IFactory、SqlServerFactory和AccessFactory三個工廠類
使用DataAccess類取代它們

UML

?


代碼
class DataAccess
{
? ? private static readonly string db = "SqlServer";
? ? // private static readonly string db = "Access";

? ?public static IUser CreateUser()
? {
? ? ? ?IUser result = null;
? ? ? switch (db)
? ? ? {
? ? ? ? ?case "SqlServer":
? ? ? ? ?result = new SqlserverUser();
? ? ? ? ?break;
? ? ? ? ?case "Access":
? ? ? ? ?result = new AccessUser();
? ? ? ? ?break;
? ? ?}
? ? ? return result;
}

public static IDepartment CreateDepartment()
{
? ? ? IDepartment result = null;
? ? ? switch (db)
? ? ?{
? ? ? ? case "SqlServer":
? ? ? ? result = new SqlserverDepartment();
? ? ? ? break;
? ? ? ? case "Access":
? ? ? ? result = new AccessDepartment();
? ? ? ? break;
? ? ?}
? ? ? return result;
? ?}
}
// test
User user = new User();
IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);

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

// result
在SQL Server中給User表增加一條記錄
在SQL Server中根據ID得到User表一條記錄
在SQL Server中給Department表增加一條記錄
在SQL Server中根據ID得到Department表一條記錄

這里使用了簡單工廠的方法來解決了上面的缺陷,但同時又產生了新的問題(switch問題)
如果要新增Oracle數據庫,抽象工廠本來只要增加一個OracleFactory工廠即可,這里簡單工廠要修改switch增加case

.NET中的依賴注入( Dependency Injection)
using System.Reflection;

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


// 常規寫法
IUser result = new SqlServerUser();

// 反射寫法
using System.Reflection;

IUser result = (IUser)Assembly.Load("抽象工廠模式").CreateInstance("抽象工廠模式.SqlServerUser");

使用反射的具體代碼

using System.Reflection;

class DataAccess
{
? ? ?private static readonly string AssemblyName = "PatternTest";

? ? ?private static readonly string db = "AbstractPattern.Sqlserver";
? ? ?// private static readonly string db = "AbstractPattern.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);
? }
}

上述代碼同樣得到了結果

如果我們增加了Oracle數據訪問,相關的類的增加是不可避免的,不過這叫擴展,開閉原則告訴我們對于擴展開放,對于修改關閉
我們只要修改db字符串變量的值為

// private static readonly string db = "AbstractPattern.Oracle";
1
每次更換數據庫時還是要修改程序修改db值重編譯,如果可以不修改程序,才是真正的開放-封閉原則

解決方案:使用配置文件

轉載于:https://www.cnblogs.com/lvjy-net/p/10430762.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的C#设计模式之:抽象工厂模式与反射的全部內容,希望文章能夠幫你解決所遇到的問題。

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