[英]Design pattern for child class that contains child property
我想知道是否存在可以解決此問題的設計模式。 我有一個看起來像這樣的結構:
public abstract class DBAccess
{
protected MetaData MetaData;
}
public class OldDBAccess: DBAccess
{
//this class will set metatData = new OldDBMetaData(); in the constructor
}
public class NewDBAccess: DBAccess
{
//this class will set metaData = new NewMetaData(); in the constructor
}
public abstract class MetaData
{
//some variables and methods that belong to all MetaData objects
}
public class OldMetaData : MetaData
{
string oldName;
//some variables and methods that belong to only OldDBMetaData objects
}
public class NewMetaData : MetaData
{
//some variables and methods that belong to only NewDBMetaData
}
我希望能夠在OldDBAcess中調用設置屬於OldDBMetaData的屬性的方法。 由於metaData是MetaData對象而不是OldDBMetaData對象,因此到目前為止,我必須這樣做:
//method in OldDBAccess
public void SetOldName(string name)
{
if(metaData is OldMetaData)
{
OldMetaData metaData = (OldMetaData)MetaData;
if (metaData == null)
// metaData isn't of type OldMetaData
else
metaData.oldName = name;
}
}
這很好,我只是不想在每次調用方法時都必須檢查metaData是否為OldMetaData類型。 我知道它是這種類型的,因為我在構造函數中將它設置為這種類型。 我想在派生類或基類中使用metaData屬性,所以我不能只在每個DBAccess類中創建屬性。 使用這種結構是否有設計模式或一些簡單的方法可以做到這一點?
這可能會滿足您的需求:
public sealed class OldDbAccess : DbAccess
{
protected override MetaData CreateMetaData()
{
// return old metadata
}
}
public class DbAccess
{
public DbAccess()
{
this.MetaData = CreateMetaData();
}
protected virtual MetaData CreateMetaData()
{
// return new metadata
}
}
如果您使用的是ReSharper(或類似的工具),它可能會在您調用構造函數中的虛擬成員時讓您CreateMetaData()
,但這應該沒問題,只要您的CreateMetaData()
調用不依賴於派生類的構造函數中設置的任何內容即可。 。
據您了解,您的情況是這樣的:
public abstract class MetaData
{
public string Name { get; set; }
}
public class OldDBMetaData : MetaData
{
public string OldName { get; set; }
}
public class NewDBMetaData : MetaData
{
public string NewName { get; set; }
}
例如,您的問題將在TestSetName方法中發生
public abstract class DBAccess
{
protected MetaData metaData;
}
public class OldDBAccess : DBAccess
{
public OldDBAccess()
{
metaData = new OldDBMetaData();
}
public void TestSetName(string name)
{
// You want to do this one, but you cannot because the abstract class MetaData doest not exist OldName property
// metaData.OldName = name;
// I can simple resolve this problem by cast this to the OldDBMetaData
((OldDBMetaData)metaData.OldName) = name;
}
}
以我的觀點,我們可以通過CAST解決此問題,但是它將與實現結合在一起。 如果要避免這種情況,可以為OldDBMetaData和NewDBMetaData創建另一個抽象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.