包含子属性的子类的设计模式

时间:2016-07-28 21:42:07

标签: c# design-patterns

我想知道是否有一种设计模式可以解决这个问题。 我的结构看起来像这样:

    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类中创建属性。有这种结构的设计模式或一些简单的方法吗?

2 个答案:

答案 0 :(得分:0)

这可能会满足您的需求:

    Dim newElem As XmlElement = doc.CreateElement("/Content/Catalog/Feature[7]/Option")

如果你正在使用ReSharper(或类似的),它可能会嘲笑你在构造函数中调用虚拟成员,但只要你的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 } } 调用并不依赖于它就应该没问题在派生类的构造函数中设置的任何内容。

答案 1 :(得分:0)

据我所知,你的情况是这样的:

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创建另一个抽象。