【问题标题】:Best practices for delegating the implementation of interfaces to other objects - with interfaces which implement other interfaces将接口的实现委托给其他对象的最佳实践 - 使用实现其他接口的接口
【发布时间】:2020-05-22 15:35:29
【问题描述】:

我不停地为此挠头,试图找出最好的前进方式。假设我有一个可选择的模型类,所有可选择的对象都可以更改它们的颜色以显示它们已被选中。 我想将功能放入单独的接口中,因为有些东西可以改变不一定可选择的颜色,但是,可选择的所有内容都需要是 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


    【解决方案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);
        }
    }
    

    【讨论】:

    • 这似乎是一个合理的前进方向,尽管现在这似乎我有两个 UpdateColour 方法的实现......除非我从原始模型中获取 IColourable 实现?
    • 唯一真正的“实现”在ModelColourableImpl 类中。其他类最终只是从这个实现返回值。
    猜你喜欢
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 2011-03-29
    • 2019-04-08
    相关资源
    最近更新 更多