САМОУЧИТЕЛЬ PHP 4

       

Возврат ссылки на объект


Первый прием связан с новой возможностью PHP версии 4— ссылочными переменными. Помните, в части III этой книги мы говорили, что функция может возвращать ссылку на переменную (объект), а не только копию переменной?.. В нашем случае это оказывается довольно удобно. Вот как могла бы выглядеть функция OpenTable() и использование для нее ссылок (листинг 31.4):

Листинг 31.4. Использование ссылок

// Массив всех уже открытых таблиц. Ключи — имена таблиц, значения —

// соответствующие объекты.

$Tables=array();

. . .

// Функция OpenTable() возвращает ссылку на объект, соответствующий

// таблице MySQL с заданным именем. Копии объектов не создаются.

function &OpenTable($name,$Fields="")

{ global $Tables;

 if(!Isset($Tables[$name]))

 $Tables[$name]=new MysqlTable($name,$Fields);

 return $Tables[$name];



}

. . .

// Вот так мы должны использовать эту функцию.

$Tbl1=&OpenTable("MyTable"); // создает новый объект

$Tbl2=&OpenTable("OtherTable"); // создает объект

$TblEqualsTo1=&OpenTable("MyTable"); // возвращает имеющийся объект!

// Теперь $Tbl1 и $TblEqualsTo1 ссылаются на один и тот же объект.

// То есть изменение $Tbl1 тут же отразится на $TblEqualsTo1,

// и наоборот.

Опытный программист сразу же заметит в подходе предыдущего примера два значительных недостатка. Оба они связаны с несовершенством механизма управления ссылками в PHP.

r    Если пропустить перед вызовом функции оператор & (взятие ссылки), то функция вернет не ссылку на объект, а копию этого объекта. При этом программа не выдаст никакого предупреждения и, скорее всего, будет даже работать верно — до тех пор, пока для копии объекта не будет вызван метод, ради которого мы и хотели избежать копирования. Вообразите себе муки программиста, отлаживающего такую программу, которая отказалась правильно работать по этой причине — ведь & может быть пропущен очень далеко от того места, где возникла ошибка!

r    У неопытного программиста, использующего ваш класс, может возникнуть искушение скопировать $Tbl1 в новую переменную "обычным"

образом — при помощи оператора =. Или же он может по ошибке пропустить &, когда объявляет функцию со ссылочным параметром.

Мы видим, что два указанных недостатка приводят к тому, что программу становится очень трудно отлаживать. А такие программы, как показал многолетний опыт программирования, не только никуда не годятся — они приносят разработчику лишь огорчения, сокращая его век.

Есть ли альтернатива ссылкам? Оказывается, есть. Правда, она сопряжена с большими сложностями при разработке классов, но зато полностью лишена недостатков, описанных выше. Это — фактическое отделение набора методов, отвечающих за взаимодействие с объектом класса (то есть интерфейса класса) от его реализации.



Содержание раздела