На большинстве других Объектно-ориентированных языков. это было бы кощунство, чтобы иметь каждую функцию, получают единственный ассоциативный массив Объектов вместо того, чтобы перечислить каждого в сигнатуре метода. Почему, хотя, действительно ли это является приемлемым и наиболее часто используемым в большинстве популярных платформ для обоих из этих языков, чтобы сделать это?
Есть ли некоторое выравнивание вне желания иметь краткие сигнатуры методов?
Я действительно вижу преимущество в этом - что API мог остаться неизменным, поскольку добавляются новые, дополнительные параметры. Но JavaScript и PHP уже допускают дополнительные параметры в их сигнатурах методов. В любом случае это походит на Java, или другой язык OO извлек бы выгоду из этого больше..., и все же я редко вижу этот шаблон там.
Что дает?
Основная причина в том, что эти конкретные языки просто не поддерживают использование нескольких соглашений о вызовах для одного и того же имени функции. I.E. вы не можете делать следующее:
public function someFunc(SomeClass $some);
public function someFunc(AnotherClass $another);
public function someFunc(SomeClass $some, AnotherClass $another);
Итак, вы должны найти другой способ создать более простые способы передачи ваших переменных, в PHP мы получаем someFunc (array ('some' => $ some, 'another '=> $ another))
, потому что это единственный удобный способ. В JavaScript мы в конечном итоге используем объекты, что не так уж плохо: someFunc ({some: something, another: anotherthing})
не выполняется никаких вызовов System.exit (). На мой взгляд, количество принимаемых аргументов у многих этих функций растет. , старше 10 - не редкость. Даже если вы укажете необязательные параметры, вам все равно придется отправлять их по порядку.
Рассмотрим функцию вроде:
function myFunc(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13){
//...
}
Допустим, вы хотите использовать только аргументы 3 и 11. Вот ваш код:
myFunc(null, null, null, 'hello', null, null, null, null, null, null, null, 'world');
Вы бы предпочли просто:
myFunc({
a3 : 'hello',
a11 : 'world'
});
?
Там есть пара причин для этого.
Во-первых, не все списки аргументов имеют естественный порядок. Если есть вариант использования для предоставления только 1-го и 6-го аргументов, теперь вам нужно заполнить четыре заполнителя по умолчанию. Джейдж хорошо это иллюстрирует.
Во-вторых, очень трудно запомнить порядок, в котором должны располагаться аргументы. Если вы возьмете ряд чисел в качестве аргументов, вряд ли вы узнаете, какое число что означает. В качестве примера возьмем imagecopyresampled ($ dest, $ src, 0, 10, 0, 20, 100, 50, 30, 80)
. В этом случае массив конфигурации действует как именованные аргументы Python.
Ruby также следует этой методологии и даже разработал более лаконичный синтаксис, специально предназначенный для использования хэшей в качестве инициализаторов, начиная с Ruby 1.9:
# old syntax
myFunc(:user => 'john', :password => 'password');
# new syntax
myFunc(user: 'john', password: 'password');
Решаемая проблема заключается в том, что в этих языках нельзя перегружать функции в зависимости от типа аргумента. В результате получаются сложные классы с одним конструктором, который может иметь огромный и громоздкий список аргументов. Использование хеш-подобных объектов для предоставления параметров допускает своего рода псевдоперегрузку по имени параметра, а не по типу.
Моя единственная реальная проблема с этой практикой заключается в том, что становится трудно задокументировать ваши аргументы: PHPDoc для массивов аргументов переменной длины
Одна из наиболее важных причин, почему вы не видите этого в других объектно-ориентированных языках, заключается в том, что вы, вероятно, имеете в виду скомпилированные языки, такие как C ++ или Java.
Компилятор отвечает за определение, во время компиляции, а не во время выполнения, какой метод вы хотите вызвать, и это обычно делается на основе сигнатуры, поэтому в основном это должно быть сделано именно так. Таким же образом выполняется перегрузка методов на этих языках.
На мой взгляд, это произошло по 2 причинам:
Во-первых, такая техника очень проста для кодеров.
Им не нужно запоминать порядок всех параметров всех функций в вашем приложении. Код становится более читабельным и надежным.
Предусмотреть любые будущие разработки, улучшения или рефакторинг не так уж и сложно. Код становится более удобным в обслуживании.
Но есть и подводные камни. Например, не каждая IDE предоставит вам простой код с такими функциями и их параметрами.