題目如下:
假設(shè)你正在為一家汽車制造公司編寫軟件。公司生產(chǎn)多種類型的汽車,包括轎車、SUV和卡車。每種汽車都有不同的特點(diǎn)和功能。
請(qǐng)?jiān)O(shè)計(jì)一個(gè)工廠模式,用于創(chuàng)建不同類型的汽車對(duì)象。該工廠模式應(yīng)具有以下要求:
工廠類名為 CarFactory,包含一個(gè)靜態(tài)方法 CreateCar,根據(jù)傳入的參數(shù)類型,返回對(duì)應(yīng)類型的汽車對(duì)象。
汽車類 Car 是一個(gè)抽象類,包含一個(gè)抽象方法 Drive,用于描述汽車的駕駛行為。
轎車類 Sedan 繼承自 Car 類,實(shí)現(xiàn)了 Drive 方法,在 Drive 方法中輸出“駕駛轎車”。
SUV 類繼承自 Car 類,實(shí)現(xiàn)了 Drive 方法,在 Drive 方法中輸出“駕駛SUV”。
卡車類 Truck 繼承自 Car 類,實(shí)現(xiàn)了 Drive 方法,在 Drive 方法中輸出“駕駛卡車”。
使用該工廠模式完成以下操作:
在程序入口處,向 CarFactory 的 CreateCar 方法傳入?yún)?shù) "sedan",并將返回的對(duì)象存儲(chǔ)到 sedanCar 變量中。
在 sedanCar 上調(diào)用 Drive 方法,觀察輸出結(jié)果。
同樣地,創(chuàng)建一個(gè) SUV 對(duì)象,并調(diào)用其 Drive 方法。
創(chuàng)建一個(gè) Truck 對(duì)象,并調(diào)用其 Drive 方法。
請(qǐng)根據(jù)以上要求實(shí)現(xiàn)該工廠模式,并編寫相應(yīng)的代碼。
簡(jiǎn)單工廠實(shí)現(xiàn):
using System;
using System.Reflection;
namespace Factory
{
internal class CarFactory
{
public static T CreateCar<T>() where T : Car, new()
{
if (typeof(T) == typeof(Sedan))
return new Sedan() as T;
if (typeof(T) == typeof(SUV))
return new SUV() as T;
if (typeof(T) == typeof(Truck))
return new Truck() as T;
throw new ArgumentException("無法創(chuàng)建該類型的汽車對(duì)象。");
}
}
}
namespace Factory
{
public abstract class Car
{
public abstract void Drive();
}
}
using System;
namespace Factory
{
internal class Program
{
static void Main(string[] args)
{
Car sedanCar = CarFactory.CreateCar<Sedan>();
sedanCar.Drive();
Car suvCar = CarFactory.CreateCar<SUV>();
suvCar.Drive();
Car truckCar = CarFactory.CreateCar<Truck>();
truckCar.Drive();
Console.ReadLine();
}
}
}
上述代碼給出了抽象基類的基本定義,和泛型工廠的實(shí)現(xiàn)方式,以及調(diào)用方式。
值得注意的是where T : Car, new()
這個(gè)條件:where T : Car, new()
是對(duì)泛型類型參數(shù) T
的約束。這個(gè)約束表明泛型類型參數(shù) T
必須滿足兩個(gè)條件:
T
必須是 Car
類或者其派生類:表示 T
必須是 Car
類型或者 Car
類的子類(派生類)。
T
必須具有無參構(gòu)造函數(shù):通過 new()
約束,表示 T
必須具有一個(gè)無參構(gòu)造函數(shù),即能夠使用 new T() 創(chuàng)建 T
的實(shí)例。
上述約束的作用是為了確保泛型類型參數(shù) T
在使用過程中是符合要求的。約束 T
必須是 Car
類型或其派生類型,以保證在 CreateCar
方法中創(chuàng)建的對(duì)象是 Car
類型或其子類的實(shí)例;同時(shí),約束 T
必須具有無參構(gòu)造函數(shù),以確保可以通過 new T()
的方式來創(chuàng)建 T
的實(shí)例。
通過這樣的約束,可以確保在調(diào)用 CreateCar
方法時(shí),傳入的 T
類型參數(shù)滿足指定的要求,并且能夠在方法內(nèi)部根據(jù) T
的類型來創(chuàng)建相應(yīng)的對(duì)象實(shí)例。
工廠模式適用于以下場(chǎng)景:
對(duì)象創(chuàng)建復(fù)雜:當(dāng)對(duì)象的創(chuàng)建涉及到復(fù)雜的邏輯判斷、依賴關(guān)系或者大量的初始化操作時(shí),可以使用工廠模式來封裝對(duì)象的創(chuàng)建過程。這樣可以簡(jiǎn)化客戶端代碼,并提供一個(gè)統(tǒng)一的入口來創(chuàng)建對(duì)象。
對(duì)象類型不確定:當(dāng)需要根據(jù)不同的條件或者配置來創(chuàng)建不同類型的對(duì)象時(shí),可以使用工廠模式。通過工廠模式,可以將對(duì)象的創(chuàng)建邏輯從客戶端代碼中分離出來,降低代碼的耦合性。
擴(kuò)展性要求高:當(dāng)系統(tǒng)中需要添加新的產(chǎn)品或者變化頻繁時(shí),使用工廠模式可以方便地?cái)U(kuò)展和修改代碼。通過增加新的具體工廠和產(chǎn)品類,而無需修改已有代碼,符合開閉原則。
隱藏對(duì)象創(chuàng)建細(xì)節(jié):當(dāng)需要隱藏對(duì)象創(chuàng)建的細(xì)節(jié)時(shí),可以使用工廠模式??蛻舳酥恍枰c工廠接口進(jìn)行交互,無需關(guān)心具體的產(chǎn)品如何創(chuàng)建或?qū)崿F(xiàn)。
總的來說,工廠模式適用于對(duì)象創(chuàng)建復(fù)雜、對(duì)象類型不確定、擴(kuò)展性要求高以及隱藏對(duì)象創(chuàng)建細(xì)節(jié)的情況。它能夠提供靈活、可擴(kuò)展和易于維護(hù)的代碼結(jié)構(gòu)。
從代碼中我們可以看出CarFactory
這個(gè)工廠類是有弊端的,比如每次添加新的汽車對(duì)象我們都需要去修改CarFactory
類中的CreateCar
,添加一條新的對(duì)象。此時(shí)我們可以采用動(dòng)態(tài)工廠,通過反射的形式去創(chuàng)建對(duì)象。文章來源:http://www.zghlxwxcb.cn/news/detail-667868.html
using System;
using System.Reflection;
namespace Factory
{
internal class CarFactory
{
public static T CreateCar<T>(string typeName) where T : Car, new()
{
Type type = GetTypeByName(typeName);
if (type != null && typeof(T).IsAssignableFrom(type)) return Activator.CreateInstance(type) as T;
throw new ArgumentException("無法創(chuàng)建該類型的汽車對(duì)象。");
}
private static Type GetTypeByName(string typeName)
{
return Assembly.GetAssembly(typeof(CarFactory)).GetType($"Factory.{typeName}");
}
}
}
using System;
namespace Factory
{
internal class Program
{
static void Main(string[] args)
{
// 傳遞具體類的類型名稱作為參數(shù)
string typeName = "Sedan";
Car sedan = CarFactory.CreateCar<Sedan>(typeName);
sedan.Drive();
// 可以根據(jù)需要?jiǎng)?chuàng)建不同類型的汽車對(duì)象
typeName = "SUV";
Car suv = CarFactory.CreateCar<SUV>(typeName);
suv.Drive();
typeName = "Truck";
Car truck = CarFactory.CreateCar<Truck>(typeName);
truck.Drive();
Console.ReadLine();
}
}
}
這樣核心工廠代碼我們就不需要修改呢。
通過傳進(jìn)來的typeName
去動(dòng)態(tài)生成實(shí)例,其中Assembly.GetAssembly(typeof(CarFactory))
是獲取當(dāng)前類型所處的程序集。Factory.{typeName} 為 命名空間.類
另外 typeof(T).IsAssignableFrom(type)
意思為當(dāng)前T
類型是否和Type
類型可以進(jìn)行轉(zhuǎn)換,比如type
是不是T的基類或者派生類。Activator.CreateInstance(type) as T
用于創(chuàng)建實(shí)例。文章來源地址http://www.zghlxwxcb.cn/news/detail-667868.html
到了這里,關(guān)于【創(chuàng)建型設(shè)計(jì)模式】C#設(shè)計(jì)模式之工廠模式,以及通過反射實(shí)現(xiàn)動(dòng)態(tài)工廠。的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!