【问题标题】:How to handle with difference in inherited classes?如何处理继承类的差异?
【发布时间】:2012-04-12 21:40:02
【问题描述】:

我必须执行一些操作。它们中的每一个都有一些共同的元素,因此它们应该从一个类继承。可以说,他们正在做一些网络操作,所以基类是

public class WebAction
{
    private ServerData _serverData;
    public WebAction(ServerData serverData)
    {
        _serverData = serverData;
    }
}

此外,每个动作都需要执行,所以在基类中我也应该有某种Execute() 方法。问题是,这个对象中的每一个都做了一些不同的事情,所以它应该采用不同的参数。我的问题是 - 女巫方式最适合达到这个目标?

起初我在想一些配置对象,例如Execute(IWebActionConfig config)。在这种情况下,我可以使用如下对象:

 LoginWebAction loginWebAction = LoginWebAction(staticServerConfig);
 LoginWebActionConfig = new LoginWebActionConfig { someData = "foo" };
 loginWebAction.Execute(loginWebActionConfig);

但是创建一个额外的对象树有什么意义吗?通过属性配置 WebAction 的每个子项可能会更好?

LoginWebAction loginWebAction = LoginWebAction(staticServerConfig);
loginWebAction.someData = "foo";
// Execute will throw exception when someData not set
loginWebAction.Execute();

用这些(如果有的话)方法更好吗?

【问题讨论】:

    标签: .net design-patterns inheritance


    【解决方案1】:

    我想你可以在这里使用Command Pattern。 您可以创建不同的命令(每个网络操作一个命令)来封装您的“操作”,并且每个命令都将具有所需的所有参数。

    命令处理程序将包含执行该命令的“逻辑”。

    有关命令模式的更多信息:

    http://www.codeguru.com/csharp/.net/net_general/patterns/article.php/c15663/Implement-a-Command-Pattern-Using-C.htm

    http://danielshitrit.blogspot.co.uk/2011/11/best-practices-command-pattern-in-c.html

    【讨论】:

      【解决方案2】:

      由于每个动作都采用不同的参数,因此您实际上无法使用多态性来调用它们。换句话说,在你的类上调用 Execute 的方法必须知道它要在其上调用 Execute 的类的确切类型。

      所以,我会质疑在这里使用继承是否真的是正确的解决方案。

      您声明您使用继承是因为每个类都有一些共享代码。这通常不是使用继承的充分理由。我认为它是一种反模式。

      使用继承的问题在于您将基类与派生类紧密耦合。这可能会导致单元测试和未来维护出现问题。

      我建议值得创建一个包含共享功能的单独类。然后包含此类作为成员的 Action 类并根据需要调用。这将允许您模拟这个基类以进行测试。然后这些类中的每一个都可以有自己的 Execute 方法,每个方法都带有所需的参数。

      【讨论】:

        【解决方案3】:

        可以采用更多的 OOP 风格。 look at NVI pattern

        public class WebAction
        {
          private ServerData _serverData;
          public WebAction(ServerData serverData)
          {
            _serverData = serverData;
          }
          public virtual ExecuteAction{};
          public Execute()
          {
             ExecuteAction();
             //to do the rest of base code 
        
          }
        }
        public class WebActionDerived1: WebAction
        {
           WebActionDerived1(ServerData serverData, object arg1/*any unique param*/)
           :base(serverData)
           {
              _my_arg1 = arg1;
           }
           public override ExecuteAction
           {
            //call any procedure with your _my_arg1;
           }
        }
        public class WebActionDerived2: WebAction
        {
           WebActionDerived1(ServerData serverData, string arg1,
           string arg2/*otherunique param*/)
           :base(serverData)
           {
              _my_arg1 = arg1;
              _my_arg2 = arg2;
           }
           public override ExecuteAction
           {
            //call any procedure with your _my_arg1, and _my_arg2;
           }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-06
          • 1970-01-01
          相关资源
          最近更新 更多