单一职责原则和代码可读性

single responsibility principle and code readability

在尝试坚持单一职责规则时,我的 classes 开始看起来像这样

$productImage = new ProductImage(// holds all rules for product image only
                    new ImageFile( // makes sure given file is an image file
                        new ReadableFile( // checks given item is a readable file / permissions check
                            new UploadedFile( // validates given file is uploaded file
                                new FilePath( // validates given string is a valid file path
                                    new Path( // validates for string to be a path
                                        new NonEmptyString( // given string is not empty
                                            '/tmp/xyzk7kjnbrukhg'
                                        )
                                    )
                                )
                            )
                        )
                    )
                );

这只是一个示例。 从表面上看,这一切看起来都很酷,因为它提供了非常简单且可测试的 classes。但是您会注意到代码的可读性或可用性很差。连一个上传文件的简单初始化都需要写无数行代码(如上代码所示)

我开始觉得不对劲,我误解了单一职责原则的概念。

它是如何处理对每个 class 具有单一责任的纯 OOP 还是我离题太远了?

您完全偏离了 SRP (Single Responsibility Principle)。 SRP 的工作原理在您的代码中完全看不到。没关系,你 类 他们负责不同的工作。可能是或者我猜,它们是通过尊重 SRP 来实现的。除了假设之外,SRP 的可见性在您的代码中要少得多。

OOP中,类依赖其他类。这是完全正常的。 Dependency Injection 在您的代码中完全可见。但是您不能像构建复杂结构时那样通过构造函数方法维护 Dependency Injection 。那应该是以下几种方式:

<?php

// given string is not empty
$nonEmptyString = new NonEmptyString('/tmp/xyzk7kjnbrukhg');

// validates for string to be a path
$path = new Path($nonEmptyString);

// validates given string is a valid file path
$filePath = new FilePath($path);

// validates given file is uploaded file
$uploadedFile = new UploadedFile($filePath);

// checks given item is a readable file / permissions check
$readableFile = new ReadableFile($uploadedFile);

// makes sure given file is an image file
$imageFile = new ImageFile($readableFile);

// holds all rules for product image only
$productImage = new ProductImage($imageFile);

但这也不是正确的做法。要以正确的方式执行此操作,您需要使用 Factory Method Design PatternFactory Method Design Pattern 实际上创建了其他对象。假设您有一个工厂方法模式实现,它将负责创建 ImageFile 对象,因为 ProductImage 具有 ImageFile 的依赖项。假设您在以下代码片段中导入了所需的所有 类:

<?php

class ImageFileFactory implements FactoryInterface
{
    public static function make($string)
    {
        // given string is not empty
        $nonEmptyString = new NonEmptyString($string);

        // validates for string to be a path
        $path = new Path($nonEmptyString);

        // validates given string is a valid file path
        $filePath = new FilePath($path);

        // validates given file is uploaded file
        $uploadedFile = new UploadedFile($filePath);

        // checks given item is a readable file / permissions check
        $readableFile = new ReadableFile($uploadedFile);

        // makes sure given file is an image file
        return new ImageFile($readableFile);
    }
}


// Creates ImageFile instance
$imageFile = ImageFileFactory::make('/tmp/xyzk7kjnbrukhg');

// holds all rules for product image only
$productImage = new ProductImage($imageFile); 

哦!我在 SRP 上写了一篇关于媒体的文章。如果你可以阅读它。这是 SRP

的 link

希望对您有所帮助!编码愉快!