принцип единой ответственности и читаемость кода

Пытаясь придерживаться правила единой ответственности, мои классы начали выглядеть так:

$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'
                                        )
                                    )
                                )
                            )
                        )
                    )
                );

Это всего лишь один образец. На первый взгляд все это выглядит круто, поскольку предоставляет очень простые и проверяемые классы. но, как вы можете заметить, читабельность или удобство использования кода - отстой. Мне нужно написать бесчисленное количество строк кода даже для простой инициализации загруженного файла (как показано в приведенном выше коде).

Я начал чувствовать, что что-то не так, и я неправильно понял концепцию принципа единственной ответственности.

Это то, как обрабатывается чистое ООП с единственной ответственностью за каждый класс, или я ошибаюсь?

1 ответ

Решение

Вы совсем далеко от 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 Pattern. Factory 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

Надеюсь, это поможет вам! Удачного кодирования!

Другие вопросы по тегам