我沒有使用.Net仿製藥的經驗。我正在爲.Net 4.0中的投資控股公司設計一個軟件系統。該公司擁有零售業務和IntellectualRights業務。 BookShop和AudioCDShop是零售業務的例子。 EngineDesignPatent和BenzolMedicinePatent是IntellectualRights業務的例子。這兩種業務類型完全無關。如何使用泛型實現此功能?
該投資公司有一個名爲投資回報的概念。這是從每項業務中獲得的利潤。對於每個「業務類型」(Retail,IntellectualRights),投資回報的計算邏輯都不相同。
我需要通過計算每個「業務類型」的投資來創建一個InvestmentReturnCalculator。
public static class InvestmentReturnCalculator
{
public static double GetNetInvestementReturn(List<IBusiness> allMyProfitableBusiness, List<InvestmentReturnElement<IBusiness>> profitElements)
{
double totalReturn = 0;
foreach (IBusiness b in allMyProfitableBusiness)
{
//How to do calculation?
}
return totalReturn;
}
}
問題
如何不同的業務元素添加到
List<InvestmentReturnElement<IBusiness>>
profitElements在Main
功能?注意:我在執行以下操作時遇到編譯錯誤 profitElements.Add(salesProfitBook);
如何以通用方式實現GetNetInvestementReturn方法?如果我的代碼如下所示,不同類型的算法會有重複。對於多種類型,算法相同時可以使用泛型。所以下面的方法不是
DRY
。
注意:下面的代碼不能編譯。
foreach (IBusiness b in allMyProfitableBusiness)
{
if (b is IRetailBusiness)
{
RetailProfit<IRetailBusiness> retailInvestmentProfit = new RetailProfit<IRetailBusiness>();
totalReturn = totalReturn + retailInvestmentProfit.GetInvestmentProfit(b);
}
else if (b is IIntellectualRights)
{
IntellectualRightsProfit<IIntellectualRights> intellectualRightsInvestmentProfit = new IntellectualRightsProfit<IIntellectualRights>();
totalReturn = totalReturn + intellectualRightsInvestmentProfit.GetInvestmentProfit(b);
}
}
UPDATE:
的BookShop
,EngineDesignPatent
繼承的不同的基類。所以我不能將IBusiness
,IRetailBusiness
和IIntellectualRights
作爲抽象類。他們應該保持爲interfaces
。
現在@Grzenio建議在每個實體(BookShop,AudioCDShop等)中實施GetInvestmentProfit
方法。在這裏,我將重複相同的代碼。這再次不令人滿意DRY
。
此外InvestmentReturn
概念是爲投資控股公司。各種業務類型都不知道這樣的概念。
投資回報元素
public abstract class InvestmentReturnElement<T>
{
public abstract double GetInvestmentProfit(T obj);
}
public class RetailProfit<T> : InvestmentReturnElement<T> where T : IRetailBusiness
{
public override double GetInvestmentProfit(T item)
{
return item.Revenue * 5/100;
}
}
public class IntellectualRightsProfit<T> : InvestmentReturnElement<T> where T : IIntellectualRights
{
public override double GetInvestmentProfit(T item)
{
return item.Royalty * 10/100;
}
}
企業類型抽象
public interface IBusiness
{
}
public interface IRetailBusiness : IBusiness
{
bool IsOnSale { get; set; }
double Revenue { get; set; }
}
public interface IIntellectualRights : IBusiness
{
double Royalty { get; set; }
}
混凝土企業
#region Intellectuals
public class EngineDesignPatent : IIntellectualRights
{
public double Royalty { get; set; }
}
public class BenzolMedicinePatent : IIntellectualRights
{
public double Royalty { get; set; }
}
#endregion
#region Retails
public class BookShop : IRetailBusiness
{
public bool IsOnSale { get; set; }
public double Revenue { get; set; }
}
public class AudioCDShop : IRetailBusiness
{
public bool IsOnSale { get; set; }
public double Revenue { get; set; }
}
#endregion
客戶
class Program
{
static void Main(string[] args)
{
#region MyBusines
List<IBusiness> allMyProfitableBusiness = new List<IBusiness>();
BookShop bookShop1 = new BookShop();
AudioCDShop cd1Shop = new AudioCDShop();
EngineDesignPatent enginePatent = new EngineDesignPatent();
BenzolMedicinePatent medicinePatent = new BenzolMedicinePatent();
allMyProfitableBusiness.Add(bookShop1);
allMyProfitableBusiness.Add(cd1Shop);
allMyProfitableBusiness.Add(enginePatent);
allMyProfitableBusiness.Add(medicinePatent);
#endregion
List<InvestmentReturnElement<IBusiness>> profitElements = new List<InvestmentReturnElement<IBusiness>>();
var salesProfitBook = new RetailProfit<BookShop>();
var salesProfitAudioCD = new RetailProfit<AudioCDShop>();
var intellectualProfitEngineDesign = new IntellectualRightsProfit<EngineDesignPatent>();
var intellectualProfitBenzolMedicine = new IntellectualRightsProfit<BenzolMedicinePatent>();
//profitElements.Add(salesProfitBook);
Console.ReadKey();
}
}
爲了實現這一點,你是對的,現在你需要使用反射來確定類型和調用正確的方法。更好的解決方案是使用像GetProfit這樣的方法創建一個通用接口,並使每個業務對象繼承此接口並實現GetProfit,但是您需要在每個業務中使用該接口。 – Phaeze
_在這裏我將重複相同的代碼。再次,這不令人滿意DRY._我不同意這一點。如果每個實體的公式不同(即使只是略有不同),那麼您的設計仍然是乾的。 –
可以在Eric Lippert的博客中找到類似[Curiously Recurring Template Pattern](http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx)的幫助嗎? – Lijo