объекты и библиотеки

iceman

говнокодер
а если я например код подгрузки "дополнительного" кода вынес в класс...

работает она так, сначало с БД берется список плагинов которые могут исполнятся... патом идет загрузка из ФС все доступные плагины... и по сопостовлению - загружаются...

это что мне надо разделить код загрузки... и от кода запроса к БД?

т.е. сделать так чтобы функция принимала масив данных... с доступными плагинами и с разрешенными?
 

dark-demon

d(^-^)b
korchasa, основной недостаток констант в том, что их нельзя изменить :) а бывает нужно...

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

iceman

говнокодер
следуя этой статье http://wiki.agiledev.ru/doku.php?id=ooad:manage_dependencies_in_php_code

у меня вопрос:

есть класс структура, который оргинизует структуру

а есть класс структура_cms - который организует структуру маей CMS

следуя выше преведенной статье, мой класс структура_cms должен наследовать класс структуру или получать объект структура, который должен поддерживать определенный мною интерфейс и работать сним?

или вот, класс КОНФИГ, в котором организован методы добавить конфиг и получить конфиг, и есть класс КОНФИГ_ЦМС по моей затеи он должен брать настройки с ДБ... а как их хранить на протижение выполнения скрипта, его не должно волновать...

ну вот, КОНФИГ_ЦМС должен абстрагироватся от класса КОНФИГ или должен получить этот класс, поддерживающий определенные методы и работать с ним?
 

korchasa

LIMB infected
Автор оригинала: dark-demon
korchasa, основной недостаток констант в том, что их нельзя изменить :) а бывает нужно...
Где я говорил о константах?
как ты предлагаешь с помощью статиков реализовывать абстрактные методы не привязанные к конкретной бд? например, нужно реализовать метод копирования содержимого одной базы в другую.
Причем здесь статики? Они используются для ХРАНЕНИЯ, и не для чего другого. Если вам надо абстрагироваться от конкретной БД, и реализовать общий интерфейс, то DBAL вам в помощь, но зачем на средство хранения ОБЪЕКТОВ (ему пофигу каких, в общем случае) что-то еще накладывать? Сделайте сервис, его и используйте.
PHP:
$service = new DbCopyService();
$service->setSource(registry::instance()->get('primary_db'));
$service->setDestination(registry::instance()->get('secondary_db'));
$service->copy();
следуя выше преведенной статье, мой класс структура_cms должен наследовать класс структуру или получать объект структура, который должен поддерживать определенный мною интерфейс и работать сним?
Если ничего противоестественного в структура_cms не происходит, то он является частным случаем структуры (kind of), и должен ее наследовать.

ну вот, КОНФИГ_ЦМС должен абстрагироватся от класса КОНФИГ или должен получить этот класс, поддерживающий определенные методы и работать с ним?
Тоже самое, если не предполагается, например, сливание нескольких конфигов.
 

whirlwind

TDD infected, paranoid
я имел виду када писал, что для чего использовать в ввиде объекта ($obk = new PARSER если можно легче parser:red_parse(); parser:eek:st_parse();
короче != легче

Объекты полезны при комбинировании. Если не использовать агрегацию, то никакой пользы от объектов нет.

Пример

PHP:
interface IConfig {
   public function getVar($varName);
   public function setVar($varName,$value);
}

interface IConfigParser {
   public function parse($filename);
}

// Каждый из нижеперечисленных классов может быть
// оттестирован, отремонтирован, изменен и тп. без
// ущерба для всего остального кода
class IniConfigParser implements IConfigParser { ... }
class XmlConfigParser implements IConfigParser { ... }
class AnotherConfigParser implements IConfigParser { ... }
class FakeConfigParser implements IConfigParser,IConfig { ... }

class ConfigParser {
   protected $_parsers = Array();

   public function registerParser($fileExtension,IConfigParser $parser) {
      $this->_parsers[$fileExtension] = $parser;
   }

   public function parse($filename) {
      // здесь анализируем расширение имени файла и если для такого
      // расширения зарегистрирован обработчик, то
      return $this->_parsers[$ext]->parse($filename);
   }
}

// на этапе инициализации системы это может выглядеть так
$facade = new ConfigParser();
$facade->registerParser('ini',new IniConfigParser());
$facade->registerParser('xml',new XmlConfigParser());
System::getInstance()->setConfigParser($facade);

// ...

$iniConfig = System::getInstance()->getConfigParser()->parse('myconfig.ini');

// через мильен строк кода в непонятном направлении
// мы хотим обмануть некий код, который использует парсер.
// Мы хотим переопределить его поведение, не затрагивая код
// "обманываемого" класса. Мы не трогаем ни этап инициализации,
// ни код существующих классов, все решается
// локально на этом самом месте (с функциями так не получится)
$oldParser = System::getInstance()->getConfigParser();
$fake = new FakeConfigParser($oldParser); // это декоратор. он перекрывает кое-какие значения
$fake->setVar('supportname','Vasya Pupkin');
$fake->setVar('feedbackemail',System::getInstance()->fetchConstant('feedbackemail'));
System::getInstance()->getConfigParser()->registerParser('ini',$fake); 

$myObject = new PageController(); // этот класс использует парсер с подставными значениями
$myObject->run();

System::getInstance()->getConfigParser()->registerParser('ini',$oldParser);
Объекты нужны там где они могут быть заменены на другие экземпляры. Другой экземпляр может подразумевать другой набор значений атрибутов объекта или другую реализацию методов, но всегда подразумевается единый интерфейс.
 

dark-demon

d(^-^)b
> Где я говорил о константах?

когда ты пишешь registry:: - это означает, что ты обращаешься к свойствам "глобального константного объекта" или попросу "класса".


> Сделайте сервис, его и используйте.

замечательно, у нас получилось нечто вроде:


PHP:
function anyMethod(){
  // что-то делаем
  $service = new DbCopyService();
  $service->setSource(registry::instance()->get('primary_db'));
  $service->setDestination(registry::instance()->get('secondary_db'));
  $service->copy();
  // что-то делаем
}
теперь из внешнего кода нужно вызвать этот метод, но чтобы он работал не с теми базами, что прописаны в реестре под именами 'primary_db' и 'secondary_db'. впрочем, можешь не отвечать, за тебя это уже сделал whirlwind:


> Мы не трогаем ни этап инициализации,
> ни код существующих классов, все решается
> локально на этом самом месте (с функциями так не получится)

молодец, ты реализовал паттерн "стэк". ^_^ проблема в том, что ты зачем-то используешь синглетон сознательно ограничивая себя единственной реализацией и тут же с помощью стэка обходишь это ограничение. к чему эти пляски с бубном?

то же самое, но проще:

PHP:
global $parser;
$newParser= new Parser;
$newParser->support= 'pupkin';
array_unshift( $parser, $newParser );

$myObject = new PageController(); // этот объект использует парсер $parser[0] с подставными значениями
$myObject->run();

array_shift( $parser );
и на функциях реализовать можно всё, что угодно. доказано ассемблером ^_^

-~{}~ 06.11.07 22:43:

хотя нет, что-то я тормознул. стэк ты так и не реализовал. ты реализовал паттерн "глобальная переменная в крайне извращённой форме":

PHP:
global $parser;
$newParser= new Parser;
$newParser->support= 'pupkin';
$oldParser= $parser;
$parser= $newParser;

$myObject = new PageController(); // этот объект использует парсер $parser с подставными значениями
$myObject->run(); 

$parser= $oldParser;
 

korchasa

LIMB infected
>когда ты пишешь registry:: - это означает, что ты обращаешься к свойствам "глобального константного объекта" или попросу "класса"
Это ОДНА статическая связка, которую НИКОГДА не надо подменять, надо менять СОДЕРЖИМОЕ. Надеюсь с капсом понятнее.

>теперь из внешнего кода нужно вызвать этот метод, но чтобы он работал не с теми базами, что прописаны в реестре под именами 'primary_db' и 'secondary_db'.
PHP:
registry::instance->set('primary_db', $new_value);
Мы делаем это ЯВНО.

>то же самое, но проще
то же самое, но с помощью магии, описанной в комментарии

Прочитайте выше мой пост по поводу +/- GLOBALS, там вроде все ясно описано, и никто вроде бы не спорил.

Неявное хуже явного ;)
 

whirlwind

TDD infected, paranoid
молодец, ты реализовал паттерн "стэк".
Где ты тут стек увидел, я не понял

^_^ проблема в том, что ты зачем-то используешь синглетон сознательно ограничивая себя единственной реализацией и тут же с помощью стэка обходишь это ограничение. к чему эти пляски с бубном?
Ну, может это у тебя такие сингельтоны, которые ограничивают твой код единственной реализацией. Я вроде интерфейс System не показывал. В моей реализации это как правило нечто подобное

PHP:
    private function __construct(){
        WCMF::getInstance()->attachGlobalListener(new GlobalEventsHook());
    }

    public static function getInstance(){
        if ( self::$_instance === null ){
            self::$_instance = new System();
        }
        return self::$_instance;
    }

    public static function setInstance(System $instance=null){
        self::$_instance = $instance;

    }
К тому же с помощью "стека" я не обхожу эту проблему. Считай System тулкитом. С помощью "стека" я показываю как можно получить бесконечное колво реализаций парсера при том, что клиенту абсолютно пофик в каком там формате да и вообще где оно там хранится. Клиент оперирует только dsn-ом.

Сингельтон выигрывает перед глобальной переменной наглядностью. В переменной может быть все что угодно. Записывая System::getInstance() мы сразу знаем куда рыть. А $parser? Пока я не увидел array_unshift я и не подумал бы что эт массив. И вот из-за таких переменных приходится постоянно тыркаться по всему проекту в попытках выяснить - а что же там такое? А тут
PHP:
System::getInstance()->getConfigParser()
смотрим прототип метода (в крайнем случае на возвращаемое значение) и сразу понимаем с чем имеем дело.

и на функциях реализовать можно всё, что угодно. доказано ассемблером ^_^
С помощью ООП можно бесконечно долго сопровождать все что угодно. Доказано практикой.

PS. Я же не утверждаю, что для сайта-визитки или там каталога продуктов нужно обязательно использовать ООП. Ложка к обеду хороша.
 

dark-demon

d(^-^)b
> С помощью ООП можно бесконечно долго сопровождать все что угодно.

это миф. если, конечно, под "сопровождением" не понимается только лишь латание дыр.


> Пока я не увидел array_unshift я и не подумал бы что этo массив.

ну назови его "parser_array".


> system::getInstance()->getConfigParser()
> смотрим прототип метода (в крайнем случае на возвращаемое значение) и сразу понимаем с чем имеем дело.

$system->config_parser[ 0 ]
смотрим на код (в крайнем случае на полученное значение) и сразу понимаем с чем имеем дело.

-~{}~ 07.11.07 22:59:

> Это ОДНА статическая связка, которую НИКОГДА не надо подменять, надо менять СОДЕРЖИМОЕ. Надеюсь с капсом понятнее.

имя глобальной переменной тоже не надо менять - менять надо содержимое. надеюсь без капса понятно?


> registry::instance->set('primary_db', $new_value);
> Мы делаем это ЯВНО.

$registry->push( 'primary_db', $new_value );
мы делаем это неявно?


> отсутствие контроля над модификациями (хрен найдешь место, где кто-то изменил содержимое переменной)

проблема высосана из пальца.

> возможный конфликт с локальными переменными

эт ты сейчас о каком языке? ^_^ одна из отличительных особенностей пыха - отсутствие конфликтов между локальным и родительским контекстом.
 

Nelius

кипарис во дворе
Люди, человеки, программеры!))))
Топик то о5 сводится к вечному спору ООП vs НЕ ООП кодинг)
Это ведь ни к чему не приведет! Супер гуру этого форума уже просто не обращают внимание тихо сидят в сторонке и хихикают...
И ведь не для кого давно не секрет что не стоит забивать гвозди микроскопом и наоборот...

Опомнитесь!) Топик стартер уже наверное в шоке от прочитанного а он ведь всего-лишь хотел понять...

P.S. Да простят меня админы и модеры, за мой крик души...
 

jonjonson

Охренеть
Nelius, я как-то забил гвоздь настоящим микроскопом. Ничего страшного, просто было не очень удобно. (Я серьёзно.)

Те кому же нужно помериться, всё одно померятся... ;)
 

cDLEON

Онанист РНРСlub
имя глобальной переменной тоже не надо менять - менять надо содержимое. надеюсь без капса понятно?
А вы сами то пробывали править код, в котором идёт работа с глобалами? Когда ни хрена не понятно, занята эта переменная, не занята, когда не известно откуда эта переменная инициализируется и что она из себя представляет?
 

dark-demon

d(^-^)b
cDLEON, А вы сами то пробывали править код, в котором идёт работа с синглетонами? Когда ни хрена не понятно, занято это имя класса, не занято, когда не известно откуда этот класс получил свой инстанс и что он из себя представляет? :)
описанная тобой проблема - это проблема незнания архитектуры приложения, а не проблема глобалов.
но она решаема - покопавшись в коде можно понять принципы его организации. а вот проблема посерьёзней: начитавшись Фаулера многие разработчики начинают лепить все (точнее только те, что поняли, остальные - игнорируются) паттерны подряд куда только можно. в итоге получается архитектура в хитросплетении которой сам чёрт ногу сломит.

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

$arr1= new Array;
echo $arr1->adds( array( 'abc', 'def', 'ghi' ) )->drop( 'def' )->join( ',' );
 

korchasa

LIMB infected
>имя глобальной переменной тоже не надо менять - менять надо содержимое. надеюсь без капса понятно?
К чему это заявление, если в предыдущем посте я пытался до вас донести, что синглтон должен быть один, а не что он круче, чем GLOBALS. Вы этого до сих пор не поняли, судя по:
А вы сами то пробывали править код, в котором идёт работа с синглетонами? Когда ни хрена не понятно, занято это имя класса, не занято, когда не известно откуда этот класс получил свой инстанс и что он из себя представляет?
Насчет "откуда получил свой инстанс ищеться просто, например, поиском по коду ;)
описанная тобой проблема - это проблема незнания архитектуры приложения, а не проблема глобалов.
Если бы все программисты писали:
PHP:
if('someConstant' = $someValue)
А не
PHP:
if($someValue = 'someConstant')
тогда я бы с вами согласился. А пока есть "случайные" присваивания...

>$registry->push( 'primary_db', $new_value );
>мы делаем это неявно?
PHP:
globals $parser;
//хотя бы 10 строчек кода
$aaa = $parser;
Это тоже явно?

>эт ты сейчас о каком языке? ^_^ одна из отличительных особенностей пыха - отсутствие конфликтов между локальным и родительским контекстом.
Если программист не забудет посмотреть "вверх", и проверить незанято ли имя.

ЗЫ: Спор действительно стал похож на замеры длины, хотя я не говорил, что registry круче, а просто пытался показать, что у GLOBALS есть недостатки. Но как это у dark-demon бывает, он категорически не видит минусов в том, что использует (или готовится использовать).
 

whirlwind

TDD infected, paranoid
> С помощью ООП можно бесконечно долго сопровождать все что угодно.

это миф. если, конечно, под "сопровождением" не понимается только лишь латание дыр.
[offtop]
Да ваще, полеты в космос - это миф, потому что я не умею рулить ракетой.
[/offtop]
 

iceman

говнокодер
да, кончайте спорить...
тема была создана для одного, чтобы понять как программировать с ООП...

модераторы, пожалуйста НЕ закрывайте, у меня возникают вопросы и не понятности с ООП, которые буду постить в эту тему... как соберусь с мыслями, задам...
 

dark-demon

d(^-^)b
> Если бы все программисты писали:
> if('someConstant' = $someValue)

то ничего не изменилось бы. ибо от ( $someValue1 = $someValue2 ) это не спасает
а спасает более простая хитрость:
if( $someValue1= $someValue2 )
if( $someValue1 == $someValue2 )
когда привыкнешь, что сравнение симметрично, а присваивание - ассиметрично, такой код( $someValue1 = $someValue2 ) будет бросаться в глаза.

> А пока есть "случайные" присваивания...

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


> globals $parser;
> //хотя бы 10 строчек кода
> $aaa = $parser;
> Это тоже явно?

ну и с какой целью мы переименовываем переменную? любишь же ты шаманства...


> Если программист не забудет посмотреть "вверх", и проверить незанято ли имя.

а может ты перед тем как сказать очередную глупость возьмёшь да попробуешь?


iceman, не нужно бояться создавать новые темы по новым вопросам.
 

whirlwind

TDD infected, paranoid
когда не известно откуда этот класс получил свой инстанс и что он из себя представляет?
dark-demon походу ты самого основного не понимаешь. Для пользователя класса не важно что представляет тот или иной инстанс. Важно что нужный инстанс имплементирует требуемый интерфейс.

PS. Насчет знания архитектуры... Вот ты скажи, что бы почистить карбюратор или поменять колеса тебе обязательно нужно учитывать архитектуру всего автомобиля? Классы позволяют абстрагироваться до определенного уровня, что значительно облегчает восприятие, в отличие от километровых процедурных портянок в больших проектах.
 

Nelius

кипарис во дворе
Решил не создавать новой темы а написать в эту...
3 дня уже парюсь перебирая и реализовывая разные способы использования объектов внутри других классов.
Может подскажете, а то всю голову сломал уже, от текстов пухнет голова...
Казалось бы можно просто использовать
PHP:
public function ccc () {
global $db;
$db->query();
....
но как-то оно не кошерно)))
Я себе представляю это как некий "Registry" в котором регистрируются все созданные объекты...
а потом что-то типа:
PHP:
public function ccc () {
$db = registry::get('MySQL');
$db->query();
....
Но вот с реаллизацией этого "Registry" я чет торможу...

Возможно я несу бред из-за недопонимания... пинайте меня за это, я только за)

-~{}~ 14.11.07 02:07:

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

-~{}~ 14.11.07 04:57:

Точно разобрался) 3 дня чтения/втыкания/кодинга не прошли даром, вопрос снят, прошу прощения что побеспокоил)
 

dark-demon

d(^-^)b
> Вот ты скажи, что бы почистить карбюратор или поменять колеса тебе обязательно нужно учитывать архитектуру всего автомобиля?

да, представь себе, нужно иметь хотябы общее представление об архитектуре.

в частности, я не понимаю:
- что такое карбюратор
- где его искать
- зачем его чистить
- как его чистить

с колёсами наверно несколько проще, хотя и не уверен, что сделаю это правильно.


> Классы позволяют абстрагироваться до определенного уровня, что значительно облегчает восприятие,
> в отличие от километровых процедурных портянок в больших проектах.

эт ты с кем сейчас разговариваешь?
 
Сверху