Как называется подход в ООП?

  • Автор темы Светлана PHP
  • Дата начала

_RVK_

Новичок
fixxxer
проблем нет, согласен. Да вот это плохо, что приходится модифицировать не только класс, но и код с ним работающий. Не соблюдаются принципы обратной совместимости что не есть гуд.
Screjet
public для методов. кажется в SmalTalk (поправте если не прав) все переменные экземпляра закрыты

-~{}~ 28.03.05 14:06:

Frol
я с самого начала аргументировал свои слова. ты и neko нет.
 

Frol

Новичок
это была аргументация?
спасибо, вопросов больше не имею.
 

_RVK_

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

-~{}~ 28.03.05 14:20:

вообще неплохо, имхо, get/set реализовано в делфи, где в интерфейсе класса можно указать методы, выполняющиеся при доступе к свойству. тут уже не важно открыто или закрыто свойство. Вы всегда сможете изменить поведение не меняя интерфейса.
 

Screjet

Новичок
_RVK_
Да, а еще там нравится read/write access.
Делается это для того, что бы если в будующих версиях класса, тебе вдруг нужно будет что-то делать при установке свойства, ты легко мог это сделать не меняя интерфейса класса
Это типа
PHP:
...
private $allow_method = array(
  'get' => array('A','B','C','D'),
  'set' => array('A','B')
);

public function __call( $m, $a ){
  list($method,$prop) = explode('_',$m);
  if ( isset($this->allow_method[$method]) ){
    $args = array_flip($this->allow_method[$method]));
    if ( !isset($args[$prop]) ){
      //trigger_error("Cannot $method for $prop");
    }
  } else {
   //trigger_error('Method not allowed..
  }
  // ...
}
типа этого?
 

_RVK_

Новичок
Screjet
Ну не знаю... лично у меня все проще. Тот же __call:
PHP:
    function __call($name, $params) {
        $ClassVars = get_class_vars(get_class($this));
        if (array_key_exists($name,$ClassVars)) {
            return (count($params)) ? $this->$name = $params[0] : $this->$name;
        } else {
            return self::RaseError('Вызван несуществующий метод '.get_class($this).'::'.$name);
        }
    }
в пхп4 приходилось писать по методу на свойство.
 

Screjet

Новичок
Подожди.., а польза от этого какая?
Верно же замечено, что должна быть какаято польза?
 

_RVK_

Новичок
Польза в том что мне ненужно для каждого свойства писать еще и метод.
PHP:
print $obj->count();
$obj->count(10);
выведут и установят $count если даже нет метода count(). Когда мне в будующих версиях нужно будет посчитать totalCount перед установкой, или проверить count на допустимый диапазон я просто добавлю count() и буду делать это, не изменив интерфейса класса.
 

Screjet

Новичок
По моемому нужно просто добавить метод count(). А если в _будущих_версиях_ нужен будет totalCount() то и его просто добавить. А к номеру версии добавить 0.01 :)

По моемому интерфейс может/должен меняться от версии к версии. Главный плюс = это видят остальные разработчики в группе и ненужно особо напрягаться с документированием.
И еще вопрос: разве может быть в "правильном" объекте более 5-10 таких "публичных" свойств?
 

_RVK_

Новичок
Screjet
ты не понял. Например:
PHP:
<?php
//версия 1
class counter {
    var $count;
    var $price;
    
    function calc() {
        return $this->count*$this->price;
    }
}

//код работающий
$counter->count = 10;
$counter->price = 3.60;
$res = $counter->calc();
print $res;

//версия 2
class counter {
    var $count;
    var $price;
    
    function count($count) {
        if ($count>5) exit('Вам нельзя купить больше 5 мадагаскарских тараканов');
        return $this->count = $count;
    }

    function price($price) {
        if ($price<5) exit('Мадагаскарские тараканы не стоят менее 5$');
        return $this->price = $price;
    }

    function calc() {
        return $this->count*$this->price;
    }
}


$counter = new counter();
//Тот же код, но с класом версии 2 он будет работать не так как задуманно
$counter->count = 10;
$counter->price = 3.60;
$res = $counter->calc();
print $res;

//Его придется переписать
$counter->count(10);
$counter->price(3.60);
$res = $counter->calc();
print $res;

//Если бы мы сразу писали так, ничего переписывать бы не пришлось.
class counter {
    
    //**** protected ******
    var $count;
    var $price;
    
    //**** public *****
    function count($count=false) {
        return ($count===false) ? $this->count : $this->count = $count;
    }

    function price($price=false) {
        return ($price===false) ? $this->price : $this->price = $price;
    }

    function calc() {
        return $this->count*$this->price;
    }
}

?>
-~{}~ 28.03.05 15:56:

вот для того что бы не писать 2 метода count() и price() (в версии где они пока не нужны), но не работать со свойствами напрямую в пхп5 и есть метод __call
 

Screjet

Новичок
По сути это разные объекты: поведение различно.
Тут как раз было бы уместно наследование, если первая версия имеет право на жизнь.
 

_RVK_

Новичок
в том то и дело что не имеет. Это версии одного и того же класса. Наследуй не наследуй, а весь код, написанный для старой объектной модели придется переписывать. А что если ты пишешь framework? Представь ты выпустил новую версию, а старый код с новой версией не работает. Что о тебе скажут расстроенные пользователи, которые жаждят использовать новые фичи, но не хотят переписывать весь уже написанный под старую версию код?

-~{}~ 28.03.05 16:20:

Да, и тот пример что я привел это лишь пример. Бывают случаи и похуже, вплоть до полной несовместимости. И люди, пишушие здесь, что это все лишнее, либо имеют плохое представление об ооп, либо гении, умеющие продумать все свои ООП проекты вплоть до последней версии. Я человек скромный, потому предпочитаю перестраховаться.
 

fixxxer

К.О.
Партнер клуба
public $var при необходимости несложно заменить на private $_var и соответствующие get/set-ы :)
 

Screjet

Новичок
Что о тебе скажут расстроенные пользователи, которые жаждят использовать новые фичи, но не хотят переписывать весь уже написанный под старую версию код?
Вот это правильный вопрос. Обратная совместимость должна быть в любом случае. Хотят использовать новые фитчи, точно также расширяют/дополняют собственные модули. Не есть правильно, если ты будешь за них это делать. Поведение не должно меняться.
 

_RVK_

Новичок
fixxxer
а если старый код юзал $var? Он не будет работать. Еще раз повторяю пример простой. Есть ситуации покруче. В лучшем случае тебе придется писать заплатки для поддержки старого кода, и старый код не сможе использовать фич новой версии. Лучше стразу программировать правильно. Лень великая сила, но я себя давно приучил что есть вещи где оне не двигатель проресса а наоборот. :)

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

_RVK_

Новичок
Поведение не должно меняться
Именно поэтому интерфейс может только дополняться, но не должен изменяться. У меня в коде константы это для примера. Представь что там переменные
PHP:
$counter->count($_GET['count']); 
$counter->price($_GET['price']);
и все станет на свои места. Поведение не меняется. Зато ползователь знает об ошибке уже на стадии установки, а не во время вычисления. Это фича, для удобства юзера, которой небыло в старой версии. Для того что бы воспользоваться ей, тебе придется всего лишь обновить класс. Если же ты изменяешь свойства напрямую тебе придется еще и переписать код.

-~{}~ 28.03.05 16:55:

Tonn
Твоими бы устами.... да по одному месту :)

Почитай об итерационном методе разработки. Твой "водопадный" уж давно устарел.
 

Screjet

Новичок
проектирование, мягко говоря, неочень..
Есть валидаторы, которые проверяют входные данные, и фильтруют/выдают строго-типизированные данные. Просто должны меняться настройки валидатора.
Это фича, для удобства юзера
вот это очень спорное утверждение.. В первую очередь удобство = это стабильность. А функционал = это уже второстепенно.
 

Vasya

Guest
И люди, пишушие здесь, что это все лишнее, либо имеют плохое представление об ооп, либо гении, умеющие продумать все свои ООП проекты вплоть до последней версии. Я человек скромный, потому предпочитаю перестраховаться.
Это, видимо, ко мне относится? :)
Ключевое слово на этот раз "перестраховаться".
Интерфейс (API) вашей системы может расширяться от версии к версии. Сам этот интерфейс -- это, грубо говоря, контракт, который расширяется, но не отменяет действия предыдущих версий.
Ваш подход характерен тем, что вы пытаетесь впихнуть в контракт "всё, что может понадобиться". В результате, обычно, "надобится" именно то, чего нет в контракте :)
Поэтому этот публичный интерфейс (API) должен быть хорошо спроектирован, продуман, а не сделан по вышеописанному шаблону "впихну всё, что в голову может быть когда-нибудь взбредет".
С другой стороны, есть код, который не доступен извне, внутренняя, скрытая реализация. Этот код не влияет на API и поэтому вы можете менять его как угодно. Тотальное использование геттероф/сеттероф, в этом случае, похоже на подписывание контракта с самим собой, что выглядит довольно странно, хотя и оправдано, если вы плохо представляете себе последствия своих действий.
 

_RVK_

Новичок
Screjet
ЁПРСТ! Ты хотел чтоб я тебе за 5 мин накидал пример с валидаторами? :)
Попробуй отнестить к этому коду как к примеру. Не ужели не хватает фантазии.

Кстати, то что я вам сейчас рассказываю написанно толь у Буча то ли у Страуструпа, то ли у кого то из других класиков ООП.
 
Сверху