我一直在为这个问题挠头,想找出最好的办法。比方说我有一个Model类,它是可选择的,所有可选择的对象都可以改变它们的颜色以显示它们被选择了.我想把这些功能放到单独的接口中,因为有些东西可以改变颜色,而这些东西不一定是可选择的,然而,所有可选择的东西都需要是IColourable的,所以我可以让ISelectable接口继承IColourable接口这样。
interface ISelectable : IColourable
{
void SetIsSelected(bool isSelected);
}
interface IColourable
{
void UpdateColour(Color color);
}
class Model : ISelectable
{
private bool _isSelected;
public void UpdateColour(Color color)
{
...
}
public void SetIsSelected(bool isSelected)
{
_isSelected = isSelected;
}
}
所以现在我想让模型类保持小规模 (因为它实现了很多其他接口) 让我们把ISelectable和IColourable的实现委托给另一个对象--比如ModelSelectableImpl和ModelColourableImpl。
所以现在类Model看起来像。
class Model : ISelectable
{
private ISelectable _selectableImplementation;
private IColourable _colourableImplementation;
public Model()
{
_selectableImplementation = new ModelSelectableImpl(this);
_colourableImplementation = new ModelColourableImpl(this);
}
public void SetIsSelected(bool isSelected)
{
_selectableImplementation.SetIsSelected(isSelected);
}
public void UpdateColour(Color color)
{
_colourableImplementation.UpdateColour(color);
}
}
我有另外两个类来实现模型的接口。
class ModelColourableImpl : IColourable
{
private IColourable target;
public ModelColourableImpl(IColourable colourable)
{
target = colourable;
}
public void UpdateColour(Color color)
{
// Update targets colour
}
}
class ModelSelectableImpl : ISelectable
{
private Model target;
private bool _isSelected;
public ModelSelectableImpl(Model model)
{
target = model;
}
public void SetIsSelected(bool isSelected)
{
_isSelected = isSelected;
}
public void UpdateColour(Color color)
{
// GRRRRR I don't want this to have to be here, can probably do something like:
target.UpdateColour(color);
// But it just seems messy having it in this class
}
}
所以你可以看到烦恼的地方了,我有一个ModelSelectableImpl,现在有一个UpdateColour的实现,它把它传回模型,再传给ModelColourableImpl,这看起来就有点乱了。
你可以稍微改变一下实现方式,这样 Model
有一个单独的字段,负责 ISelectable
和 IColorable
因为前者无论如何都要实现后者),然后在 该 类的实现,它可以有一个字段,负责对 IColorable
的实现(如果你还想把它分解成另一个类的话)。
比如说
// This hasn't changed from your example
class ModelColourableImpl : IColourable
{
private IColourable _target;
public ModelColourableImpl(IColourable colourable)
{
_target = colourable;
}
public void UpdateColour(Color color)
{
// Update targets colour
}
}
// But now *this* class contains the ModelColourableImpl field
class ModelSelectableImpl : ISelectable
{
private IColourable _colorableImpl;
private ISelectable _target;
private bool _isSelected;
public ModelSelectableImpl(ISelectable model)
{
_target = model;
_colorableImpl = new ModelColourableImpl(model);
}
public void SetIsSelected(bool isSelected)
{
_isSelected = isSelected;
}
public void UpdateColour(Color color)
{
_colorableImpl.UpdateColour(color);
}
}
// And now our model just has one field responsible for the ISelectable implementation:
class Model : ISelectable
{
private ISelectable _selectableImpl;
public Model()
{
_selectableImpl = new ModelSelectableImpl(this);
}
public void SetIsSelected(bool isSelected)
{
_selectableImpl.SetIsSelected(isSelected);
}
public void UpdateColour(Color color)
{
_selectableImpl.UpdateColour(color);
}
}