Перегрузка функций — это механизм, который позволяет двум родственным функциям иметь одинаковые имена.
Допустим
Допустим необходимо реализовать функции, которые будут вычислить объем следующих фигур:
- куб
- шар
- цилиндр
- конус
- пирамида
- прямоугольный параллелепипед
// Объем куба function Volume_Cube(/*int*/ $side) { return pow($side, 3); } // Объем шара function Volume_Sphere(/*double*/ $radius) { return ((4/3) * M_PI * pow($radius, 3)); } // Объем цилиндра function Volume_Cylinder(/*double*/ $radius, /*int*/ $height) { return (M_PI * pow($radius, 2) * $height); } // Объем конуса function Volume_Сone(/*int*/ $height, /*double*/ $radius) { return ((1/3) * M_PI * pow($radius, 2) * $height); } // Объем пирамиды function Volume_Pyramid(/*int*/ $square, /*int*/ $height) { return ((1/3) * $square * $height); } // Объем прямоугольного параллелепипеда function Volume_Cuboid(/*int*/ $length, /*int*/ $width, /*int*/ $height) { return ($length * $width * $height); }
Это делает ситуацию сложнее, чем она есть на самом деле. Другими словами, при одних и тех же действиях (вычисление объема) программисту необходимо помнить имена всех шести функций вместо одного.
PHP_Over регистрирует значение, которое может быть вызвано как функция, по заданному количеству и/или значению типа аргумента, которое должно быть перегружено в процессе вызова.
require 'src/php_over/PHP_Over.php'; $Volume = new PHP_Over; $Volume ->overload('%i', function($side) { return pow($side, 3); }) ->overload('%d', function($radius) { return ((4 / 3) * M_PI * pow($radius, 3)); }) ->overload('%d', '%i', function($radius, $height) { return (M_PI * pow($radius, 2) * $height); }) ->overload('%i', '%d', function($height, $radius) { return ((1 / 3) * M_PI * pow($radius, 2) * $height); }) ->overload('%i', '%i', function($square, $height) { return ((1 / 3) * $square * $height); }) ->overload('%i', '%i', '%i', function($length, $width, $height) { return ($length * $width * $height); }); $Volume(5); // 125 $Volume(5.); // 523.5987755983 $Volume(3., 10); // 282.74333882308 $Volume(10, 2.); // 41.887902047864 $Volume(15, 9); // 45 $Volume(15, 9, 3); // 405
Теперь достаточно знать только одно имя $Volume, а для вычисления объема требуемой фигуры необходимо указать то количество и те типы аргументов, которые требуются.
Допустим
Допустим необходимо изменить набор фигур для которых требуется вычислить объем:
куб- шар
- цилиндр
- конус
пирамида- прямоугольный параллелепипед
- правильный тетраэдр
- призма
// ... Part 1 $Volume ->override('%i', function($edge) { return (pow($edge, 3) * sqrt(2) / 12); }) ->override('%i', '%i', function($square, $height) { return ($square * $height); }); $Volume->invokeTo(5); // 14.73139127472 $Volume->invokeTo(5.); // 523.5987755983 $Volume->invokeTo(3., 10); // 282.74333882308 $Volume->invokeTo(10, 2.); // 41.887902047864 $Volume->invokeTo(15, 9); // 135 $Volume->invokeTo(15, 9, 3); // 405
Допустим
Допустим необходимо избавиться от некоторых перегружаемых функций, в процессе выполнения:
- правильный тетраэдр
шарцилиндрконус- призма
- прямоугольный параллелепипед
// ... Part 1 // ... Part 2 $Volume ->override('%i', '%d') ->override('%d', false); function wrapperToVolume() { global $Volume; try { return $Volume->invokeArgsTo(func_get_args()); } catch (Exception $exp) { return $exp->getMessage(); } } wrapperToVolume(5); // 14.73139127472 wrapperToVolume(5.); // Вызов неопределенной ранее функции wrapperToVolume(3., 10); // Вызов неопределенной ранее функции wrapperToVolume(10, 2.); // Вызов неопределенной ранее функции wrapperToVolume(15, 9); // 135 wrapperToVolume(15, 9, 3); // 405
Скорость выполнения псевдо-перегружаемой функции, само собой, оставляет за собой право желать лучшего:
require 'src/php_over/PHP_Over.php'; define('NUMBER_OF_OPERATIONS_TEST_PHP_OVER', 1000000); $array1 = array('a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red'); $array2 = array('a' => 'green', 'b' => 'yellow', 'blue', 'red'); function my_array_intersect_assoc($array1, $array2) { return array_intersect_assoc($array1, $array2); } $php_over = new PHP_Over; $php_over->overload('%a', '%a', 'my_array_intersect_assoc'); function Test_1() { global $array1, $array2; $i = 0; $t = microtime(true); while ($i++ < NUMBER_OF_OPERATIONS_TEST_PHP_OVER) { array_intersect_assoc($array1, $array2); } return (microtime(true) - $t); } function Test_2() { global $array1, $array2; $i = 0; $t = microtime(true); while ($i++ < NUMBER_OF_OPERATIONS_TEST_PHP_OVER) { my_array_intersect_assoc($array1, $array2); } return (microtime(true) - $t); } function Test_3() { global $php_over, $array1, $array2; $i = 0; $t = microtime(true); while ($i++ < NUMBER_OF_OPERATIONS_TEST_PHP_OVER) { $php_over->invokeTo($array1, $array2); } return (microtime(true) - $t); } //========================================================================== // | Count | PHP 5.3(average) | PHP 5.4(average) | PHP 5.5(average) | //========================================================================== // Test_1 | 5 | 6.56 sec | 5.86 ses | 5.69 sec | //========================================================================== // Test_2 | 5 | 11.11 sec | 10.02 sec | 9.51 sec | //========================================================================== // Test_3 | 5 | 148.6 sec | 123.6 sec | 115.4 sec | //==========================================================================
.git: PHP_Over
ссылка на оригинал статьи http://habrahabr.ru/post/211683/
Добавить комментарий