принцип единой ответственности и читаемость кода
Пытаясь придерживаться правила единой ответственности, мои классы начали выглядеть так:
$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
Надеюсь, это поможет вам! Удачного кодирования!