求解一下大佬們,假設有CarBuilderBase的抽象類派生出來BmwBuilder和BenzBuilder類,而實體有CarInstanceBase的抽象類繼承出比如BmwInstance和BenzInstance類,而每個Instance類中對應著Builder類,這種情況如何存盤才能從容的使用多型? 目前的做法是在CarInstanceBase中public CarBuilderBase Builder,而這樣存盤的話每次呼叫實際的類的時候必須要用as或者is來轉,這樣也就沒有派生類的意義了,那應該怎么存盤使用呢?
uj5u.com熱心網友回復:
假設有汽車類: abstract class CarInstanceBase { }
class BmwInstance : CarInstanceBase { }
class BenzInstance : CarInstanceBase { }
假設有汽車工廠概念:
abstract class CarBuilderBase
{
public abstract CarInstanceBase BuildCarInstance();
}
強型別的汽車工廠,當然需要知道型別。由于C#支持泛型,強型別的汽車工廠大約可以這樣寫:
abstract class CarBuilder<T> : CarBuilderBase where T : CarInstanceBase
{
public override CarInstanceBase BuildCarInstance()
{
return Build();
}
public abstract T Build();
}
class BmwCarBuilder : CarBuilder<BmwInstance>
{
public override BmwInstance Build() => new BmwInstance();
}
class BenzCarBuilder : CarBuilder<BenzInstance>
{
public override BenzInstance Build() => new BenzInstance();
}
可以這樣創建汽車:
class 單元測驗
{
void CreateCarInstances()
{
BmwInstance bmw = new BmwCarBuilder().Build();
BenzInstance benz = new BenzCarBuilder().Build();
}
}
如果要管理多個汽車工廠,可以大概這樣做:
static class KnownCarBuilder
{
public static T Build<T>() where T : CarInstanceBase
{
return (T)s_builders[typeof(T)].BuildCarInstance();
}
public static CarInstanceBase Build(string make)
{
return s_builders.First(x => x.Key.Name.StartsWith(make, StringComparison.OrdinalIgnoreCase)).Value.BuildCarInstance();
}
public static void RegisterCarBuilder<T>(CarBuilder<T> builder) where T : CarInstanceBase
{
s_builders[typeof(T)] = builder;
}
static KnownCarBuilder()
{
RegisterCarBuilder(new BmwCarBuilder()); // 也可以用反射來進行自發掘和登記。
RegisterCarBuilder(new BenzCarBuilder());
}
static readonly Dictionary<Type, CarBuilderBase> s_builders = new Dictionary<Type, CarBuilderBase>();
}
class Program
{
static void Main()
{
BmwInstance bmw = KnownCarBuilder.Build<BmwInstance>();
BenzInstance benz = KnownCarBuilder.Build<BenzInstance>();
CarInstanceBase[] cars = new[] { KnownCarBuilder.Build(make: "BMW"), KnownCarBuilder.Build(make: "Benz") };
}
}
uj5u.com熱心網友回復:
之前派生類名字寫錯了。更正一下。public static void Main(string[] args)
{
CarBuilderBase cb = new CarBuilderBase();
BmwInstance bmw = cb.Builder<BmwInstance>();
BenzInstance bz = cb.Builder<BenzInstance>();
bmw.Test(); //BMW
bz.Test(); //Benz
Console.ReadLine();
}
public abstract class CarInstanceBase
{ }
public class BmwInstance : CarInstanceBase
{
public void Test() => Console.WriteLine("BMW");
}
public class BenzInstance : CarInstanceBase
{
public void Test() => Console.WriteLine("Benz");
}
public class CarBuilderBase
{
public virtual T Builder<T>() where T : CarInstanceBase, new()
{
return new T();
}
}
uj5u.com熱心網友回復:
不知道你的CarBuilderBase中,各自的builder是不是實作邏輯一定相同。如果不同的話,你就繼續生成派生類各自實作。那就和樓上差不多了。
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
設計模式中的工廠模式轉載請註明出處,本文鏈接:https://www.uj5u.com/net/102068.html
標籤:C#
上一篇:執行緒阻塞問題
下一篇:VScode新手問題,除錯程序出現Unable to perform this action because the process is running.
