Forum Webscript.Ru

Программирование => PHP => Тема начата: Алексей от 04 Мая 2005, 13:46:23

Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 04 Мая 2005, 13:46:23
У меня имеется класс DB, для работы с БД.
Есть другой класс, который в данный момент является extends по отношению к DB:

class DB{
...
}

class OUTPUT extends DB{
...
}

Вот. Почему extends? потому, что в классе OUTPUT (это форматирование информаци перед разного рода выводом) имеется 1 метод из класса DB.

Получается, что в своих сценариях я запускаю либо DB, либо OUTPUT, в зависимости от того, нужно ли будет данные перед отправкой клиенту форматировать или нет.

Вот я и не уверен, правильно ли я делаю.. Может какие-нибудь другие способы есть вызвать метод класса DB из класса OUTPUT? Хотя с другой стороны, удобно инициализировать лишь OUTPUT

$myDB = new OUTPUT();

а не вызывать сначала класс DB, а потом и OUTPUT... Вобщем не знаю...
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Croaker от 04 Мая 2005, 14:02:37
Алексей

extends - ключевое слово. Наследование. Т.е. класс OUTPUT должен расширять класс DB, а не использовать.

Наследование может быть необходимо, если DB - это некий абстрактный класс для работы с базами данных вообще, а класс OUTPUT реализует, к примеру, работу с отдельно взятой СУБД (aka MySQL).

Если класс OUTPUT только использует методы класса DB, а не дополняет класс своими методами, то лучше использовать не наследование, а просто добавить в класс OUTPUT ссылку на класс DB. Например так:


class DB {

}

$dbh = new DB;

class OUTPUT {

    var $dbh;

    function OUTPIT($dbh) {
       $this->dbh = $dbh;
    }

}

$out = new OUTPUT(&$dbh);

Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 04 Мая 2005, 14:40:41
Croaker
понял, спасибо. Ща попробую разобраться..
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 04 Мая 2005, 14:41:53
Алексей
ты случайно не по статьям курепина учился ?



Цитировать
Croaker:
class DB {

}

$dbh = new DB;

class OUTPUT {

var $dbh;

function OUTPIT($dbh) {$this->dbh = $dbh; }

}

$out = new OUTPUT(&$dbh);

ИМХО правильнее :

class OUTPUT {

    var $dbh;

    function OUTPIT(&$dbh) {
       $this->dbh = &$dbh;
    }
}
$out = new OUTPUT($dbh);
твой код выдает warning при allow_call_time_pass_reference = Off в пхп4. В остальном все верно.
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Croaker от 04 Мая 2005, 14:49:24
Макс
Не знал. По логике вещей код

 function OUTPIT(&$dbh) {
       $this->dbh = &$dbh;
    }


Объявляет $this->dbh ссылкой на ссылку на объект. Не? Я не сильно в этом вопросе шарю. =\\
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 04 Мая 2005, 14:51:38
Croaker
все верно.
Ведь нам в скрипте  не надо 2 экземпляра объекта соединения с БД
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Croaker от 04 Мая 2005, 14:54:02
Макс
Не надо. Но откуда два экземпляра, если мы ссылку передаем изначально? По логике вещей в классе OUTPUT пользуем ссылку на единственный объект. Откуда второй берется?
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 04 Мая 2005, 15:02:39
1. Почему код $a = call_some_func(&$var)
считается некачественным ?
Потому что внутри функции call_some_func() нельзя определить, имеем ли мы дело с переменной или с ссылкой на нее.

2. если писать function call_some_func(&$var) {
   $b = &$var;
}
то мы точно будем иметь дело именно со ссылкой, а не со значением

3. В обсуждаемом случае второй объект (копия объекта) появится если не писать & в конструкторе :function OUTPIT(&$dbh) {
       $this->dbh = &$dbh;
    }
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Croaker от 04 Мая 2005, 15:07:48
Макс
Спасибо :)

Цитировать
Макс:
утри функции call_some_func() нельзя определить, имеем ли мы дело с переменной или с ссылкой на нее


вот этого не знал.
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 04 Мая 2005, 16:41:45
Макс
нет, я его не читал.

так как правильно?
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 04 Мая 2005, 17:01:45
Цитировать
Алексей:
так как правильно?

так как написал  Croaker с моими поправками.
Мои правки носят чисто технический характер. С точки зрения идеологии ООП Croaker все верно написал
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 08 Августа 2005, 11:23:39
Опять я возвращаюсь к этой теме.
Вообщем, я понял что и как и куда, зачем ссылки нужны тут, вот что получается:


class DB {
//........
}

class OUTPUT {

    var $dbh;

    function OUTPUT(&$dbh) {
       $this->dbh = &$dbh;
    }
}

// вызываю
$dbh = new DB; //сначала главный класс
$out = new OUTPUT($dbh); //потом класс обработки информации




Теперь я не понимаю, как мне со всем этим работать. раньше был экземпляр лишь одного класса. Теперь я инициализирую 2 класса, и для каждого действия приходится работать с определённым классом.

Т.е. раньше было:


$myDB= new DB;
// работаем с функцией класса DB - делаем SQL запрос
$data = $myDB->get_rezar("SELECT .........");
// работает с функцией класса OUTPUT, которая использует в своём теле функции из класса DB
$data = $myDB->replace_template($data);
 

а теперь как?
воот что получается (неудобно!)


$mainDB = new DB;
$myDB = new OUTPUT($mainDB);

// работаем с классом DB - делаем SQL запрос
$data = $mainDB->get_rezar("SELECT .........");
// работаем с классом OUTPUT
$data = $myDB->replace_template($data);
 

это правильно? но это чертовски нудобно. инициазизация 2 классов + работа с разными классами.... или я что-то не так сделал?
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: sarutobi от 08 Августа 2005, 23:44:36
Алексей
Так в этом идеология ООП и заключается. Класс MainDB ничего не знает о том, что будет происходить с данными, которые он возвращает. Он только знает, что взять и как вернуть. Класс MyDb вообще не интересует, откуда взялись данные. Он единственное что умеет - сделать обработку получаемых данных. У тебя (пока) не совсем праильная архитектура классов. Если я правильно поинмаю то что тебе надо, то написать надо так:

$mainDb = new Db();
$result = new MyDb();
$data = $result->replace_template($mainDB->getRezar());
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 09 Августа 2005, 10:48:34
sarutobi
понятно, спасибо.
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 09 Августа 2005, 13:37:28
Люди! Я решил всё на PHP 5 писать.
Насколько я понял, мне теперь просто нужно знаки амперсанд убрать, т.к. в 5 версии мы работаем не с копией, а с сылкой, т.е.:

 
class DB {
//........
}

class OUTPUT {

    var $dbh;

    function OUTPUT($dbh) {
       $this->dbh = $dbh;
    }
}

// вызываю
$dbh = new DB; //сначала главный класс
$out = new OUTPUT($dbh); //потом класс обработки информации
да?
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 09 Августа 2005, 16:32:05
Алексей
1. а ты хочешь работать с ссылкой или копией ?
2. Может правильнее будет спросить как научиться определять, когда работаешь с ссылкой а когда с копией ?
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 09 Августа 2005, 16:43:02
Макс
мне нужно просто работать с методом класса DB в классе OUTPUT.
для этого, мы передавали в OUTPUT ссылку(&) на DB, т.к. явно передавать переменную объекта в 4 версии нельзя было - передавалась лишь копия.
А с 5 версией вроде бы можно ссылку не ставить - будет сразу передаваться тот же объект. Это описано в одном из номеров PHPinside, о новшевствах 5 версии.

Поэтому я и спрашиваю.
1. Да мне в принципе всё равно в данном случае. Хотя нет.. наверно имено с ссылкой.
2. В 5 версии ты всегда будешь работать со ссылкой. Или я не прав?


Т.е. было у нас раньше:
class OUTPUT {

    var $dbh;

    function OUTPIT(&$dbh) {
       $this->dbh = &$dbh;
    }
}
$dbh = new DB;
$out = new OUTPUT($dbh);  

теперь, с выходом пятерки. насколько я понимаю, это можно переписать так:
(эффект будет один и тот же)


class OUTPUT {

    private $dbh;

    function __construct($dbh) {
       $this->dbh = $dbh;
    }
}
$dbh = new DB;
$out = new OUTPUT($dbh);
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 09 Августа 2005, 18:00:21
По-моему ты совсем не понимаешь разницы между ссылками и копиями
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 09 Августа 2005, 18:01:35
Цитировать
Алексей:
2. В 5 версии ты всегда будешь работать со ссылкой. Или я не прав?
неправ. В пятерке можно работать с копией, но для этого надо делать определенные действия
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Алексей от 09 Августа 2005, 18:06:57
Макс
ну как? ссылка - работаем с тем же объектом.
копия - это копия.

Цитировать
В пятерке можно работать с копией, но для этого надо делать определенные действия
clone??
Название: Посоветуйте, как правильно сделать (ООП)
Отправлено: Макс от 09 Августа 2005, 21:09:01
да, все верно.