| |
держать все те методы, которые поддерживаются MysqlTable, только заниматься
они будут ни чем иным, как просто переадресацией вызовов на "настоящие" объекты.
А последние, в свою очередь, хранятся в глобальном массиве объектов, на
элементы
которого должно ссылаться одно из свойств IMysql. Реализуем эту стратегию для
упрощенной версии MysqlTable, имеющей только метод Drop() и конструктор
(листинг 31.5):
Листинг 31.5. Упрощенный интерфейс к таблице MySQL
// Массив объектов-таблиц, созданных в программе
$GLOBALS["Tables"]=array(); // вначале массив пуст
// Реализация класса. Это — обычный класс без каких-либо особенностей.
// Давайте предположим, что объекты этого класса недопустимо
// копировать обычным способом.
class MysqlTable {
// . . .
function MysqlTable($name) { echo "MysqlTable($name) "; }
function Drop() { echo "Drop() "; }
}
// Класс-интерфейс
class IMysql {
var $id; // идентификатор реализации таблицы (MysqlTable) в $Tables
// Открывает таблицу с именем $name. Если эта таблица уже была
// открыта ранее, то ничего не делает и просто становится ее
// синонимом, иначе создает экземпляр объекта.
Часть V. Приемы программирования на PHP 484
function IMysql($name)
{ global $Tables;
$this->id=$name;
// Если объект для таблицы $name еще не создан, создать его
if(!isset($Tables[$name])) $Tables[$name]=new MysqlTable($name);
// Иначе объект уже существует и ничего делать не надо
}
// Уничтожает таблицу. Переадресуем вызов реализации
function Drop() { $obj=&$GLOBALS['Tables'][$this->id]; $obj->Drop(); }
}
// Демонстрация работы с интерфейсом
$m=new IMysql("TestTable"); // объект создается
$m=new IMysql("TestTable"); // новый объект не создается!
$m->Drop(); // очищается единственный объект
Откровенно говоря, мы реализовали здесь не совсем то, что в объектно-
ориентированном проектировании принято называть "интерфейсом". По опре-
делению интерфейс не может иметь конструктора, класс же IMysql его имеет.
Так что слово "интерфейс" здесь, мягко говоря, не подходит, но я буду назы-
вать класс IMysql именно так — для краткости. Думаю, в этом нет ничего
страшного — такова уж специфика PHP, и это самое простое, что можно было
бы предложить. В самом деле, не писать же на PHP специальные "классы-
фабрики", занимающиеся исключительно созданием объектов, как это принято
в ООП…
Таким образом, как при копировании, так и при создании объекта-таблицы, который
был уже ранее создан в программе, новый экземпляр объекта не создается. Иными
словами, мы можем иметь сколько угодно объектов класса IMysql, ссылающихся на
одну и ту же таблицу, и при изменении одного из них это "почувствуют" и все ос-
тальные. Нужно только грамотно реализовать все переадресующие функции.
И еще насчет класса-реализации: лучше всего дать ему какое-нибудь некрасивое
имя
(например, __MysqlTableImpl__), чтобы какой-нибудь неопытный пользователь
случайно не стал к нему обращаться напрямую, а не через IMysql.
Хочу заметить, что в настоящих объектно-ориентированных языках нет причин при-
бегать к столь странным ухищрениям, потому что в них есть такое понятие, как
ука-
з
|
|