100 lines
No EOL
9.2 KiB
JSON
100 lines
No EOL
9.2 KiB
JSON
{
|
|
"uuid": [
|
|
{
|
|
"value": "08a03029-d231-45f2-91b3-0a4611156b0c"
|
|
}
|
|
],
|
|
"langcode": [
|
|
{
|
|
"value": "en"
|
|
}
|
|
],
|
|
"type": [
|
|
{
|
|
"target_id": "daily_email",
|
|
"target_type": "node_type",
|
|
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
|
}
|
|
],
|
|
"revision_timestamp": [
|
|
{
|
|
"value": "2025-04-16T14:13:06+00:00"
|
|
}
|
|
],
|
|
"revision_uid": [
|
|
{
|
|
"target_type": "user",
|
|
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
|
}
|
|
],
|
|
"revision_log": [],
|
|
"status": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"uid": [
|
|
{
|
|
"target_type": "user",
|
|
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
|
}
|
|
],
|
|
"title": [
|
|
{
|
|
"value": "Refactoring to value objects"
|
|
}
|
|
],
|
|
"created": [
|
|
{
|
|
"value": "2022-10-03T00:00:00+00:00"
|
|
}
|
|
],
|
|
"changed": [
|
|
{
|
|
"value": "2025-04-16T14:13:06+00:00"
|
|
}
|
|
],
|
|
"promote": [
|
|
{
|
|
"value": false
|
|
}
|
|
],
|
|
"sticky": [
|
|
{
|
|
"value": false
|
|
}
|
|
],
|
|
"default_langcode": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"revision_translation_affected": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"path": [
|
|
{
|
|
"alias": "\/daily\/2022\/10\/03\/refactoring-value-objects",
|
|
"langcode": "en"
|
|
}
|
|
],
|
|
"body": [
|
|
{
|
|
"value": "\n <p>Here's a snippet of some Drupal code that I wrote last week. It's responsible for converting an array of nodes into a Collection of one of it's field values.<\/p>\n\n<pre><code class=\"language-php\">return Collection::make($stationNodes)\n ->map(fn (NodeInterface $station): string => $station->get('field_station_code')->getString())\n ->values();\n<\/code><\/pre>\n\n<p>There are two issues with this code.<\/p>\n\n<p>First, whilst I'm implicitly saying that it accepts a certain type of node, because of the <code>NodeInterface<\/code> typehint this could accept any type of node. If that node doesn't have the required field, the code will error - but I'd like to know sooner if an incorrect type of node is passed and make it explicit that only a certain type of node can be used.<\/p>\n\n<p>Second, the code for getting the field values is quite verbose and is potentially repeated in other places within the codebase. I'd like to have a simple way to access these field values that I can reuse anywhere else. If the logic for getting these particular field values changes, then I'd only need to change it in one place.<\/p>\n\n<h2 id=\"introducing-a-value-object\">Introducing a value object<\/h2>\n\n<p>This is the value object that I created.<\/p>\n\n<p>It accepts the original node but checks to ensure that the node is the correct type. If not, an Exception is thrown.<\/p>\n\n<p>I've added a helper method to get the field value, encapsulating that logic in a reusable function whilst making the code easier to read and its intent clearer.<\/p>\n\n<pre><code class=\"language-php\">namespace Drupal\\mymodule\\ValueObject;\n\nuse Drupal\\node\\NodeInterface;\n\nfinal class Station implements StationInterface {\n\n private NodeInterface $node;\n\n private function __construct(NodeInterface $node) {\n if ($node->bundle() != 'station') {\n throw new \\InvalidArgumentException();\n }\n\n $this->node = $node;\n }\n\n public function getStationCode(): string {\n return $this->node->get('field_station_code')->getString();\n }\n\n public static function fromNode(NodeInterface $node): self {\n return new self($node);\n }\n\n}\n<\/code><\/pre>\n\n<h2 id=\"refactoring-to-use-the-value-object\">Refactoring to use the value object<\/h2>\n\n<p>This is what my code now looks like:<\/p>\n\n<pre><code class=\"language-php\">return Collection::make($stationNodes)\n ->map(fn (NodeInterface $node): StationInterface => Station::fromNode($node))\n ->map(fn (StationInterface $station): string => $station->getStationCode())\n ->values();\n<\/code><\/pre>\n\n<h1><<<<<<< HEAD:website\/source\/_daily_emails\/2022-10-03.md<\/h1>\n\n<blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <p>b9cea6d (chore: replace Sculpin with Astro):website\/src\/pages\/daily-emails\/2022-10-03.md\n I've added an additional <code>map<\/code> to convert the nodes to the value object, but the second map can now use the new typehint - ensuring better type safety and also giving us auto-completion in IDEs and text editors. If an incorrect node type is passed in, then the Exception will be thrown and a much clearer error message will be shown.<\/p>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n<\/blockquote>\n\n<p>Finally, I can use the helper method to get the field value, encapsulating the logic within the value object and making it intention clearer and easier to read.<\/p>\n\n ",
|
|
"format": "full_html",
|
|
"processed": "\n <p>Here's a snippet of some Drupal code that I wrote last week. It's responsible for converting an array of nodes into a Collection of one of it's field values.<\/p>\n\n<pre><code class=\"language-php\">return Collection::make($stationNodes)\n ->map(fn (NodeInterface $station): string => $station->get('field_station_code')->getString())\n ->values();\n<\/code><\/pre>\n\n<p>There are two issues with this code.<\/p>\n\n<p>First, whilst I'm implicitly saying that it accepts a certain type of node, because of the <code>NodeInterface<\/code> typehint this could accept any type of node. If that node doesn't have the required field, the code will error - but I'd like to know sooner if an incorrect type of node is passed and make it explicit that only a certain type of node can be used.<\/p>\n\n<p>Second, the code for getting the field values is quite verbose and is potentially repeated in other places within the codebase. I'd like to have a simple way to access these field values that I can reuse anywhere else. If the logic for getting these particular field values changes, then I'd only need to change it in one place.<\/p>\n\n<h2 id=\"introducing-a-value-object\">Introducing a value object<\/h2>\n\n<p>This is the value object that I created.<\/p>\n\n<p>It accepts the original node but checks to ensure that the node is the correct type. If not, an Exception is thrown.<\/p>\n\n<p>I've added a helper method to get the field value, encapsulating that logic in a reusable function whilst making the code easier to read and its intent clearer.<\/p>\n\n<pre><code class=\"language-php\">namespace Drupal\\mymodule\\ValueObject;\n\nuse Drupal\\node\\NodeInterface;\n\nfinal class Station implements StationInterface {\n\n private NodeInterface $node;\n\n private function __construct(NodeInterface $node) {\n if ($node->bundle() != 'station') {\n throw new \\InvalidArgumentException();\n }\n\n $this->node = $node;\n }\n\n public function getStationCode(): string {\n return $this->node->get('field_station_code')->getString();\n }\n\n public static function fromNode(NodeInterface $node): self {\n return new self($node);\n }\n\n}\n<\/code><\/pre>\n\n<h2 id=\"refactoring-to-use-the-value-object\">Refactoring to use the value object<\/h2>\n\n<p>This is what my code now looks like:<\/p>\n\n<pre><code class=\"language-php\">return Collection::make($stationNodes)\n ->map(fn (NodeInterface $node): StationInterface => Station::fromNode($node))\n ->map(fn (StationInterface $station): string => $station->getStationCode())\n ->values();\n<\/code><\/pre>\n\n<h1><<<<<<< HEAD:website\/source\/_daily_emails\/2022-10-03.md<\/h1>\n\n<blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <blockquote>\n <p>b9cea6d (chore: replace Sculpin with Astro):website\/src\/pages\/daily-emails\/2022-10-03.md\n I've added an additional <code>map<\/code> to convert the nodes to the value object, but the second map can now use the new typehint - ensuring better type safety and also giving us auto-completion in IDEs and text editors. If an incorrect node type is passed in, then the Exception will be thrown and a much clearer error message will be shown.<\/p>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n <\/blockquote>\n<\/blockquote>\n\n<p>Finally, I can use the helper method to get the field value, encapsulating the logic within the value object and making it intention clearer and easier to read.<\/p>\n\n ",
|
|
"summary": null
|
|
}
|
|
],
|
|
"feeds_item": [
|
|
{
|
|
"imported": "2025-04-16T14:13:06+00:00",
|
|
"guid": null,
|
|
"hash": "7ee7cb63765e8fc082bb197e047a1b09",
|
|
"target_type": "feeds_feed",
|
|
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
|
}
|
|
]
|
|
} |