2016-07-28 14 views
0

この問題を解決するデザインパターンがあるかどうかは疑問です。子プロパティを含む子クラスのデザインパターン

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 
    } 

私はOldDBMetaDataに属しているプロパティを設定しますOldDBAcessでメソッドを呼び出すことができるようにしたい: 私はこのようになります構造を有しています。メタデータはメタデータオブジェクトではなく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; 
     } 
    } 

これはうまく動作しますが、私はちょうどメタデータがタイプでOldMetaDataであることを確認する必要がありますする必要はありません私がメソッドを呼び出すたびに。私はそれがコンストラクタでこの型に設定されているので、この型のことを知っています。派生クラスまたは基本クラスのいずれかでmetaDataプロパティを使用したいので、それぞれのDBAccessクラスにプロパティを作成するだけではありません。このような構造でこれを行うためのデザインパターンや簡単な方法はありますか?

+0

あなたの質問には欠けている部分があると思います。たとえば、OldDBMetaDataがOldDBAccessのコンストラクタでnew'dであるとします。次に、OldDBAccessのメソッドであるSetOldNameというメソッドを提供します。したがって、OldDBAccessは構築してから型を正確に認識しています。また、サンプルメソッドでは、クラス名が変更されています(AccountMetaDataはMetaDataと同じですか?OldDBMetaDataはOldMetaDataと同じですか?)。 –

+0

廃止されたプロパティとメソッド( 'OldMetaData'ではなく、' NewMetaData'ではないもの)をno-opsにするようにしますか? – FMM

+0

@ TrevorAsh、そうです、私は一貫性のないいくつかのメソッドクラス名を持っていました。私は今彼らを固定してより意味をなさせるべきです。 – stacy

答えて

0

これは、あなたが必要なものを行うことがあります。

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()呼び出しは、派生クラスのコンストラクタで設定されたものに依存しません。

+0

これは機能しますが、問題はありません。私のコードはすでにこのようなことをしています。私が持っている問題は、OldDBMetaDataクラスにしか属していないプロパティを設定しようとするOldDBAccessでは、アクセスする前にMetaDataがOldDBMetaData型であることを確認する必要があります。 OldDBAccessのメソッドにあれば、MetaDataの型はOldDBMetaDataです – stacy

+0

Ahhh ...私は知っているので、毎回型をチェックせずにこれを行う方法が必要です... – FMM

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の別の抽象クラスを作成することができます。

関連する問題