簡體   English   中英

包含子屬性的子類的設計模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM