Если установлено расширение mbstring и включена перегрузка mbstring , то использование substr
может вызвать проблемы. Перегрузка Mbstring вызовет автоматический вызов mb_substr
при каждом вызове substr
(если установлена mbstring, а перегрузка mbstring отключена , тогда substr
будет правильно извлекать байты). Следующий код будет использовать mb_substr
, если mbstring установлен, и substr
, если он не установлен. Используется 8-битная кодировка символов, которая обрабатывает каждый символ как 1 байт и игнорирует нулевые терминаторы ('\ 0').
if (function_exists('mb_substr')) {
$bytes = mb_substr($string, 0, 8, '8bit');
} else {
$bytes = substr($string, 0, 8);
}
Проблема в том, как вы выбираете способ описания «принадлежности собственности».
Большинство приведенных вами примеров можно сопоставить с другими упомянутыми вами категориями.
Просто несколько, например:
HasListener => реализует Listenable
ContainsChildren => реализует Parent
WithDescription => реализует Descriptable
] Постарайтесь придерживаться более традиционных схем именования, желательно таких, которые описывают ваш объект наилучшим и более читаемым образом.
Также убедитесь, что вы не чрезмерно интерфейсов ваших классов с бесполезными интерфейсами. Сделайте его кратким и конкретным, иначе разработчики, читающие ваш код, очень быстро заблудятся.
Я думаю, что на некоторые из проблемных случаев, которые вы обрисовываете, ответ можно найти «с другой стороны»:
HasListener -> Speaker
LinksToRoot, HasParent -> Child (or perhaps Node)
ContainsChildren -> Parent
Конечно, разные случаи будут более или менее очевидными .
Я согласен, что эти названия интерфейсов кажутся мне ужасными. «HasListener» больше похож на вызов метода, который должен возвращать логическое значение, чем на имя интерфейса.
Не должно существовать интерфейсов для хранения / хранения свойств класса. Их следует использовать для обозначения отношений, которым должны следовать все классы, реализующие их. Я лично придерживаюсь отношения «это есть». Если есть прямая связь, то есть кошка "является (n)" животным, то я создам для нее интерфейс и назову его "Животное", дав ему подходящее имя.
Мне было бы действительно интересно узнать, что за " Описание интерфейса HasListener. Что именно он делает? Почему можно
Я думаю, что вы можете взять часть того, что вы делаете, и превратить их в интерфейсы типа "профессии":
HasListener
-> ListenerContainer
WithDescription
-> DescriptionContainer
( Describable
также может работать, в зависимости от того, что именно «описание» является в данном контексте) Похоже, что во многих других ваших интерфейсах что-то есть делать с древовидной структурой. Я бы предложил назвать их в соответствии с их функциями в дереве.
ContainsChildren
-> Parent
или Collection
BelongsToParent
-> Child
Что касается других, мне нужно больше узнать о том, для чего конкретно предназначены эти интерфейсы. Некоторые из них, например Named
, вероятно, названы очень хорошо.
Мне очень нравится подход "IHasListener".
В .NET Framework вы найдете это в таких интерфейсах, как:
Имена типа «Listenable» предполагают, что реализация прослушивает, а не содержит слушателя. IHasListener четко говорит, что он делает.
HasListener в порядке, как и Listenable . Я не имею ничего против этого.
Но IHasListener ужасен: во-первых, потому что нам не нужен префикс I, чтобы сказать, что это интерфейс (посмотрите на подпись класса!) И во-вторых, потому что это звучит как «Я не говорю по-английски».
Единственным интерфейсом в Java, который я создал с префиксом I, был IRule . :)