我必须实施一些行动。每个都有一些共同的元素,所以它们应该从一个类继承。可以说,他们做了一些网络动作,所以基类是
public class WebAction
{
private ServerData _serverData;
public WebAction(ServerData serverData)
{
_serverData = serverData;
}
}
此外,每个动作都需要执行,因此在基类I中也应该有某种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();
这些(如果有的话)方式更好吗?
答案 0 :(得分:1)
我想你可以在这里使用Command Pattern
。
您可以创建封装“Action”的不同命令(每个Web操作一个命令),每个命令都将包含所需的所有参数。
命令处理程序将包含用于执行该命令的“逻辑”。
有关命令模式的更多信息:
http://danielshitrit.blogspot.co.uk/2011/11/best-practices-command-pattern-in-c.html
答案 1 :(得分:1)
由于每个操作采用不同的参数,因此您无法使用多态来调用它们。换句话说,在类上调用Execute的方法必须知道它将调用Execute的类的确切类型。
所以,我会怀疑在这里使用继承是否真的是正确的解决方案。
您声明您正在使用继承,因为每个类都有一些共享代码。这通常不是使用继承的充分理由。我认为它是一种反模式。
使用继承的问题在于您将基类与派生类紧密耦合。这可能会导致单元测试和将来的维护出现问题。
我建议值得创建一个包含共享功能的单独类。然后你的Action类包含这个类作为成员并根据需要调用。这将允许您模拟此基类以进行测试。然后,每个类都可以拥有自己的Execute方法,每个方法都带有所需的参数。
答案 2 :(得分:0)
可以采用更多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;
}
}