Created
May 28, 2022 09:30
-
-
Save nbish11/64db626bc60a12905fec9dbd1edcab31 to your computer and use it in GitHub Desktop.
Removing reliance on nulls in PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| declare(strict_types=1); | |
| // IMPLEMENTATION using DDD... | |
| final class ItemIdentity | |
| { | |
| public function __construct(public readonly int $number) {} | |
| public function equals(self $other): bool | |
| { | |
| return $this->number === $other->number; | |
| } | |
| } | |
| final class ItemDescription | |
| { | |
| public function __construct(public readonly string $value) {} | |
| } | |
| final class Item | |
| { | |
| public readonly ItemDescription $description; | |
| public function __construct(public readonly ItemIdentity $identity) | |
| { | |
| $this->describe(''); | |
| } | |
| public function identify(): int | |
| { | |
| return $this->identity->number; | |
| } | |
| public function describe(string $description): void | |
| { | |
| $this->description = new ItemDescription($description); | |
| } | |
| public function equals(self $other): bool | |
| { | |
| return $this === $other; | |
| } | |
| } | |
| interface ItemRepository | |
| { | |
| public function get(ItemIdentity $id): Item; | |
| public function add(Item $item): void; | |
| public function remove(Item $item): void; | |
| } | |
| final class InMemoryItemRepository | |
| { | |
| private static $stored = []; | |
| private static $id = 0; | |
| public static function withDefaultItems() | |
| { | |
| $items = new self(); | |
| $itemsToMake = [ | |
| $items->nextAvailableIdentity() => 'One', | |
| $items->nextAvailableIdentity() => 'Second Item', | |
| $items->nextAvailableIdentity() => 'Third Item' | |
| ]; | |
| foreach ($itemsToMake as $id => $description) { | |
| $itemToAdd = new Item($id); | |
| $itemToAdd->describe($description); | |
| $items->add($itemToAdd); | |
| } | |
| return $items; | |
| } | |
| // note this function will ALWAYS return a product | |
| public function get(ItemIdentity $id): Item | |
| { | |
| // if product exists... return it | |
| foreach (self::$stored as $item) { | |
| if ($item->identity->equals($id)) { | |
| return $item; | |
| } | |
| } | |
| // if it doesn't exist... return an empty one with id set | |
| return new Item($this->nextAvailableIdentity()); | |
| } | |
| public function add(Item $item): void | |
| { | |
| if (!this->exists($item)) { | |
| self::$stored[] = $item; | |
| } | |
| } | |
| public function remove(Item $item): void | |
| { | |
| if (($index = $this->indexOf($item)) !== -1) { | |
| unset(self::$stored[$index]); | |
| } | |
| } | |
| public function exists(Item $item): bool | |
| { | |
| foreach (self::$stored as $storedItem) { | |
| if ($storedItem->equals($item)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| private function indexOf(Item $item): int | |
| { | |
| foreach (self::$stored as $index => $storedItem) { | |
| if ($storedItem->equals($item)) { | |
| return $index; | |
| } | |
| } | |
| return -1; | |
| } | |
| public function nextAvailableIdentity(): ProductIdentity | |
| { | |
| return new ItemIdentity(self::$id++); | |
| } | |
| } | |
| // USAGE: | |
| $items = InMemoryItemRepository::withDefaultItems(); | |
| // essentially an "update" query | |
| $itemThatDoesExist = $items->get(new ItemIdentity(0)); | |
| $itemThatDoesExist->describe('First Item'); | |
| $items->add($itemThatDoesExist); | |
| // essentially a "create" query | |
| $itemThatDoesNotExist = $items->get(new ItemIdentity(3)); | |
| $itemThatDoesNotExist->describe('Fourth Item'); | |
| $items->add($itemThatDoesNotExist); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment