Правильная структура вызова классов

Guest_w

Новичок
Правильная структура вызова классов

Всем привет.
Я уже довольно давно занимаюсь работой в области веб программирования, но для меня так и не решен вопрос какова должна быть ПРАВИЛЬНАЯ структура подключения классов..

А сейчас решил перейти на Pear :: DB так вообще ...

вот пример:
PHP:
class WWtree
{
	var $__db;
	function WWtree()
	{
		$this->__db = &DB::connect(DSN_OPT, true);

	 	if (DB::isError($db)) {  // эта строка не работает :-(
		die ($this->db->getMessage());
		}
		 
	}

	function recreateTable()
	{
		$sql="select * from table1; ";

		$this->__db->query($sql);
	}


}

$tree=&new WWtree();
$tree->recreateTable();
Както все здесь не так, как то глупо только не бейте сильно..

до этого я просто наследовал свои классы т.е.
Config_class
Mysql_class extends Config_class
Work_class extends class
....
хотя и это как то не так

я потратил день на поиски ответа но результата нет
:-(
 

whirlwind

TDD infected, paranoid
исключительные ситуации вон из конструктора

-~{}~ 07.02.06 15:17:

>Config_class
>Mysql_class extends Config_class
>Work_class extends class

надо наследовать одну сущность. например животное наследуется коровой. но в ситуации когда корова пользуется утюгом, утюг инкапсулируется в корове, а не наследуется.
 

Alexandre

PHPПенсионер
Я уже довольно давно занимаюсь работой в области веб программирования, но для меня так и не решен вопрос какова должна быть ПРАВИЛЬНАЯ структура подключения классов
Я занимаюсь веб программированием более 5 лет, и для себя так же не определил правильного решения. Вопрос, конечно филосовский.
Для начала, надо изучить Основы Объектно-ориентированного анализа, например здесь http://www.books.ru/shop/books/56332
Когда у тебя выстроится понимание основ ООА, то начнешь понимать для каких случаев твоя схема применима, а для каких лучше использовать иные шаблоны проектирования.
 

Guest_w

Новичок
Alexandre я занимаюсь около года и с классами моя основная проблема
за ссылку спасибо но книга через инет это долго..
думаю пробежаться по магазинам .
времени совсем нет а задачу хотелось бы решить


whirlwind
да я и сам понимаю что это неправильно, мне бы ссылки на метериал где будут примеры как надо делать
 

whirlwind

TDD infected, paranoid
Ссылок не дам, но посоветовать могу. Какое отношение имеет коннект к объекту WWTree? Никакого. Вынести всю работу с коннектами в сингельтон. Он пусть и обрабатывает исключительные ситуации, связанные с коннектом. В конструкторах никогда не размещать кода, который в случае невыполнения вызовет исключение. Хорошая практика - прием значений для первичной инициализации объекта. Но конструктор всегда должен иметь возможность выполниться без аргументов (д.б. заданы дефолтные значения аргументов). А в общем принцип не такой уж замороченный - все что не имеет отношения к сущности нашего объекта должно быть вынесено из класса.
 

Guest_w

Новичок
whirlwind
хоть за это спасибо.

а если допустим далее в программе (про класс WWtree забываем )будет функция
как из нее
DB::isError($db) вызвать иначе он говорит что незнает такую команду..

-~{}~ 08.02.06 13:18:

или же у меня есть класс , неважно какой,
а из него нужно обратится к базе данных с помощью другого класса, например, pear:DB, но как? если нельзя ни наследовать не глобал ...
 

whirlwind

TDD infected, paranoid
>DB::isError($db)

Это вызов статического. ИМХО, изноугуд. Вообще насчет DB ниче хорошего сказать не могу. Я выбрал Creole который меня устраивает по большинству показателей. Вот примерно как у меня выглядит работа с БД

PHP:
        protected function _deletePersistentObject(){
            $conn = $this->_getConnection();
            if ( $conn === null )
                return false;

            $qtext = sprintf("DELETE FROM %s WHERE %s = ?",
                $this->_getTableName(),$this->getPKID());
            $sth = $conn->prepareStatement($qtext);

            try {
                //$conn->setAutoCommit(false);
                $sth->executeQuery(
                    array($this->_atom($this->getPKID())->safeGetValue()));
                self::$_sql_deletes ++;
                //$conn->commit();
            } catch ( SQLException $e ){
                //$conn->rollback();
                $this->log("%s::%s %s",ML_ERROR,
                    __CLASS__,__FUNCTION__,$e->getMessage());
                return false;
            }

            return true;
        }

        private function _obtainConnection(){
            if ( $this->_pdbal_conn !== null ){
                return true;
            }

            try{
                $conn = DBConnectionManager::getConnection($this->_getDSN());
            } catch (SQLException $e){
                $this->log("%s::%s %s",ML_ERROR,
                    __CLASS__,__FUNCTION__,$e->getMessage());
                return false;
            }

            if ( $conn === null ){
                $this->log("%s::%s Couldn't connect: %s",ML_ERROR,
                    __CLASS__,__FUNCTION__, $this->_getDSN());
                return false;
            }

            if ( !($conn instanceof ConnectionCommon) ){
                $this->log("%s::%s Unknown driver type: %s",ML_ERROR,
                    __CLASS__,__FUNCTION__,get_class($conn));
                return false;
            }

            $this->_pdbal_conn = $conn;
            return true;
        }


        protected function _getConnection(){
            return $this->_obtainConnection() ? $this->_pdbal_conn : null;
        }
Я нигде не говорил, что нельзя юзать хендлер коннекшена. Просто инициировать сам коннект надо ВНЕ класса.

ПС. тут в соседней теме про лог говорили. Так вот у меня вызов log базового - это всего лиш способ унифицированно обрабатывать НЕ експекшены.
 

Guest_w

Новичок
whirlwind
спасибо, буду изучать

-~{}~ 12.02.06 09:24:

Я решил сделать так:
_________________________________________

require_once(PATH_TO_CLASS.'Mysql.class.php');

$c_m = new DB_mysql();
$ch = new Test($c_m);
$c_m->connect();

$ch->getGroup();

class Test
{
var $db; // private
var $error_mes='';
var $error=0;


function Test(&$db){

if(is_object($db)){
$this->db=&$db;
}
else {
$this->error_mes='Аргумент не является обьектом';
$this->error=1;
}
}

function getGroup($GroupId=0){
if (!$GroupId){
$this->db->query('select * from charts_groups',2);
}
else {

}

}

}

_________________________________________
это уже лучше ?
 

Andreika

"PHP for nubies" reader
whirlwind
В конструкторах никогда не размещать кода, который в случае невыполнения вызовет исключение.
эт еще почему?
 

itprog

Cruftsman
Мне тоже интересно почему, вполне правильно:
PHP:
public function __construct($str)
{
if(!is_string($str)) { throw new invalidParameterException(); }
}
 

whirlwind

TDD infected, paranoid
>эт еще почему?

1. конструктор должен иметь возможность отработать независимо от условий
2. конструктор вызываете не вы
3. для того, что бы получить результат отработки конструктора нужно изголяться (вам это надо?)

По поводу исключений тема уже неоднократно обсасывалась. То что в контексте класса является исключением, может не являться таковым например в контексте наследника или в контексте пользователя. Вы конечно, можете перегрузить функциональность конструктора базового класса, или обернуть вызов базового конструктора сеткой try/catch, что бы подавить исключительную ситуацию, но тогда возникает вопрос - на кой вы вообще что то наследовали, если модификация базового функционала начинается уже с конструктора? По большей части это вопрос дизайна. goto то же правильно с точки зрения интерпретатора, однако все знают, что это плохо.
 

Andreika

"PHP for nubies" reader
whirlwind
конструктор должен иметь возможность отработать независимо от условий
ага, а еще конструктор мне 100 у.е. должен...

конструктор вызываете не вы
допустим, и?

для того, что бы получить результат отработки конструктора нужно изголяться
если обычная функция возвращает false, то это уже не результат?

PHP:
class DB {
   function __construct() {
      if (!$this->conn =  mysql_connect()) {
          throw new Exception();
     }
  }
}
если для моего класса это исключение фатально (пример - обертка для "бд" - нет соединения с базой - нет смысла в существовании объекта.. но мы будем жить по библейским заповедям.. самоубийство это не выход, будем намекать пользователю - "знаете дохтор, у нас тут чтото того не этого")

не вижу смысла в "перегрузить с try catch" не меняя всю логику конструктора.. если есть что предложить объекту вместо погибшего родителя - try catch тут очень даже не помешает
в конце то концов там не exit вызывается и глобально на скрипт оно не влияет

допустим про goto уже через гены передается, а вот с исключениями в конструкторе вам прийдется других убеждать
 

whirlwind

TDD infected, paranoid
>а вот с исключениями в конструкторе вам прийдется других убеждать

Сейчас, только разбегусь побыстрее. Делать мне больше нечего. Я ни кому ничего не навязываю. У Вас своя техника разработки? Юзайте на здоровье исключения, замените хоть все ошибки на исключения мне абсолютно до фени.

> вместо погибшего родителя

Хотя я уверен, что лично в моих советах Вы, уважаемый, ну никак не можете нуждаться, все же рискну поправить. Не бывает никакого погибшего родителя. Классы существуют только для разработчика, для программы существуют экземпляры объектов, сконструированных на основе конечных классов. И обработать исключения в конструкторе вы можете только потому, что Вам приходится вызывать конструктор базового класса.
 

Andreika

"PHP for nubies" reader
Я ни кому ничего не навязываю.
слово "уже" после "я" забыл

>Не бывает никакого...
сам спросил,сам за меня ответил и теперь объясняешь почему "я" ответил неправильно? )

если ТЫ наследуешь МОЙ класс, то будь добр придерживацца моей идеологии.. если я считаю, что при данных условиях данный объект (экземпляр, если оч хочется) должен умереть, то не надо делать ему клизму целебную из try { parent::__construct}catch { пустота}.

в общем из аргументации только "я так делаю"? сильно
 

whirlwind

TDD infected, paranoid
Andreika умник, ты хоть сам понял че сказал? А по поводу моего ответа: каков привет, такой ответ. Ч/г я тебе недавно только с блеклиста вытащил, но видать преждевременно...
 

Andreika

"PHP for nubies" reader
whirlwind
я понял. а ты нет? может картинку тебе нарисовать? заплатно естестно
<offtop>
ага, вот думаю чего мне кошмары снились, а потом перестали.. а это оказывается меня whirlwind в блеклист поместил, а потом вытащил.. ну прям вершитель судеб блин )
</offtop>
 

whirlwind

TDD infected, paranoid
PS. Я все ж еще раз попытаюсь объяснить, что б те, кто реально интересуется поняли разницу между ошибкой и исключением. Исключение прекращает работу программы. Это значит что единственное неотловленное исключение завернет работу вашей программы на безусловный выход. Исключение в конструкторе - это попытка склеить ласты не объекту а программе. Исключение позволяют форсировать стек вызовов, не давая промежуточным звеньям алгоритма обработать результат вызванного метода/функции. По сути это то же самый goto.
 

Andreika

"PHP for nubies" reader
Исключение позволяют форсировать стек вызовов, что делать запрещено?
не давая промежуточным звеньям алгоритма обработать результат вызванного метода/функции
такое ощущение, что намеренно вызванное исключение В ВАШЕМ КОДЕ не относится к алгоритму, а является непредсказуемым стихийным бедствием. а то, что вы не обрабатываете (документированные) исключения в чужом коде - это проблемы авторов чужого кода?
 

whirlwind

TDD infected, paranoid
>а является непредсказуемым стихийным бедствием
Браво! Наконец то до Вас дошло.
 

zerkms

TDD infected
Команда форума
Исключение прекращает работу программы. Это значит что единственное неотловленное исключение завернет работу вашей программы на безусловный выход
совсем не согласен - исключения сделаны не для того чтобы аварийно завершить выполнение скрипта - а как раз наоборот - попытаться его (исключение или сложившуюся ситуацию) как можно более корректно обработать
 
Сверху