gui*_*r80 8 c# constructor abstract-class base-class derived-class
我正在尝试为我正在编写的程序实现良好的设计模式。我有一个这样的班级结构。
abstract class SomeBase
{
public SomeObject obj { get; protected set; }
protected SomeBase(SomeObject x)
{
obj = x;
}
//Other methods and fields...
}
public class SomeDerived : SomeBase
{
public SomeDerived() : base(new SomeObject(this))
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在我确定您知道,您不能在基本构造函数中传递 this,因为此时对象尚未初始化。无论如何,我真的希望有一个解决方法。允许SomeDerived()处理基类字段的设置对我来说不是最佳实践。我想将这个新对象向上传递。
这是不可能的,在构造函数之后使用 Init 方法:
abstract class SomeBase
{
private SomeObject _obj { get; set; }
public SomeObject obj
{
get
{ // check _obj is inited:
if (_obj == null) throw new <exception of your choice> ;
return _obj;
}
}
protected SomeBase()
{
obj = null;
}
protected void Init()
{
obj = x;
}
//Other methods and fields...
}
public class SomeDerived : SomeBase
{
public SomeDerived() : base()
{
Init(new SomeObject(this));
}
}
Run Code Online (Sandbox Code Playgroud)
com*_*div -10
1)构造函数的设计根本就是错误的——它看起来像实例方法,但实际上它是半实例的半方法。
2)“具有模式的良好设计程序”不会导致聚合中类之间的直接循环依赖,正如我们在这里看到的那样 - 两个类必须在创建时相互了解和使用(!!!)谁知道 SomeObject 在它的“this”中做了什么构造函数???
因此,在“模式”中存在两个问题——类之间的高度依赖性和初始化逻辑的不可用封装。所以我们必须找到“模式”方法来解决它......嗯..该怎么办......
在您提供的代码中,我看到派生类只是为属性 obj 提供了它自己的逻辑,您可以将其重写为自动初始化属性
public abstract class MyClass{
private SomeObject _obj ;
public SomeObject Obj {get { return _obj ?? (_obj = InitializeObj() );}} //no setter needed
protected abstract SomeObject InitializeObj();
}
public class MyRealClass:MyClass {
protected override SomeObject InitializeObj(){
return new VerySpecialSomeObject(this, other, another, 1, 2 , false, option: new Options());
}
}
Run Code Online (Sandbox Code Playgroud)
对于您的示例,此类解决方案提供了获胜的单一“模式” - “多态性”))并获得额外的奖励 - 如果“Obj”没有用 - 它永远不会被创建))))
| 归档时间: |
|
| 查看次数: |
3361 次 |
| 最近记录: |