introduced PostId and PostStatus and changed naming from Storage to Persistence

This commit is contained in:
Dominik Liebler
2018-06-14 18:28:40 +02:00
parent 2ab82dbfbf
commit 6c726d66b7
18 changed files with 334 additions and 743 deletions

View File

@@ -5,10 +5,15 @@ namespace DesignPatterns\More\Repository\Domain;
class Post class Post
{ {
/** /**
* @var int * @var PostId
*/ */
private $id; private $id;
/**
* @var PostStatus
*/
private $status;
/** /**
* @var string * @var string
*/ */
@@ -19,10 +24,11 @@ class Post
*/ */
private $text; private $text;
public static function draft(int $id, string $title, string $text): Post public static function draft(PostId $id, string $title, string $text): Post
{ {
return new self( return new self(
$id, $id,
PostStatus::fromString(PostStatus::STATE_DRAFT),
$title, $title,
$text $text
); );
@@ -31,29 +37,37 @@ class Post
public static function fromState(array $state): Post public static function fromState(array $state): Post
{ {
return new self( return new self(
$state['id'], PostId::fromInt($state['id']),
PostStatus::fromInt($state['statusId']),
$state['title'], $state['title'],
$state['text'] $state['text']
); );
} }
/** /**
* @param int $id * @param PostId $id
* @param string $text * @param PostStatus $status
* @param string $title * @param string $title
* @param string $text
*/ */
private function __construct(int $id, string $title, string $text) private function __construct(PostId $id, PostStatus $status, string $title, string $text)
{ {
$this->id = $id; $this->id = $id;
$this->status = $status;
$this->text = $text; $this->text = $text;
$this->title = $title; $this->title = $title;
} }
public function getId(): int public function getId(): PostId
{ {
return $this->id; return $this->id;
} }
public function getStatus(): PostStatus
{
return $this->status;
}
public function getText(): string public function getText(): string
{ {
return $this->text; return $this->text;

View File

@@ -0,0 +1,42 @@
<?php
namespace DesignPatterns\More\Repository\Domain;
/**
* This is a perfect example of a value object that is identifiable by it's value alone and
* is guaranteed to be valid each time an instance is created. Another important property of value objects
* is immutability.
*
* Notice also the use of a named constructor (fromInt) which adds a little context when creating an instance.
*/
class PostId
{
/**
* @var int
*/
private $id;
public static function fromInt(int $id)
{
self::ensureIsValid($id);
return new self($id);
}
private function __construct(int $id)
{
$this->id = $id;
}
public function toInt(): int
{
return $this->id;
}
private static function ensureIsValid(int $id)
{
if ($id <= 0) {
throw new \InvalidArgumentException('Invalid PostId given');
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace DesignPatterns\More\Repository\Domain;
/**
* Like PostId, this is a value object which holds the value of the current status of a Post. It can be constructed
* either from a string or int and is able to validate itself. An instance can then be converted back to int or string.
*/
class PostStatus
{
const STATE_DRAFT_ID = 1;
const STATE_PUBLISHED_ID = 2;
const STATE_DRAFT = 'draft';
const STATE_PUBLISHED = 'published';
private static $validStates = [
self::STATE_DRAFT_ID => self::STATE_DRAFT,
self::STATE_PUBLISHED_ID => self::STATE_PUBLISHED,
];
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $name;
public static function fromInt(int $statusId)
{
self::ensureIsValidId($statusId);
return new self($statusId, self::$validStates[$statusId]);
}
public static function fromString(string $status)
{
self::ensureIsValidName($status);
return new self(array_search($status, self::$validStates), $status);
}
private function __construct(int $id, string $name)
{
$this->id = $id;
$this->name = $name;
}
public function toInt(): int
{
return $this->id;
}
/**
* there is a reason that I avoid using __toString() as it operates outside of the stack in PHP
* and is therefor not able to operate well with exceptions
*/
public function toString(): string
{
return $this->name;
}
private static function ensureIsValidId(int $status)
{
if (!in_array($status, array_keys(self::$validStates), true)) {
throw new \InvalidArgumentException('Invalid status id given');
}
}
private static function ensureIsValidName(string $status)
{
if (!in_array($status, self::$validStates, true)) {
throw new \InvalidArgumentException('Invalid status name given');
}
}
}

View File

@@ -2,7 +2,7 @@
namespace DesignPatterns\More\Repository; namespace DesignPatterns\More\Repository;
class MemoryStorage implements Storage class InMemoryPersistence implements Persistence
{ {
/** /**
* @var array * @var array

View File

@@ -2,7 +2,7 @@
namespace DesignPatterns\More\Repository; namespace DesignPatterns\More\Repository;
interface Storage interface Persistence
{ {
public function generateId(): int; public function generateId(): int;

View File

@@ -3,9 +3,10 @@
namespace DesignPatterns\More\Repository; namespace DesignPatterns\More\Repository;
use DesignPatterns\More\Repository\Domain\Post; use DesignPatterns\More\Repository\Domain\Post;
use DesignPatterns\More\Repository\Domain\PostId;
/** /**
* This class is situated between Entity layer (class Post) and access object layer (MemoryStorage). * This class is situated between Entity layer (class Post) and access object layer (Persistence).
* *
* Repository encapsulates the set of objects persisted in a data store and the operations performed over them * Repository encapsulates the set of objects persisted in a data store and the operations performed over them
* providing a more object-oriented view of the persistence layer * providing a more object-oriented view of the persistence layer
@@ -16,26 +17,26 @@ use DesignPatterns\More\Repository\Domain\Post;
class PostRepository class PostRepository
{ {
/** /**
* @var Storage * @var Persistence
*/ */
private $persistence; private $persistence;
public function __construct(Storage $persistence) public function __construct(Persistence $persistence)
{ {
$this->persistence = $persistence; $this->persistence = $persistence;
} }
public function generateId(): int public function generateId(): PostId
{ {
return $this->persistence->generateId(); return PostId::fromInt($this->persistence->generateId());
} }
public function findById(int $id): Post public function findById(PostId $id): Post
{ {
try { try {
$arrayData = $this->persistence->retrieve($id); $arrayData = $this->persistence->retrieve($id->toInt());
} catch (\OutOfBoundsException $e) { } catch (\OutOfBoundsException $e) {
throw new \OutOfBoundsException(sprintf('Post with id %d does not exist', $id), 0, $e); throw new \OutOfBoundsException(sprintf('Post with id %d does not exist', $id->toInt()), 0, $e);
} }
return Post::fromState($arrayData); return Post::fromState($arrayData);
@@ -44,7 +45,8 @@ class PostRepository
public function save(Post $post) public function save(Post $post)
{ {
$this->persistence->persist([ $this->persistence->persist([
'id' => $post->getId(), 'id' => $post->getId()->toInt(),
'statusId' => $post->getStatus()->toInt(),
'text' => $post->getText(), 'text' => $post->getText(),
'title' => $post->getTitle(), 'title' => $post->getTitle(),
]); ]);

View File

@@ -33,7 +33,19 @@ You can also find this code on `GitHub`_
Post.php Post.php
.. literalinclude:: Post.php .. literalinclude:: Domain/Post.php
:language: php
:linenos:
PostId.php
.. literalinclude:: Domain/PostId.php
:language: php
:linenos:
PostStatus.php
.. literalinclude:: Domain/PostStatus.php
:language: php :language: php
:linenos: :linenos:
@@ -43,18 +55,24 @@ PostRepository.php
:language: php :language: php
:linenos: :linenos:
MemoryStorage.php Persistence.php
.. literalinclude:: MemoryStorage.php .. literalinclude:: InMemoryPersistence.php
:language: php
:linenos:
InMemoryPersistence.php
.. literalinclude:: InMemoryPersistence.php
:language: php :language: php
:linenos: :linenos:
Test Test
---- ----
Tests/RepositoryTest.php Tests/PostRepositoryTest.php
.. literalinclude:: Tests/RepositoryTest.php .. literalinclude:: Tests/PostRepositoryTest.php
:language: php :language: php
:linenos: :linenos:

View File

@@ -2,7 +2,9 @@
namespace DesignPatterns\More\Repository\Tests; namespace DesignPatterns\More\Repository\Tests;
use DesignPatterns\More\Repository\MemoryStorage; use DesignPatterns\More\Repository\Domain\PostId;
use DesignPatterns\More\Repository\Domain\PostStatus;
use DesignPatterns\More\Repository\InMemoryPersistence;
use DesignPatterns\More\Repository\Domain\Post; use DesignPatterns\More\Repository\Domain\Post;
use DesignPatterns\More\Repository\PostRepository; use DesignPatterns\More\Repository\PostRepository;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@@ -16,12 +18,12 @@ class PostRepositoryTest extends TestCase
protected function setUp() protected function setUp()
{ {
$this->repository = new PostRepository(new MemoryStorage()); $this->repository = new PostRepository(new InMemoryPersistence());
} }
public function testCanGenerateId() public function testCanGenerateId()
{ {
$this->assertEquals(1, $this->repository->generateId()); $this->assertEquals(1, $this->repository->generateId()->toInt());
} }
/** /**
@@ -30,7 +32,7 @@ class PostRepositoryTest extends TestCase
*/ */
public function testThrowsExceptionWhenTryingToFindPostWhichDoesNotExist() public function testThrowsExceptionWhenTryingToFindPostWhichDoesNotExist()
{ {
$this->repository->findById(42); $this->repository->findById(PostId::fromInt(42));
} }
public function testCanPersistPostDraft() public function testCanPersistPostDraft()
@@ -39,6 +41,9 @@ class PostRepositoryTest extends TestCase
$post = Post::draft($postId, 'Repository Pattern', 'Design Patterns PHP'); $post = Post::draft($postId, 'Repository Pattern', 'Design Patterns PHP');
$this->repository->save($post); $this->repository->save($post);
$this->repository->findById($postId);
$this->assertEquals($postId, $this->repository->findById($postId)->getId()); $this->assertEquals($postId, $this->repository->findById($postId)->getId());
$this->assertEquals(PostStatus::STATE_DRAFT, $post->getStatus()->toString());
} }
} }

View File

@@ -3,20 +3,24 @@
<ID>PHP</ID> <ID>PHP</ID>
<OriginalElement>\DesignPatterns\More\Repository\PostRepository</OriginalElement> <OriginalElement>\DesignPatterns\More\Repository\PostRepository</OriginalElement>
<nodes> <nodes>
<node x="415.0" y="0.0">\DesignPatterns\More\Repository\Storage</node> <node x="283.0" y="167.0">\DesignPatterns\More\Repository\InMemoryPersistence</node>
<node x="405.0" y="137.0">\DesignPatterns\More\Repository\MemoryStorage</node> <node x="0.0" y="0.0">\DesignPatterns\More\Repository\Domain\PostStatus</node>
<node x="0.0" y="0.0">\DesignPatterns\More\Repository\Post</node> <node x="590.0" y="385.0">\DesignPatterns\More\Repository\Domain\PostId</node>
<node x="0.0" y="373.0">\DesignPatterns\More\Repository\PostRepository</node> <node x="0.0" y="385.0">\DesignPatterns\More\Repository\Domain\Post</node>
<node x="289.0" y="0.0">\DesignPatterns\More\Repository\Persistence</node>
<node x="320.0" y="385.0">\DesignPatterns\More\Repository\PostRepository</node>
</nodes> </nodes>
<notes /> <notes />
<edges> <edges>
<edge source="\DesignPatterns\More\Repository\MemoryStorage" target="\DesignPatterns\More\Repository\Storage"> <edge source="\DesignPatterns\More\Repository\InMemoryPersistence" target="\DesignPatterns\More\Repository\Persistence">
<point x="0.0" y="-74.5" /> <point x="0.0" y="-81.0" />
<point x="0.0" y="43.5" /> <point x="0.0" y="58.5" />
</edge> </edge>
</edges> </edges>
<settings layout="Hierarchic Group" zoom="0.7394636015325671" x="299.5" y="251.0" /> <settings layout="Hierarchic Group" zoom="1.0" x="666.5" y="488.0" />
<SelectedNodes /> <SelectedNodes>
<node>\DesignPatterns\More\Repository\PostRepository</node>
</SelectedNodes>
<Categories> <Categories>
<Category>Fields</Category> <Category>Fields</Category>
<Category>Constants</Category> <Category>Constants</Category>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 128 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -64,11 +64,11 @@ msgid "PostRepository.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59

View File

@@ -75,12 +75,12 @@ msgid "PostRepository.php"
msgstr "PostRepository.php" msgstr "PostRepository.php"
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "Storage.php" msgstr "Persistence.php"
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "MemoryStorage.php" msgstr "InMemoryPersistence.php"
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59
msgid "Test" msgid "Test"

View File

@@ -64,11 +64,11 @@ msgid "PostRepository.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59

View File

@@ -72,12 +72,12 @@ msgid "PostRepository.php"
msgstr "PostRepository.php" msgstr "PostRepository.php"
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "Storage.php" msgstr "Persistence.php"
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "MemoryStorage.php" msgstr "InMemoryPersistence.php"
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59
msgid "Test" msgid "Test"

View File

@@ -72,11 +72,11 @@ msgid "PostRepository.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59

View File

@@ -73,12 +73,12 @@ msgid "PostRepository.php"
msgstr "PostRepository.php" msgstr "PostRepository.php"
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "Storage.php" msgstr "Persistence.php"
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "MemoryStorage.php" msgstr "InMemoryPersistence.php"
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59
msgid "Test" msgid "Test"

View File

@@ -64,11 +64,11 @@ msgid "PostRepository.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:46 #: ../../More/Repository/README.rst:46
msgid "Storage.php" msgid "Persistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:52 #: ../../More/Repository/README.rst:52
msgid "MemoryStorage.php" msgid "InMemoryPersistence.php"
msgstr "" msgstr ""
#: ../../More/Repository/README.rst:59 #: ../../More/Repository/README.rst:59