ASubject::detach()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlecRabbit\Spinner\Core\A;
6
7
use AlecRabbit\Spinner\Contract\IObserver;
8
use AlecRabbit\Spinner\Contract\ISubject;
9
use AlecRabbit\Spinner\Exception\InvalidArgument;
10
use AlecRabbit\Spinner\Exception\LogicException;
11
use AlecRabbit\Spinner\Exception\ObserverCanNotBeOverwritten;
12
13
use function sprintf;
14
15
abstract class ASubject implements ISubject
16
{
17
    public function __construct(
18
        protected ?IObserver $observer = null,
19
    ) {
20
    }
21
22
    public function notify(): void
23
    {
24
        $this->observer?->update($this);
25
    }
26
27
    public function attach(IObserver $observer): void
28
    {
29
        $this->assertNotSelf($observer);
30
31
        $this->assertObserverIsNotAttached();
32
33
        $this->observer = $observer;
34
    }
35
36
    /**
37
     * @throws InvalidArgument
38
     */
39
    protected function assertNotSelf(object $obj): void
40
    {
41
        if ($obj === $this) {
42
            throw new InvalidArgument(
43
                sprintf(
44
                    'Object can not be self. %s #%s.',
45
                    get_debug_type($obj),
46
                    spl_object_id($obj),
47
                )
48
            );
49
        }
50
    }
51
52
    /**
53
     * @throws LogicException
54
     */
55
    protected function assertObserverIsNotAttached(): void
56
    {
57
        if ($this->observer instanceof IObserver) {
58
            throw new ObserverCanNotBeOverwritten('Observer is already attached.');
59
        }
60
    }
61
62
    public function detach(IObserver $observer): void
63
    {
64
        if ($this->observer === $observer) {
65
            $this->observer = null;
66
        }
67
    }
68
}
69