单一职责原则和代码可读性
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 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
的 link
希望对您有所帮助!编码愉快!
在尝试坚持单一职责规则时,我的 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 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
希望对您有所帮助!编码愉快!