通过构造函数或方法添加参数

adding argument via constructor or method

提问人:Ali Faris 提问时间:5/27/2021 更新时间:5/27/2021 访问量:39

问:

我有这些验证器类

interface Validator {
     bool Validate(string value,object options)
}

class NumberValidator extends Validator {}
class EmailValidator extends Validator {}
class RangeValidator extends Validator {}
...

正如你所看到的,在调用方法时传递了。但我想知道通过构造函数而不是方法传递参数是否更好?(从 CleanCode 的角度来看)。optionsValidateoptionsValidate

因此,接口和我的实现类将如下所示:

interface Validator {
    bool Validate(string value)
}

class SomeValidator extends Validator {
     private object options;
     public SomeValidator(object options) {...}
     public bool Validate(string value) {...}
}

...

我感觉到在构造函数上会更好,但老实说,我没有更好的理由。options

设计模式 与语言无关的 代码清理

评论


答:

1赞 Tony Delroy 5/27/2021 #1

如果客户端代码方便,对于任何特定类,都具有...SomeValidator

  1. 一个实例,其中相同的选项将应用于每个调用,或者Validate
  2. 许多实例使用不同的选项值构造,并且 找到每个验证的使用权,SomeValidator

...那么将选项作为构造函数参数是有意义的。在这些情况下,构造的对象实例实际上成为“”对象 - 在其生命周期内作为特定类型的验证执行。SomeValidatorWithSpecificOptions

另一方面,如果要求同一对象在特定调用期间使用不同的选项更方便/实用,那么将选项作为函数的参数是有意义的。SomeValidatorValidateValidate

还可以采用混合方法,其中构造函数采用默认选项值,并且调用可以覆盖或不覆盖选项。Validate

什么是最好的完全取决于客户端代码的需求。

2赞 Mark Seemann 5/27/2021 #2

如果您所说的 CleanCode 指的是 Robert C. Martin 的 œuvre,您可能还需要考虑 SOLID 原则。在这里,依赖倒置原则似乎特别重要。

正如 Martin 在 APPP 中所说,

客户端 [...] 拥有抽象接口

这意味着从客户端代码的角度设计接口,而不是基于实现代码。

是否要求客户端可以在运行时传递参数?如果是这样,请将其包含在接口定义中。options

如果客户端在运行时不关心,那么它不应该是接口的一部分。然后,通过消除,您必须使其成为构造函数的一部分。options

评论

0赞 Ali Faris 5/27/2021
我正在考虑根据类型创建验证器实例并在构造函数调用时分配选项,因此这些选项将在运行时动态和更改。谢谢你的回答:)ValidatorFactory