Абстрактный класс::вызов метода

Духовность™

Продвинутый новичок
Абстрактный класс::вызов метода

PHP:
abstract class a
{
   public static function foo(){}
}

a::foo(); // работает, это правильно с точки зрения ООП??
 

dimagolov

Новичок
а зачем тебе слово abstract? чтобы не позволить инстанцировать класс?

п.с. статика сама по себе это не ООП, так что...
 

Духовность™

Продвинутый новичок
а зачем тебе слово abstract? чтобы не позволить инстанцировать класс?
абстракт для того, что это абстракт и вызванный класс без extends не имеет никакого смысла.

В данном случае, если интересует подробности, абстракт - меппер. В меппере лежит статическая коллекция объектов. Иногда нужно из модели делаеть запрос в эту коллекцию без явного инстанцирования класса меппера. Вот я его и делаю с помощью Abstract_Mapper::findObject(....)
 

.des.

Поставил пиво кому надо ;-)
Что именно тебя смущает? Не создается никаких экземпляров класса, по сути вызывается функция a::foo.
 

Fortop

Новичок
triumvirat
В статические функции/методы должен выноситься функционал, который не зависит от текущего состояния объекта (и соответственно не требует его инстанцирования)

Т.е. если хранение коллекции - как статического свойства - еще оправдано, то метод доступа к ней быть статическим не обязан (а строго говоря и не должен)
 

Духовность™

Продвинутый новичок
Т.е. если хранение коллекции - как статического свойства - еще оправдано, то метод доступа к ней быть статическим не обязан (а строго говоря и не должен)
почему не обязан? Если свойство статическое, то зачем мне создавать объект и получать свойство через не статический метод? Зачем такие трудозатраты?
 

.des.

Поставил пиво кому надо ;-)
это работает везде. Потому что статика имеет мало отношения к ооп.
Код:
// c++
class a {
   public:
     static void foo(){ }
     virtual void f() = 0;
};
int main() {
  a::foo();
  return 0;
}
// java
public abstract class a {
  abstract void f();
  static void foo() { }
}
public class Main {
  public static void main(String [] args) {
    a.foo();
  }
}
То есть если тебе нужны статические методы в абстрактном класс - делай. Ничего страшного в этом нет.
 

Fortop

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

В текущем же случае речь идет о внутреннем кеше, который
во-первых, без существующих объектов пуст
во-вторых, не должен быть виден наружу

И смысла иметь к нему доступ "извне" - нет никакого.
Ну, а закрытый статический метод не имеет смысла вовсе (есть конечно нюансы, но не в твоем случае)
 

Lightning

Трудоголик
Как же меня бесят такие вопросы:
это правильно с точки зрения ООП?
И такие ответы:
статика сама по себе это не ООП
Извините...

По сабжу: я бы сделал чтобы мапер сам проверял, существует ли объект во внутреннем кэше. Если существует - возвращает его, если нет - делает запрос и тд... Имхо, лучше чтобы из вне не было видно кэша. Что скажешь?
 

Духовность™

Продвинутый новичок
Ребята, я не понимаю, что вы от меня хотите... у меня вот что:

PHP:
class User_Model 
{
    // Возвращает объект типа Group (группа) 
    public function getGroup()
    {
        // дайте модель Group модуля User с ид = $this->id_group
        return Base_Mapper::getCollectionObjectById('User', 'Group', $this->id_group);
    }
}
Base_Mapper - это абстракт
getCollectionObjectById сейчас вот что из себя представляет:

PHP:
public static function getCollectionObjectById($module_name, $model_name, $id)
{
    $module_name = ucfirst($module_name);
    $model_name = ucfirst($model_name);

    if (!isset(self::$collection[$module_name][$model_name][$id]))
    {
        $mapper_name = 'Module_'.$module_name.'_Mapper_'.$model_name;

        $mapper = new $mapper_name();
        $object = $mapper->findById($id);

        // в БД есть этот "объект"
        if ($object->id)
        {
            // добавляем в коллекцию и возвращаем
            return self::$collection[$module_name][$model_name][$id] = $object;
        }
        else
        {
            // ничего не найдено в БД - возвращаем пустой объект заданного типа
            return $object;
        }
    }

    // возвращаем то, что в коллекции
    return self::$collection[$module_name][$model_name][$id];
}
 

Духовность™

Продвинутый новичок
Ну почему он абстракт, а им пользуются, но от него не наследуются?
Всё наследуется и User_Mapper extends Base_Mapper - так и есть, да.

Просто getCollectionObjectById у меня ста-ти-чес-кий и я не инстанцирую в данном коде явно меппер User_Mapper:

PHP:
class User_Model 
{
    // Возвращает объект типа Group (группа) 
    public function getGroup()
    {
        // дайте модель Group модуля User с ид = $this->id_group
        return Base_Mapper::getCollectionObjectById('User', 'Group', $this->id_group);
    }
}
раньше, до использования кэша объектов, это сделал бы получение объекта "группа" явно с помощью User_Mapper:

PHP:
class User_Model 
{
    // Возвращает объект типа Group (группа) 
    public function getGroup()
    {
         $mapper = new User_Mapper();
         return $mapper->findGroupById( $this->id_group );
    }
}
 

Fortop

Новичок
Просто getCollectionObjectById у меня ста-ти-чес-кий и я
ПОЧЕМУ?

неинстанцирую в данном коде явно меппер User_Mapper
ВТОРОЕ ПОЧЕМУ?

И т..д.

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

-~{}~ 31.03.10 00:16:

раньше я бы, до использования кэша объектов, это сделал бы так, явно с помощью User_Mapper:
Вот так и надо делать.

А проверка кеша должна быть в этом методе
findGroupById

Остальным объектам/моделям должно быть глубоко фиолетово наличие кеша и всего остального. Они всего лишь должны хотеть получить объект.
 

Духовность™

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

ВТОРОЕ ПОЧЕМУ?
а зачем его инстанцировать, если getCollectionObjectById привязан к хранилищу класса, а не объекта. Он обращается к статическому свойству. Для статического свойства есть статический метод.

Почему какая-то левая модель лезет в кеш за другой моделью?
Модель User лезет в кэш за моделью Group, что в этом такого?

-~{}~ 31.03.10 01:22:

Вот так и надо делать.

А проверка кеша должна быть в этом методе
findGroupById
ща попробую
 

Fortop

Новичок
Для статического свойства есть статический метод.
Омг.

Модель User лезет в кэш за моделью Group, что в этом такого?
Это жопа.
Пришел ты в кассу и пошел сам брать деньги со счета мужа/жены, минуя кассира, бухгалтера, операциониста.

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

crocodile2u

http://vbolshov.org.ru
И еще кусок офтопика. Лучше избегать такого, чтобы в одном методе соседствовали имена типа $module_name и $model_name. Они слишком похожи и есть вероятность их перепутать.
 
Сверху