4.1. Delegacja (Delegation)

4.1.1. Przeznaczenie

Ideą wzorca projektowego Delegacji jest przekazanie zadania, które obiekt delegujący powinien wykonać (ze względu na zdefiniowaną w nim metodę) do innego, powiązanego obiektu, który to zadanie wykonuje. W tym przykładzie klasa TeamLead posiada metodę writeCode(), która jest wykorzystywana w klasie DelegationTest. Jednak realizacja tej metody tak na prawdę odbywa się poprzez metodę writeBadCode() w klasie JuniorDeveloper - obiekt klasy TeamLead wykonanie tej metody deleguje na obiekt klasy JuniorDeveloper. W ten sposób test nieświadomie uruchamia metodę writeBadCode().

4.1.2. Przykłady

Sprawdź zawartość klasy JuniorDeveloper, TeamLead oraz DelegationTest, aby zapoznać się z ideą działania tego wzorca.

4.1.3. Diagram UML

Alt Delegation UML Diagram

4.1.4. Kod

Ten kod znajdziesz również na GitHub.

TeamLead.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

namespace DesignPatterns\More\Delegation;

class TeamLead
{
    /**
     * @var JuniorDeveloper
     */
    private $junior;

    /**
     * @param JuniorDeveloper $junior
     */
    public function __construct(JuniorDeveloper $junior)
    {
        $this->junior = $junior;
    }

    public function writeCode(): string
    {
        return $this->junior->writeBadCode();
    }

    public function writeBadCode(): string
    {
        //note that we are passing $this from teamLead context
        return $this->junior->writeReallyBadCode($this);
    }

    /**
     * Junior can call this method
     */
    public function writeReallyBadCode(): string
    {
        return 'Even team lead can write bad code...';
    }
}

JuniorDeveloper.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php

namespace DesignPatterns\More\Delegation;

class JuniorDeveloper
{
    public function writeBadCode(): string
    {
        return 'Some junior developer generated code...';
    }

    /**
     * Junior is authorized to call method on TeamLead (real delegation)
     */
    public function writeReallyBadCode(TeamLead $teamLead): string
    {
        return $teamLead->writeReallyBadCode();
    }
}

4.1.5. Testy

Tests/DelegationTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

namespace DesignPatterns\More\Delegation\Tests;

use DesignPatterns\More\Delegation;
use PHPUnit\Framework\TestCase;

class DelegationTest extends TestCase
{
    public function testTeamLeadCanBlameJuniorForBadCode()
    {
        $junior = new Delegation\JuniorDeveloper();
        $teamLead = new Delegation\TeamLead($junior);

        $this->assertEquals($junior->writeBadCode(), $teamLead->writeCode());
    }

    public function testTeamLeadCanWriteBadCode()
    {
        $junior = new Delegation\JuniorDeveloper();
        $teamLead = new Delegation\TeamLead($junior);

        $this->assertEquals($junior->writeReallyBadCode($teamLead), $teamLead->writeBadCode());
    }
}