我已经尽力自己研究这个问题,但我一直找不到好的答案。很可能是因为我不知道提出问题的正确方法。所以我只是把所有东西扔到那里。
这是我所拥有的两个班级的基本结构。 (显然不是实际的代码。)
class ship
{
public int baseStat = 0; //I want this to be protected
public int derivedStat = 0; //This should also be protected
public int DerivedStat{ get { return derivedStat ; } }
private List<Component> components;
public void DeriveStats()
{
foreach(Component component in components)
{
component.DeriveStats(this);
}
}
}
class Component
{
public void DeriveStats(Ship ship)
{
ship.derivedStat = ship.baseStat + 5;
}
}
这一切都运行得很好,我有许多不同类型的Component子类,它们对船舶和它的统计数据做了不同的事情,但是通过这种设置,所有统计数据都可以在船舶类之外查看和修改。设计明智,这看起来并不正确,坦率地说,它让我疯狂。
我可以采用更清洁/更正确的方法吗?
编辑 -
非常感谢所有评论并给出答案的人,这是一个巨大的帮助。如果其他人偶然发现了这个问题,那么我就是如何解决这个问题的。
abstract class Ship
{
//Locking variable that only allows the ship's stats to be updated when true
private bool _isModifying = false;
//General Stats that define a ship******************************
//Layers of shields
protected int baseShields;
public int DerivedShields
{
get{ return DerivedShields; }
set
{
if (_isModifying)
DerivedShields = value;
else
throw (new Exception("Ship stats cannot be modified outside the ship class."));
}
}
//**************************************************************
protected List<Component> installedComponents;
public void DeriveStats()
{
_isModifying = true;
foreach (Component component in installedComponents)
{
component.DeriveStats(this);
}
_isModifying = false;
}
}
class BasicShield : Component
{
public override void DeriveStats(Ship ship)
{
ship.DerivedShields = ship.DerivedShields + 1;
}
}
答案 0 :(得分:1)
向Ship
添加允许其他人更改Ship
的方法,但赋予Ship
责任并确保其自身一致性的能力。这意味着
Ship
,但Ship
可以拒绝此类请求,如果他们违反了某些约束(或Ship
只是感觉不喜欢更新原因)。Ship
的实现细节与程序的其余部分分离。您可以自由地改变表示Ship
内部状态的方式。修改强>
如果您希望每个Component实现确定新统计数据的算法,您可以
这具有额外的好处,即船舶负责汇总来自不同组件的结果。由于组件彼此不了解,他们如何协调谁决定船舶的统计数据?
答案 1 :(得分:0)
我可以想到两种方式
组件应该计算东西(yr情况下的统计数据)并返回它。 ship类使用返回值
更新自身 ...
public void DeriveStats()
{
foreach(Component component in components)
{
derivedStat = component.DeriveStats(this);
}
}
class Component
{
public int DeriveStats(Ship ship)
{
return ship.baseStat + 5;
}
}
该船具有组件调用的UpdateStats方法。
...
public void DeriveStats()
{
foreach(Component component in components)
{
component.DeriveStats(this);
}
}
}
class Component
{
public void DeriveStats(Ship ship)
{
ship.UpdateStats(ship.baseStat + 5);
}
}
答案 2 :(得分:0)
您可以使用属性来保持相同的基本属性,并根据其组件计算船舶的有效统计数据。
class Ship
{
private int _baseStat = 0; //I want this to be protected
public int CalculatedStat
{
get
{
int result = _baseStat;
foreach(Component component in components)
{
result += component.Modifier
// you'll have to add modifier to Component yourself
// in this case, you'd set it to 5
}
return result;
}
...
答案 3 :(得分:0)
首先,您可以声明这样的属性,以便它们受到保护。
public int BaseStat ( get; protected set; }
public int DerivedStat { get; protected set; }
其次,根据所描述的场景,以下可能是更好的属性。或者,如果您不想继续计算它,您可以更新受保护的财产“发货”。以类似的方式。
public int DerivedStat
{
get
{
var derivedStat = 0;
foreach (var component in components)
{
derivedStat += baseStat + 5;
}
return derivedStat;
}
}
答案 4 :(得分:0)
如果我正确地阅读了您的问题,那么您几乎就在那里public int DerivedStat{ get { return derivedStat ; } }
- 使用您应该受保护字段的访问者。在这个非常基本的示例中,您可以在set方法中进行一些验证,如下所示。这样,其他类就不会看到ship
的内部结构,但是他们可以尝试来修改它。
以下内容如何:
class ship
{
protected int baseStat = 0; //I want this to be protected - now it is
private int derivedStat = 0; //This should also be protected - can even be private
public int DerivedStat {
get
{
return derivedStat;
}
set
{
if(value < 0)
throw new Exception("Validate your data here!");
derivedStat = value;
}
}
}
答案 5 :(得分:0)
通过A处理的B上的事件......
A可以通过向其集合添加A来注册B事件,并在删除时使用ObservableCollection注销并监视其更改。