次のように、関連するクラスのさまざまなグループを実装しようとしています。
- MySQLデータベース
- MySQLTable (MySQLDatabase を参照)
- MySQLRecord (MySQLTable を参照)
- PostGreデータベース
- PostGreTable (PostGreDatabase を参照)
- PostGreRecord (PostGreTable を参照)
- Oracleデータベース
- ...
相対クラス (MySQLTable、PostGreTable など) には多くの共有コードがあるため、次のように、抽象親クラスとジェネリックを使用してこれを実装しました。
class Database {}
class Table<DatabaseType> where DatabaseType : Database
{
public DatabaseType FDatabase; //this is what I mean by "references"
}
class Record<TableType, DatabaseType> where
DatabaseType : Database
TableType : Table<DatabaseType>
{
public TableType FTable;
}
class MySQLDatabase : Database {}
class MySQLTable : Table<MySQLDatabase>
{
public string FCharset;
}
MySQLRecord : Record<MySQLTable, MySQLDatabase> {}
...
そして、このアーキテクチャで次のことができるようにする必要があります。
- 間違った参照を防ぎます。
例: MySQLTable は PostGreDatabase または OracleDatabase を参照できません。MySQLDatabase のみを参照できます。
- プログラマーがキャストを必要とせずにオブジェクト固有のプロパティにアクセスできるようにします。
例:
SomeMySQLRecord.FTable.FCharset = 'UTF-8';
それ以外の
((MySQLTable)SomeMySQLRecord.FTable).Charset = 'UTF-8';
クラスの実際のグループには3つ以上のクラスがあり、ジェネリックが実際にコードを忍び寄っているため、これを行うためのよりエレガントな方法(またはパターン)を探しています。例:
MyType : Type1<GType1, GType2, GType3, GType4> where
GType1 : Type2,
GType2 : Type3<GType1>,
GType3 : Type4<GType1, GType2>,
GType4 : Type5<GType2, GType1, Type2, GType3>