Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 这个简单的建模示例是否违反了SOLID原则以及如何对其进行单元测试_Oop_Unit Testing_Modeling_Solid Principles - Fatal编程技术网

Oop 这个简单的建模示例是否违反了SOLID原则以及如何对其进行单元测试

Oop 这个简单的建模示例是否违反了SOLID原则以及如何对其进行单元测试,oop,unit-testing,modeling,solid-principles,Oop,Unit Testing,Modeling,Solid Principles,我试图实现一个简单的验证器类系统,它尊重坚实的原则,并用于单元测试目的 假设我有一些简单的验证器(强制、整数、大于…),现在我想实现一个更复杂的验证器,它调用几个简单的验证器(使用一些验证器的示例表单验证器) 这非常受Zend和其他框架的启发 问题是,在这里如何应用或违反坚实的原则,以及应该如何对此模型进行单元测试 我想我可以轻松地对每个简单的验证器进行单元测试,但不能对复杂的FormValidator进行单元测试 interface ICheckable { public functi

我试图实现一个简单的验证器类系统,它尊重坚实的原则,并用于单元测试目的

假设我有一些简单的验证器(强制、整数、大于…),现在我想实现一个更复杂的验证器,它调用几个简单的验证器(使用一些验证器的示例表单验证器)

这非常受Zend和其他框架的启发

问题是,在这里如何应用或违反坚实的原则,以及应该如何对此模型进行单元测试

我想我可以轻松地对每个简单的验证器进行单元测试,但不能对复杂的FormValidator进行单元测试

interface ICheckable
{
    public function check($data);
}

class MandatoryValidator implements ICheckable
{
    private $_property;
    
    public function __construct($property)
    {
        $this->_property = $property;
    }
    
    public function check($data)
    {
        return isset($data[$property]);
    }
}

class IntegerValidator implements ICheckable
{
    ...
}

class FormValidator implements ICheckable
{
    public function check($data)
    {
        $mandatoryValidator = new MandatoryValidator(array('LOGIN'));
        
        if ($mandatoryValidator->check($data) == false)
        {           
            return false;
        }
        
        $integerValidator = new IntegerValidator();
        
        if ($integerValidator->check($data['AMOUNT']) == false)
        {           
            return false;
        }
        
        ...
        return true;
    }
}

首先,很好地使用了ICheckable接口。这是一个好的开始

让我们来解决美国的单一责任原则:

这就是“一个类应该只有一个改变的理由”的原则 所有班级都尊重美国学生吗? (简单的责任。)

当前的两个验证器都尊重这一点

FormValidator是否只有一个职责?我可以看到它有三种功能:

  • 创建验证程序
  • 调用2个验证器
  • 检查验证器结果
  • 这种设计的问题是,每次你有一个新的验证器,你必须创建它,调用它,并检查它的返回值。这违反了固体原则中的O。(开/关)

    表单验证程序应该收到一个ICheckable的“自定义”列表。这个“自定义”列表也应该是可设置的,所以您可以直接调用它。这个“自定义”列表将遍历它的ICheckable列表。这将是唯一的责任

    然后,必须对结果进行评估。当函数返回值时,必须对其进行处理。一般来说,这意味着更多的代码,一个额外的IF语句。这两个人应该给你一个提示:责任太大了

    因此,为了使其可靠,您应该向验证器传递一个回调接口,该接口将用于处理验证器输出。您的示例非常简单,验证器返回true或false。它可以由两个“输出”方法表示-Validated()或ValidationFailed()。O_O,这看起来像是一个非常好的验证程序“输出”接口,可以由FormValidator实现。这种设计将符合原则的S.O.L.I.D

    请记住,当您第一次创建FormValidator时,您必须创建两个验证器、自定义列表并将所有内容连接在一起

    然后您就可以非常快速地对所有非常简单的类进行单元测试。(尝试先开始编写测试)

    注意:一般来说,如果你处理好了S,其他原则都很容易实现


    希望这有帮助。如果您需要更多信息,请告诉我。

    您应该认真研究命名。ICheckable应该像IValidator一样重命名为smth(“因为它实际上就是这么做的”),并且“check”方法应该是“isValid”。当前的名称令人困惑,所以请帮你自己一个忙,始终在返回bool的方法前面加上前缀“is”或smth,可以流利地将其放入if中。回答得好。我要补充的是,任何时候一个方法创建一个对象,然后在其上执行一个方法,它都会违反SRP(和DI)。当很难测试时,就会感觉到这些症状,因为您无法用模拟或伪组件替换创建的依赖组件。我理解,但是如果方法中的任何实例化违反SRP+DI,您将在何时(或何地)实例化任何对象?建议创建要传递到表单的ICheckable元素列表是一个好主意,但是当您必须实例化此对象列表时,实例化将在另一个方法中完成。实例必须在不同的级别上进行。我通常以一个名为“BuildApplication”的类结束,该类创建并链接我的对象。这个“BuildThing”必须在应用程序启动时调用。如果需要在运行时进行实例化,请查看FACTORY模式。