在现代 Web 应用程序开发中,高效、安全地管理和传输数据至关重要。对此过程有显着帮助的一种设计模式是数据传输对象 (DTO)。这篇文章将深入探讨使用 DTO 的优势,特别是在 Laravel 应用程序中,并展示 PHP 8.2 只读类如何进一步增强其优势。
数据传输对象(DTO)是一个简单的对象,旨在在进程或系统之间传输数据。与典型的模型或实体不同,DTO 不受业务逻辑的影响。它们封装数据,提供一种清晰且结构化的方式在应用程序的不同层或不同系统之间传输信息。
DTO 模式用于在软件应用程序内的不同子系统之间传输数据。使用 DTO 的主要目标是最大限度地减少方法调用的数量、聚合必要的数据并提供结构化方法来管理数据转换和验证。
关注点分离: DTO 将业务逻辑与数据表示隔离,从而生成更清晰、更易于维护、更易于理解的代码。
数据验证:DTO 允许在其他应用程序层处理数据之前对数据进行验证,确保仅使用有效数据。
一致性:通过提供一致的数据传输结构,DTO 简化了来自各种来源的数据的管理和处理。
安全性:DTO 可以通过控制哪些数据可访问和可修改来保护您的应用程序免受未经授权的数据操纵。
测试:由于 DTO 是没有嵌入业务逻辑的简单对象,因此它们更容易模拟和测试。
转换:DTO 有助于将数据转换为不同应用层所需的格式。
不变性: DTO 通常会促进不变性,这意味着一旦创建,它们的状态就无法更改。此功能带来了几个优点:
在 PHP 8.2 中,只读类的引入增强了 DTO 的使用。只读类无需将属性显式定义为只读,从而简化了 DTO 实现。以下是 PHP 8.2 的只读类如何改进 DTO:
让我们考虑一个属性管理系统,其中属性可以来自各种来源,例如 API 和 CSV 导入。我们可以使用 DTO 创建属性模型、订阅、资产等,确保数据在整个应用程序中保持一致并经过验证。
首先,我们定义一个PropertyDTO类:
app/DTO/PropertyDTO.php
namespace App\DTO; /** * Class PropertyDTO * * Represents a Data Transfer Object for property data. */ readonly class PropertyDTO extends AbstractDTO { /** * The name of the property. * * @var string */ public string $name; /** * The address of the property. * * @var string */ public string $address; /** * The price of the property. * * @var float */ public float $price; /** * The subscription status of the property, if applicable. * * @var string|null */ public ?string $subscription; /** * The list of assets associated with the property. * * @var array|null */ public ?array $assets; /** * Set the properties from a model instance. * * @param $model The model instance. * @return $this */ public function setFromModel($model): self { $this->name = $model->name; $this->address = $model->address; $this->price = $model->price; $this->subscription = $model->subscription; $this->assets = $model->assets; return $this; } /** * Set the properties from API data. * * @param array $data The API data. * @return $this */ public function setFromAPI(array $data): self { $this->name = $data['property_name']; $this->address = $data['property_address']; $this->price = $data['property_price']; $this->subscription = $data['subscription'] ?? null; $this->assets = $data['assets'] ?? null; return $this; } /** * Set the properties from CSV data. * * @param array $data The CSV data. * @return $this */ public function setFromCSV(array $data): self { $this->name = $data[0]; $this->address = $data[1]; $this->price = (float) $data[2]; $this->subscription = $data[3] ?? null; $this->assets = explode(',', $data[4] ?? ''); return $this; } }
以下是如何使用 PropertyDTO 处理来自不同来源的属性:
// From a Model $model = Property::find(1); $propertyDTO = (new PropertyDTO([]))->setFromModel($model); // From an API $apiData = [ 'property_name' => 'Beautiful House', 'property_address' => '1234 Elm Street', 'property_price' => 450000, 'subscription' => 'Premium', 'assets' => ['pool', 'garden'] ]; $propertyDTO = (new PropertyDTO([]))->setFromAPI($apiData); // From a CSV $csvData = ['Beautiful House', '1234 Elm Street', 450000, 'Premium', 'pool,garden']; $propertyDTO = (new PropertyDTO([]))->setFromCSV($csvData); // Convert to Array $arrayData = $propertyDTO->toArray(); // Convert to JSON $jsonData = $propertyDTO->toJson();
数据传输对象 (DTO) 通过确保数据一致性、验证和关注点分离,在 Laravel 应用程序中提供了众多优势。通过实施 DTO,您可以使应用程序更易于维护、更安全且更易于测试。在物业管理系统中,DTO 有助于高效处理来自各种来源(例如 API 和 CSV 导入)的数据,确保您的业务逻辑保持干净并专注于处理经过验证的数据。
Moreover, embracing immutability within DTOs enhances predictability, thread-safety, and simplifies debugging.
To streamline the creation of DTOs and promote code reuse, we can use an abstract class or base class. This approach allows us to define common methods and properties in the abstract class and extend it for specific data sources.
app/DTO/AbstractDTO.php
namespace App\DTO; /** * AbstractDTO * * An abstract base class for Data Transfer Objects (DTOs). * Provides common methods and properties for DTO implementations. */ abstract class AbstractDTO { /** * AbstractDTO constructor. * * Initialises the DTO with data from an associative array. * * @param array $data The data array to initialize the DTO. */ public function __construct(array $data) { $this->setFromArray($data); } /** * Set the properties of the DTO from a model instance. * * @param $model The model instance from which to populate the DTO. * @return $this */ abstract public function setFromModel($model): self; /** * Set the properties of the DTO from API data. * * @param array $data The data array from the API. * @return $this */ abstract public function setFromAPI(array $data): self; /** * Set the properties of the DTO from CSV data. * * @param array $data The data array from the CSV. * @return $this */ abstract public function setFromCSV(array $data): self; /** * Convert the DTO to an associative array. * * @return array The DTO data as an associative array. */ public function toArray(): array { $properties = get_object_vars($this); return array_filter($properties, function ($property) { return $property !== null; }); } /** * Convert the DTO to a JSON string. * * @return string The DTO data as a JSON string. */ public function toJson(): string { return json_encode($this->toArray()); } /** * Set the properties of the DTO from an associative array. * * @param array $data The data array to populate the DTO. */ protected function setFromArray(array $data): void { foreach ($data as $key => $value) { if (property_exists($this, $key)) { $this->$key = $value; } } } }
Using an abstract or base class for DTOs not only ensures consistency across different DTO implementations but also promotes code reuse and maintainability. By defining common methods and properties in an abstract class, you can create a structured and efficient way to manage data transfer within your application. This approach aligns well with the principles of clean code and helps in building scalable and robust applications.
Here’s a revised phrase that includes a call to action:
"By leveraging DTOs and abstract classes together, you can refine your Laravel application's design, improving how data is managed and ensuring a more organised and efficient data flow. If you want to further encapsulate and enhance your DTOs with traits and interfaces, explore our guide on Enhancing Object-Oriented Design with Traits, Interfaces, and Abstract Classes."
以上是探索数据传输对象 (DTO) 的优势以及 PHP 只读类如何提升您的 Laravel 代码的详细内容。更多信息请关注PHP中文网其他相关文章!