Почему параметры конфигурации допустимы в PHP и Javascript?

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

Есть ли какое-то обоснование, не требующее кратких сигнатур методов?

Я вижу в этом преимущество: API может оставаться неизменным по мере добавления новых дополнительных параметров. Но Javascript и PHP уже допускают дополнительные параметры в своих сигнатурах метода. Во всяком случае, похоже, что Java или другой язык OO выиграют от этого больше... и все же я редко вижу этот шаблон там.

Что дает?

Ответ 1

Основная причина заключается в том, что эти конкретные языки просто не поддерживают множественные соглашения о вызовах для одного и того же имени функции. И.Е. вы не можете сделать следующее:

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})

Ответ 2

По моему мнению, многие из этих функций поднимаются в количестве аргументов, которые они принимают, более 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' 
});

?

Ответ 3

Есть несколько причин для этого.

Во-первых, не все списки аргументов имеют естественный порядок. Если есть прецедент для подачи только 1-го и 6-го аргументов, теперь вы должны заполнить четыре заполнителя по умолчанию. Джадж хорошо иллюстрирует это.

Во-вторых, очень сложно запомнить порядок, в котором должны содержаться аргументы. Если вы принимаете серию чисел в качестве своих аргументов, вряд ли можно узнать, какое число означает что. Возьмем imagecopyresampled($dest, $src, 0, 10, 0, 20, 100, 50, 30, 80) в качестве примера. В этом случае массив конфигурации действует как аргументы Python с именем.

Ответ 4

Ruby также следует этой методологии и даже разработал более сжатый синтаксис, специально предназначенный для использования хешей в качестве инициализаторов, начиная с Ruby 1.9:

# old syntax
myFunc(:user => 'john', :password => 'password');

# new syntax
myFunc(user: 'john', password: 'password');

Проблема заключается в том, что на этих языках невозможно перегрузить функции на основе типа аргумента. Это приводит к сложным классам с одним конструктором, который может иметь огромный и громоздкий список аргументов. Использование хэш-подобных объектов для подачи параметров допускает некоторую псевдоперегрузку по имени параметра, а не по типу.

Моя единственная реальная проблема с этой практикой - трудно документировать ваши аргументы: PHPDoc для массивов аргументов переменной длины

Ответ 5

Одна из самых важных причин, почему вы не видите этого на других языках OO, состоит в том, что вы, вероятно, ссылаетесь на скомпилированные языки, такие как С++ или Java.

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

Ответ 6

Прежде всего, такая техника очень проста для кодировщиков.

Им не нужно запоминать порядок всех параметров всех функций вашего приложения. Код становится более читабельным и более надежным.

Любые будущие разработки, улучшения или рефакторинг не будут столь сложными. Код становится более удобным.

Но есть некоторые подводные камни. Например, не каждая среда IDE даст вам простой код, дополняющий такие функции и их параметры.

Ответ 7

На мой взгляд, есть две причины, почему это сложилось:

  • Массив очень легко создавать и манипулировать, даже со смешанными типами.
  • PHP/JS-программисты часто имеют неакадемический опыт и менее индоктринированы из таких языков, как Java и С++.