将接口的实现委托给其他对象的最佳实践--用接口实现其他接口。

问题描述 投票:0回答:2

我一直在为这个问题挠头,想找出最好的办法。比方说我有一个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,这看起来就有点乱了。

c# design-patterns code-cleanup
2个回答
1
投票

你可以稍微改变一下实现方式,这样 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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.