Skip to content

Commit 6c726d6

Browse files
author
Dominik Liebler
committed
introduced PostId and PostStatus and changed naming from Storage to Persistence
1 parent 2ab82db commit 6c726d6

File tree

18 files changed

+334
-743
lines changed

18 files changed

+334
-743
lines changed

More/Repository/Domain/Post.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@
55
class Post
66
{
77
/**
8-
* @var int
8+
* @var PostId
99
*/
1010
private $id;
1111

12+
/**
13+
* @var PostStatus
14+
*/
15+
private $status;
16+
1217
/**
1318
* @var string
1419
*/
@@ -19,10 +24,11 @@ class Post
1924
*/
2025
private $text;
2126

22-
public static function draft(int $id, string $title, string $text): Post
27+
public static function draft(PostId $id, string $title, string $text): Post
2328
{
2429
return new self(
2530
$id,
31+
PostStatus::fromString(PostStatus::STATE_DRAFT),
2632
$title,
2733
$text
2834
);
@@ -31,29 +37,37 @@ public static function draft(int $id, string $title, string $text): Post
3137
public static function fromState(array $state): Post
3238
{
3339
return new self(
34-
$state['id'],
40+
PostId::fromInt($state['id']),
41+
PostStatus::fromInt($state['statusId']),
3542
$state['title'],
3643
$state['text']
3744
);
3845
}
3946

4047
/**
41-
* @param int $id
42-
* @param string $text
48+
* @param PostId $id
49+
* @param PostStatus $status
4350
* @param string $title
51+
* @param string $text
4452
*/
45-
private function __construct(int $id, string $title, string $text)
53+
private function __construct(PostId $id, PostStatus $status, string $title, string $text)
4654
{
4755
$this->id = $id;
56+
$this->status = $status;
4857
$this->text = $text;
4958
$this->title = $title;
5059
}
5160

52-
public function getId(): int
61+
public function getId(): PostId
5362
{
5463
return $this->id;
5564
}
5665

66+
public function getStatus(): PostStatus
67+
{
68+
return $this->status;
69+
}
70+
5771
public function getText(): string
5872
{
5973
return $this->text;

More/Repository/Domain/PostId.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace DesignPatterns\More\Repository\Domain;
4+
5+
/**
6+
* This is a perfect example of a value object that is identifiable by it's value alone and
7+
* is guaranteed to be valid each time an instance is created. Another important property of value objects
8+
* is immutability.
9+
*
10+
* Notice also the use of a named constructor (fromInt) which adds a little context when creating an instance.
11+
*/
12+
class PostId
13+
{
14+
/**
15+
* @var int
16+
*/
17+
private $id;
18+
19+
public static function fromInt(int $id)
20+
{
21+
self::ensureIsValid($id);
22+
23+
return new self($id);
24+
}
25+
26+
private function __construct(int $id)
27+
{
28+
$this->id = $id;
29+
}
30+
31+
public function toInt(): int
32+
{
33+
return $this->id;
34+
}
35+
36+
private static function ensureIsValid(int $id)
37+
{
38+
if ($id <= 0) {
39+
throw new \InvalidArgumentException('Invalid PostId given');
40+
}
41+
}
42+
}

More/Repository/Domain/PostStatus.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace DesignPatterns\More\Repository\Domain;
4+
5+
/**
6+
* Like PostId, this is a value object which holds the value of the current status of a Post. It can be constructed
7+
* either from a string or int and is able to validate itself. An instance can then be converted back to int or string.
8+
*/
9+
class PostStatus
10+
{
11+
const STATE_DRAFT_ID = 1;
12+
const STATE_PUBLISHED_ID = 2;
13+
14+
const STATE_DRAFT = 'draft';
15+
const STATE_PUBLISHED = 'published';
16+
17+
private static $validStates = [
18+
self::STATE_DRAFT_ID => self::STATE_DRAFT,
19+
self::STATE_PUBLISHED_ID => self::STATE_PUBLISHED,
20+
];
21+
22+
/**
23+
* @var int
24+
*/
25+
private $id;
26+
27+
/**
28+
* @var string
29+
*/
30+
private $name;
31+
32+
public static function fromInt(int $statusId)
33+
{
34+
self::ensureIsValidId($statusId);
35+
36+
return new self($statusId, self::$validStates[$statusId]);
37+
}
38+
39+
public static function fromString(string $status)
40+
{
41+
self::ensureIsValidName($status);
42+
43+
return new self(array_search($status, self::$validStates), $status);
44+
}
45+
46+
private function __construct(int $id, string $name)
47+
{
48+
$this->id = $id;
49+
$this->name = $name;
50+
}
51+
52+
public function toInt(): int
53+
{
54+
return $this->id;
55+
}
56+
57+
/**
58+
* there is a reason that I avoid using __toString() as it operates outside of the stack in PHP
59+
* and is therefor not able to operate well with exceptions
60+
*/
61+
public function toString(): string
62+
{
63+
return $this->name;
64+
}
65+
66+
private static function ensureIsValidId(int $status)
67+
{
68+
if (!in_array($status, array_keys(self::$validStates), true)) {
69+
throw new \InvalidArgumentException('Invalid status id given');
70+
}
71+
}
72+
73+
74+
private static function ensureIsValidName(string $status)
75+
{
76+
if (!in_array($status, self::$validStates, true)) {
77+
throw new \InvalidArgumentException('Invalid status name given');
78+
}
79+
}
80+
}

More/Repository/MemoryStorage.php renamed to More/Repository/InMemoryPersistence.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace DesignPatterns\More\Repository;
44

5-
class MemoryStorage implements Storage
5+
class InMemoryPersistence implements Persistence
66
{
77
/**
88
* @var array

More/Repository/Storage.php renamed to More/Repository/Persistence.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace DesignPatterns\More\Repository;
44

5-
interface Storage
5+
interface Persistence
66
{
77
public function generateId(): int;
88

More/Repository/PostRepository.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
namespace DesignPatterns\More\Repository;
44

55
use DesignPatterns\More\Repository\Domain\Post;
6+
use DesignPatterns\More\Repository\Domain\PostId;
67

78
/**
8-
* This class is situated between Entity layer (class Post) and access object layer (MemoryStorage).
9+
* This class is situated between Entity layer (class Post) and access object layer (Persistence).
910
*
1011
* Repository encapsulates the set of objects persisted in a data store and the operations performed over them
1112
* providing a more object-oriented view of the persistence layer
@@ -16,26 +17,26 @@
1617
class PostRepository
1718
{
1819
/**
19-
* @var Storage
20+
* @var Persistence
2021
*/
2122
private $persistence;
2223

23-
public function __construct(Storage $persistence)
24+
public function __construct(Persistence $persistence)
2425
{
2526
$this->persistence = $persistence;
2627
}
2728

28-
public function generateId(): int
29+
public function generateId(): PostId
2930
{
30-
return $this->persistence->generateId();
31+
return PostId::fromInt($this->persistence->generateId());
3132
}
3233

33-
public function findById(int $id): Post
34+
public function findById(PostId $id): Post
3435
{
3536
try {
36-
$arrayData = $this->persistence->retrieve($id);
37+
$arrayData = $this->persistence->retrieve($id->toInt());
3738
} catch (\OutOfBoundsException $e) {
38-
throw new \OutOfBoundsException(sprintf('Post with id %d does not exist', $id), 0, $e);
39+
throw new \OutOfBoundsException(sprintf('Post with id %d does not exist', $id->toInt()), 0, $e);
3940
}
4041

4142
return Post::fromState($arrayData);
@@ -44,7 +45,8 @@ public function findById(int $id): Post
4445
public function save(Post $post)
4546
{
4647
$this->persistence->persist([
47-
'id' => $post->getId(),
48+
'id' => $post->getId()->toInt(),
49+
'statusId' => $post->getStatus()->toInt(),
4850
'text' => $post->getText(),
4951
'title' => $post->getTitle(),
5052
]);

More/Repository/README.rst

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ You can also find this code on `GitHub`_
3333

3434
Post.php
3535

36-
.. literalinclude:: Post.php
36+
.. literalinclude:: Domain/Post.php
37+
:language: php
38+
:linenos:
39+
40+
PostId.php
41+
42+
.. literalinclude:: Domain/PostId.php
43+
:language: php
44+
:linenos:
45+
46+
PostStatus.php
47+
48+
.. literalinclude:: Domain/PostStatus.php
3749
:language: php
3850
:linenos:
3951

@@ -43,18 +55,24 @@ PostRepository.php
4355
:language: php
4456
:linenos:
4557

46-
MemoryStorage.php
58+
Persistence.php
59+
60+
.. literalinclude:: InMemoryPersistence.php
61+
:language: php
62+
:linenos:
63+
64+
InMemoryPersistence.php
4765

48-
.. literalinclude:: MemoryStorage.php
66+
.. literalinclude:: InMemoryPersistence.php
4967
:language: php
5068
:linenos:
5169

5270
Test
5371
----
5472

55-
Tests/RepositoryTest.php
73+
Tests/PostRepositoryTest.php
5674

57-
.. literalinclude:: Tests/RepositoryTest.php
75+
.. literalinclude:: Tests/PostRepositoryTest.php
5876
:language: php
5977
:linenos:
6078

More/Repository/Tests/PostRepositoryTest.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace DesignPatterns\More\Repository\Tests;
44

5-
use DesignPatterns\More\Repository\MemoryStorage;
5+
use DesignPatterns\More\Repository\Domain\PostId;
6+
use DesignPatterns\More\Repository\Domain\PostStatus;
7+
use DesignPatterns\More\Repository\InMemoryPersistence;
68
use DesignPatterns\More\Repository\Domain\Post;
79
use DesignPatterns\More\Repository\PostRepository;
810
use PHPUnit\Framework\TestCase;
@@ -16,12 +18,12 @@ class PostRepositoryTest extends TestCase
1618

1719
protected function setUp()
1820
{
19-
$this->repository = new PostRepository(new MemoryStorage());
21+
$this->repository = new PostRepository(new InMemoryPersistence());
2022
}
2123

2224
public function testCanGenerateId()
2325
{
24-
$this->assertEquals(1, $this->repository->generateId());
26+
$this->assertEquals(1, $this->repository->generateId()->toInt());
2527
}
2628

2729
/**
@@ -30,7 +32,7 @@ public function testCanGenerateId()
3032
*/
3133
public function testThrowsExceptionWhenTryingToFindPostWhichDoesNotExist()
3234
{
33-
$this->repository->findById(42);
35+
$this->repository->findById(PostId::fromInt(42));
3436
}
3537

3638
public function testCanPersistPostDraft()
@@ -39,6 +41,9 @@ public function testCanPersistPostDraft()
3941
$post = Post::draft($postId, 'Repository Pattern', 'Design Patterns PHP');
4042
$this->repository->save($post);
4143

44+
$this->repository->findById($postId);
45+
4246
$this->assertEquals($postId, $this->repository->findById($postId)->getId());
47+
$this->assertEquals(PostStatus::STATE_DRAFT, $post->getStatus()->toString());
4348
}
4449
}

More/Repository/uml/Repository.uml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,24 @@
33
<ID>PHP</ID>
44
<OriginalElement>\DesignPatterns\More\Repository\PostRepository</OriginalElement>
55
<nodes>
6-
<node x="415.0" y="0.0">\DesignPatterns\More\Repository\Storage</node>
7-
<node x="405.0" y="137.0">\DesignPatterns\More\Repository\MemoryStorage</node>
8-
<node x="0.0" y="0.0">\DesignPatterns\More\Repository\Post</node>
9-
<node x="0.0" y="373.0">\DesignPatterns\More\Repository\PostRepository</node>
6+
<node x="283.0" y="167.0">\DesignPatterns\More\Repository\InMemoryPersistence</node>
7+
<node x="0.0" y="0.0">\DesignPatterns\More\Repository\Domain\PostStatus</node>
8+
<node x="590.0" y="385.0">\DesignPatterns\More\Repository\Domain\PostId</node>
9+
<node x="0.0" y="385.0">\DesignPatterns\More\Repository\Domain\Post</node>
10+
<node x="289.0" y="0.0">\DesignPatterns\More\Repository\Persistence</node>
11+
<node x="320.0" y="385.0">\DesignPatterns\More\Repository\PostRepository</node>
1012
</nodes>
1113
<notes />
1214
<edges>
13-
<edge source="\DesignPatterns\More\Repository\MemoryStorage" target="\DesignPatterns\More\Repository\Storage">
14-
<point x="0.0" y="-74.5" />
15-
<point x="0.0" y="43.5" />
15+
<edge source="\DesignPatterns\More\Repository\InMemoryPersistence" target="\DesignPatterns\More\Repository\Persistence">
16+
<point x="0.0" y="-81.0" />
17+
<point x="0.0" y="58.5" />
1618
</edge>
1719
</edges>
18-
<settings layout="Hierarchic Group" zoom="0.7394636015325671" x="299.5" y="251.0" />
19-
<SelectedNodes />
20+
<settings layout="Hierarchic Group" zoom="1.0" x="666.5" y="488.0" />
21+
<SelectedNodes>
22+
<node>\DesignPatterns\More\Repository\PostRepository</node>
23+
</SelectedNodes>
2024
<Categories>
2125
<Category>Fields</Category>
2226
<Category>Constants</Category>

More/Repository/uml/uml.png

102 KB
Loading

0 commit comments

Comments
 (0)