Статический класс PHP или пространство имен

Я хочу узнать мнение людей об использовании статических классов вместо пространств имен. Я родом из C++, и мне очень нравится его синтаксис и то, как он позволяет вам структурировать код. Недавно я решил, что мне нужно сгруппировать свой код в логические блоки, а не просто в файлы. Например, я предпочитаю такие вызовы, как User::login, вместо user_login. Итак, я немного погуглил и с облегчением обнаружил, что в PHP есть пространства имен. Однако мое облегчение длилось недолго, мне действительно не нравится синтаксис; это добавляет больше беспорядка в мои вызовы функций. Итак, на данный момент я использую статические классы для имитации пространств имен. Есть ли в этом недостатки?

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

Кроме того, есть ли способ избежать следующей ситуации:

class Test {
 public static void myFunc() {
  Test::myOtherFunc();
 }
 public static void myOtherFunc() {

 }
}

Я предположил, что можно было бы вызывать функции в одном классе без указания имени, но, видимо, это не так. Существуют ли какие-либо обходные пути для этого (например, в С++ есть ключевое слово using).


person user1520427    schedule 14.08.2012    source источник
comment
self:: и $this-> используются в PHP для вызова ваших собственных статических методов и методов экземпляра соответственно.   -  person Ja͢ck    schedule 14.08.2012
comment
Значит, квалификация не может быть неявной? т.е. проверить текущий класс на наличие функции?   -  person user1520427    schedule 14.08.2012
comment
Нет, но я считаю, что откровенность — это хорошо :)   -  person Ja͢ck    schedule 14.08.2012
comment
Хех, мне нравится, когда это явно между классами, но я привык к тому, что это неявно внутри класса. Ну, думаю, со временем привыкну.   -  person user1520427    schedule 14.08.2012
comment
Вы должны просто попытаться заглянуть за пределы эстетического диссонанса. Это будет гораздо полезнее, чем имитация пространств имен просто потому, что вы предпочитаете двойное двоеточие.   -  person Blake    schedule 14.08.2012


Ответы (2)


По совпадению я на самом деле двигался в прямо противоположном направлении:

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

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

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

Наконец, самоссылка в статических классах является явной, тогда как в пространствах имен она работает точно так же, как в C++: вы указываете имя функции, и оно сначала ищется в пространстве имен.

person Ja͢ck    schedule 14.08.2012
comment
Мне нравится идея пространств имен и то, как они позволяют вам управлять кодом, как вы сказали, вы можете организовать их в нескольких файлах. Моя единственная реальная проблема - неуклюжий синтаксис. Я не вижу необходимости использовать \ и удалять согласованность с другими языками. - person user1520427; 14.08.2012
comment
@user1520427 user1520427 Я знаю, как вы себя чувствуете, это не очень красиво, но подумайте об этом как о структуре каталогов, и это имеет смысл :) автозагрузчик по умолчанию фактически использует его таким же образом. - person Ja͢ck; 14.08.2012

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

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

Что касается вашего User::login() примера, это было бы плохой практикой. Вместо этого у вас должен быть реальный объект, способный содержать состояние.

$mapper = new UserMapper;
$user = new User;
$user->setNickname( $name );

$mapper->fetch( $user );

if ( $user->hasPassword( $password ) )
{
    $user->setLastLogin( time() );
}
else
{
    // log the access attempt
    // set error state
}

$mapper->save( $user );

Суть в следующем: если вы используете статические структуры (функции или методы), это не ООП. Вы просто притворяетесь. Вместо этого вы должны использовать настоящее ООП с внедрением зависимостей.

Если в вашем коде повсюду используются статические методы и переменные, это создает тесную связь между классами, добавьте global состояние и усложняет поддержку и тестирование кодовой базы. И это не специфично для PHP.

person tereško    schedule 14.08.2012