1final class EloquentJobRepository implements JobRepository
2{
3 public function find(int $id, bool $useCache = true): ?Job
4 {
5 if ($useCache && $job = Cache::get("job.{$id}")) {
6 return $job;
7 }
8
9 $started = microtime(true);
10 $job = Job::query()->with('company')->find($id);
11 Log::debug('job.find', ['id' => $id, 'ms' => (microtime(true) - $started) * 1000]);
12
13 if ($useCache && $job !== null) {
14 Cache::put("job.{$id}", $job, now()->addMinutes(10));
15 }
16
17 return $job;
18 }
19}
1<?php
2
3final readonly class Job
4{
5 public function __construct(public int $id, public string $title) {}
6}
7
81interface JobRepository
9{
10 public function find(int $id): ?Job;
11}
12
13final class DatabaseJobRepository implements JobRepository
14{
15 /** @param array<int, string> $rows */
16 public function __construct(private readonly array $rows) {}
17
18 public function find(int $id): ?Job
19 {
20 echo " SQL: select * from jobs where id = {$id}\n";
21
22 return isset($this->rows[$id]) ? new Job($id, $this->rows[$id]) : null;
23 }
24}
25
26final class CachedJobRepository implements JobRepository
27{
28 /** @var array<int, ?Job> */
29 private array $cache = [];
30
312 public function __construct(private readonly JobRepository $inner) {}
32
33 public function find(int $id): ?Job
34 {
35 if (! array_key_exists($id, $this->cache)) {
36 $this->cache[$id] = $this->inner->find($id);
37 }
38
39 return $this->cache[$id];
40 }
41}
42
433final class LoggingJobRepository implements JobRepository
44{
45 public function __construct(private readonly JobRepository $inner) {}
46
47 public function find(int $id): ?Job
48 {
49 $job = $this->inner->find($id);
50 echo " лог: find({$id}) ", $job === null ? 'нічого не знайшов' : 'знайшов вакансію', "\n";
51
52 return $job;
53 }
54}
55
564$jobs = new LoggingJobRepository(
57 new CachedJobRepository(
58 new DatabaseJobRepository([7 => 'Senior PHP Developer, Львів']),
59 ),
60);
61
62foreach ([1, 2, 3] as $visit) {
63 echo "Перегляд {$visit}:\n";
64 $job = $jobs->find(7);
65 echo " {$job?->title}\n";
66}