组合优于继承 - 如何使组件可扩展?

Posted

技术标签:

【中文标题】组合优于继承 - 如何使组件可扩展?【英文标题】:Composition over inheritance - How to make components extensible? 【发布时间】:2018-10-15 23:28:22 【问题描述】:

由于我的代码被多重/菱形继承问题所困扰,我一直在尝试学习并切换到更多的组合模式。

尽管我尽了最大努力,但我并没有真正“明白”,因为它与我的代码有关。我没有将所有东西都放在基类中,而是一直在尝试考虑可以拆分为其他组件的行为。

问题是我不知道如何使类或组件可扩展。

这是我的代码示例...

public class SelectList : BaseControl

    private ISelectListActions SelectActions  get; 

    public string Text 
        get  return SelectActions.Text; 
    

    public SelectList(IWebDriver driver, By locator, ISelectListActions selectActions) : base(driver, locator)
    
        SelectActions = selectActions;
    

    public void SelectByText(string text)
    
        SelectActions.SelectByText(text);
    

SelectActions 被设计为代表所有行为的组件(在本示例中所有行为都组合在一起)。

假设我想通过添加一个名为CheckText 的新方法来扩展SelectList 类的功能。

传统的继承解决方案看起来像这样......

public class BetterSelectList : SelectList

    public BetterSelectList(IWebDriver driver, By locator, ISelectListActions selectActions) : base(driver, locator, selectActions)  

    public void CheckText()
    
        Console.WriteLine("CheckText");
    

但是如果我最终需要再做 5 次怎么办 - 我将再次陷入继承兔子洞。

我不知道作文解决方案:

如果我将新的CheckText 方法添加到ISelectListActions 并提供具体实现,如果我想从SelectList 的实例中使用它,我需要在SelectList 中公开它。然后SelectList 的每个实例都会公开我可能不一定想要的方法。

我想错了吗?

【问题讨论】:

对于您给出的示例,扩展方法可以很好地工作。如果您需要在扩展中获得更复杂的功能,装饰器模式可能会帮助您en.wikipedia.org/wiki/Decorator_pattern 【参考方案1】:

我认为你想做这样的事情,但不确定这是否有帮助

abstract class Action
    
        public void Perform(SelectList list)
        
          Console.WriteLine("CheckText");
        
    

class CheckBoxAction1:Action

    public void Perform(SelectList list)
    
      Console.WriteLine("CheckText1");
    


class CheckBoxAction2:Action

    public void Perform(SelectList list)
    
      Console.WriteLine("CheckText2");
    

class ComposedActions
    private Action _action;
    public ComposedActions(Action action)
     
      _action=action;
    
    public void Perform(SelectList list)
    
      _action.Perform(list);
    
 
ComposedActions action1= new ComposedActions(new CheckBoxAction1());
ComposedActions action2= new ComposedActions(new CheckBoxAction2());
SelectList list = new SelectList();
action1.Perform(list);
//CheckText1
action2.Perform(list);
//CheckText2

【讨论】:

以上是关于组合优于继承 - 如何使组件可扩展?的主要内容,如果未能解决你的问题,请参考以下文章

在设计原则中,为什么反复强调组合要优于继承?

在 React 类组件中同时使用继承和组合是一种好的做法吗?

如何使可扩展列表视图的项目选中/不可选中

如何使 RabbitMQ 可扩展?

如何使扩展非可序列化的java类可序列化

如何通过拖动扩展的窗口框架使 WPF 窗口可移动?