継承によるいくつかの欠陥があるレガシーアプリケーションに取り組んでいますが、適切に解決するのに苦労しています。
現在、WinForms の構造は次のようになっています。
BaseForm
ListViewForm : BaseForm
ListViewFormReadOnly : ListViewForm
ListViewFormWithDetailForm : ListViewForm
DetailForm : BaseForm
ConcreteForm : ListViewFormWithDetailForm
BaseForm 内に sth like と呼ばれるメソッドがありprotected virtual void InitializeMyStuff()
、継承されたインスタンスで上書きされます。
例えば
public class BaseForm {
public BaseForm() {
//.. do stuff
//.. do other stuff like initialize DB connection or read app.config values and initialize properties..
}
public virtual void InitializeMyStuff() {
throw new NotImplementedException();
}
}
public class ListViewForm : BaseForm {
protected BindingSource GridBindingSource { get; set; }
public ListViewForm {
//do special stuff like adding the grid and some buttons
}
}
public class ConcreteForm : ListViewForm {
public override void InitializeMyStuff() {
GridBindingSource = my_bindingSource;
SomeOtherUsefulProperty = myValue;
Foo = new Bar();
// etc.
}
}
//Usage:
var myForm = new ConcreteForm();
myForm.InitializeMyStuff();
ご想像のとおり、これは次のような問題を引き起こします: - 「フォームを機能させるには、この時点で何を設定する必要がありますか?」 - 「まだ初期化されていない可能性のあるものは何ですか?」- 「まだ自由に使えるプロパティとメソッド呼び出しはどれか」と、その魔法のブラックボックスで何が起こっているのかについてのその他の興味深い考え。
何が起こっているのかをより明確にするために、これをリファクタリングするにはどうすればよいですか? これは、約 150 以上のコンクリート フォームを使用するプロジェクトであることを忘れないでください。
GridBindingSource
私の最初の考えは、たとえばのような魔法のプロパティをオブジェクト (eg FormConfiguration
) にカプセル化し、BaseForm
.
たとえば、そのようなもの
public class BaseForm {
private FormConfigObject _formConfig = new FormConfigObject();
protected override void OnLoad()
{
InitializeMyStuff(_formConfig);
}
protected virtual void InitializeMyStuff(FormConfigObject config)
{}
}
ここでの問題は、ListForm の FormConfig オブジェクトには、たとえば、他のプロパティが必要ですが、派生クラスの署名を..のisntead にGridBindingSource
変更することはできません。ListFormConfigObject
FormConfigObject
このジレンマから抜け出すための解決策を提案できる人はいますか?
// 編集: 実際に何が起こるかコードを整理し、コンストラクタ違反の仮想呼び出しを取り除きました。