В последнее время я привык назначать целочисленные значения константам и просто использовать константное имя в качестве средства определения его цели. Однако в некоторых случаях это привело к необходимости писать такую функцию, как typeToString ($ const), когда требуется представление строки. Очевидно, что это неэффективно и ненужно, но это проблема только раз и навсегда.
Итак, мой вопрос: есть ли какие-либо другие компромиссы, которые я должен рассмотреть? Какой случай считается более чистым / более стандартным? Кроме того, разница производительности в большинстве случаев небрежна?
Случай 1: (быстрее, когда строковая версия не нужна?)
class Foo { const USER_TYPE_ADMIN = 0; const USER_TYPE_USER = 1; const USER_TYPE_GUEST = 2; public $userType = self::USER_TYPE_ADMIN; public function __construct($type) { $this->userType = $type; } public function typeToString() { switch($this->userType) { case self::USER_TYPE_ADMIN: return 'admin'; break; case self::USER_TYPE_USER: return 'user'; break; case self::USER_TYPE_GUEST: return 'guest'; break; default: return 'unknown'; break; } } } $foo = new Foo(Foo::USER_TYPE_GUEST); echo $foo->typeToString(); // Displays "guest"
Случай 2: (быстрее / проще, когда требуется строковая версия)
class Foo { const USER_TYPE_ADMIN = 'admin'; const USER_TYPE_USER = 'user'; const USER_TYPE_GUEST = 'guest'; public $userType = self::USER_TYPE_ADMIN; public function __construct($type) { $this->userType = $type; } } $foo = new Foo(Foo::USER_TYPE_GUEST); echo $foo->userType(); // Displays "guest"
Разница в производительности будет незначительной, если вы не храните много из них. Я бы написал метод toString()
более кратко:
$strings = array ( self::USER_TYPE_ADMIN => 'admin', self::USER_TYPE_USER => 'user', ); if (!isset($strings[$type])) return 'unknown'; return $strings[$type];
Кроме того, вы можете сделать массив $strings
static
.
Я буду честен, я не знаю, есть ли «удар» любого вида, когда вы определяете свои константы изначально как строки, – но если есть один, я готов поспорить, что он настолько мал, что это будет трудно измерить.
Лично, если значение константы имеет смысл как литерал, тогда просто присвойте ему это значение. Если значение константы имеет смысл только в качестве селектора параметров (или какого-либо другого знака значения), тогда используйте целые числа или все, что вы выберете.
Я думаю, что строковые константы – лучший выбор в этом случае. Код выглядит лучше.
Конечно, если вам нужен последний бит производительности, используйте целочисленные константы. Но только после того, как вы проверите с профилировщиком, что сравнение строк является узким местом. Во всяком случае, в большинстве приложений есть много более дорогих вещей, таких как доступ к базе данных и т. Д.
Вместо использования константных целых чисел я обычно просто перебираю строки, если мне нужно их распечатать. Поэтому я бы сделал что-то вроде $foo = new Foo('guest');
, Я все еще могу проверить вход в конструкторе, и я могу пометить его, когда мне это нужно.
В примере, который вы пишете, вы можете удалить все методы и сделать класс статичным, и вы создали бы свой счет Enumerator. Как это:
class Enumeration { public static const One = 1; public static const Two = 2; public static const Three = 3; }
Еще один удобный способ использования констант – использовать их в качестве конфигурации приложения. Они намного быстрее работают, а затем анализируют xml-файл для конфигурации.