30 мар. 2011 г.

Шаблон делегирования


[показать]

[показать]


[показать]

Исходный текст на языке PHP5

<?php


class A {

    public function f() {
        print "А: Вызываем метод f()<br />";

    }

    public function g() {
        print "А: Вызываем метод g()<br />";

    }
}

class C {

    private $_a;


    public function __construct() {
        $this->_a = new A;

    }

    public function f() {
        $this->_a->f();

    }

    public function g() {
        $this->_a->g();

    }

    public function y() {
        print "C: вызываем метод y()<br />";

    }
}

$obj = new C;
$obj->f();

$obj->g();
$obj->y();

?>

Сложный пример


[показать]

[показать]


[показать]

Исходный текст на языке PHP5

<?php


// используем интерфейс для безопасности типа
interface I {
    public function f();

    public function g();
}

class A implements I {

    public function f() {
        print "А: Вызываем метод f()<br />";

    }

    public function g() {
        print "А: Вызываем метод g()<br />";

    }
}

class B implements I {
    public function f() {

        print "B: Вызываем метод f()<br />";
    }

    public function g() {

        print "B: Вызываем метод g()<br />";
    }
}

class C implements I {

    private $_i;

    // создаём объект, методы которого будем делегировать
    public function __construct() {

        $this->_i = new A;
    }

    // этими методами меняем поле-объект, чьи методы будем делегировать

    public function toA() {
        $this->_i = new A;

    }

    public function toB() {
        $this->_i = new B;

    }


    // делегированые методы
    public function f() {

        $this->_i->f();
    }

    public function g() {

        $this->_i->g();
    }
}

$obj = new C;

$obj->f();
$obj->g();
$obj->toB();

$obj->f();
$obj->g();

?>

Нетривиальный пример

Этот пример — это версия на PHP нетривиального примера, приведённого выше.


[показать]

[показать]


[показать]

Исходный текст на языке PHP5

<?php

// класс для хранения данных о сотруднике

class TEmployee {

    private $_name;
    private $_departament;


    public function __construct($name, $departament) {
        $this->_name = $name;

        $this->_departament = $departament;
    }

    public function getName() {

        return $this->_name;
    }

    public function getDepartament() {

        return $this->_departament;
    }
}

// имитация стандартного класса Delphi для хранения списка объектов
class TObjectList {


    private $_objList;

    public function __construct() {

        $this->free();
    }
    /**
     *чтобы не скучать!
     */
    public function free() {

        $this->_objList = array();
    }

    public function count() {

        return count($this->_objList);
    }

    public function add($obj) {

        array_push($this->_objList, $obj);
    }

    public function remove($obj) {

        $k = array_search( $obj, $this->_objList, true );

        if ( $k ) {
            unset( $this->_objList[$k] );

        }
    }

    public function get($index) {

        return $this->_objList[$index];
    }

    public function set($index, $obj) {

        $this->_objList[$index] = $obj;
    }
}


// класс для хранения сотрудников
class TEmployeeList {

    // объект класса "список объектов"
    private $_employeersList;


    public function __construct(){
        // создаём объект методы которого будем делегировать
        $this->_employeersList = new TObjectList;

    }

    public function getEmployer($index) {
        return $this->_employeersList->get($index);

    }

    public function setEmployer($index, TEmployee $objEmployer) {

        $this->_employeersList->set($index, $objEmployer);
    }


    public function __destruct() {
        $this->_employeersList->free();

    }

    public function add(TEmployee $objEmployer) {
        $this->_employeersList->add($objEmployer);

    }

    public function remove(TEmployee $objEmployer) {
        $this->_employeersList->remove($objEmployer);

    }

    // последовательный поиск сотрудника по имени
    // через аргумент $offset можно задавать позицию с которой вести поиск.
    // если сотрудник не найден вернёт значение меньше ноля (-1)
    public function getIndexByName($name, $offset=0) {

        $result = -1; // предполагаем, что его нету в списке
        $cnt = $this->_employeersList->count();

        for ($i = $offset; $i < $cnt; $i++) {

            if ( !strcmp( $name, $this->_employeersList->get($i)->getName() ) ) {

                $result = $i;
                break;
            }
        }

        return $result;
    }
}

$obj1 = new TEmployee("Шлёнский Дмитрий", "web студия");

$obj2 = new TEmployee("Кусый Назар", "web студия");
$obj3 = new TEmployee("Сорока Орест", "web студия");


$objList = new TEmployeeList();
$objList->add($obj1);

$objList->add($obj2);
$objList->add($obj3);


echo "<pre>";
print_r($objList);

echo "<hr>";


$index = $objList->getIndexByName("Кусый Назар");
$obj4 = $objList->getEmployer($index);

print_r($obj4);

echo "<hr>";

$objList->setEmployer(2, $obj4);

print_r($objList);
echo "</pre>";
?>



* This source code was highlighted with Source Code Highlighter.