После изучения языка программирования, его синтаксиса, приходит вопрос: какой парадигмы придерживаться? На самом деле нет(в большинстве случаев). Парадигма программирования это архитектура кода, следование одной из них необходимо, чтоб другой разработчик мог быстрее понять как ваша прога работает. Почему-же этот выбор, за частую, сделан за вас? все просто: если это не одноразовый скриптик, а часть какой-то программы, писать его нужно будет в том же архитектурном стиле, что и предыдущий код(нынче программы редко пишутся с нуля). Итак, рассмотрим 3 парадигмы: процедурное, функциональное и объектно-ориентированное программирование.
И еще, для того чтоб было более наглядно – приведу код. Код будет выполнять недавнее мое тестовое задание – вот и само задание:
<?php /* Implement Mankind class, which works with Person instances. General requirements: - there can only exist a single instance of the class (Martians are not mankind...) - allow to use the instance as array (use person IDs as array keys) and allow to loop through the instance via foreach Required operations: - Load people from the file (see below) - Get the Person based on ID - get the percentage of Men in Mankind Loading people from the file: Input file is in CSV format. Each person is in separate line. Each line contains ID of the person, name, surname, sex (M/F) and birth date in format dd.mm.yyyy. Attributes are separated by semicolon (;) File is using UTF8 encoding. Example: 123;Michal;Walker;M;01.11.1962 3457;Pavla;Nowak;F;13.04.1887 */
Для тех, кто слаб в английский(таких, как я) – простыми словами:
Создать класс Mankind, работающий с классом Person и делающий следующее:
- читает xml-строку указанного формата и извлекает из нее данные о персонах;
- уметь выдавать данные по отдельной персоне;
- рассчитать процентное содержание мужчин среди населения;
- представить население в виде массива персон.
там еще есть требования к классам, но их опущу(в рамках этой статьи).
Процедурное программирование
Определение с Википедии “Процедурное программирование — программирование на императивном языке, при котором последовательно выполняемые операторы можно собрать в подпрограммы, то есть более крупные целостные единицы кода, с помощью механизмов самого языка”. К определению добавить нечего…
Теперь к сути, а суть такая – это просто текст кода(то, как программирует большинство при изучении ЯП). Функционал моего тестового задания, в процедурном стиле будет выглядеть так:
<?php $persons = []; $maleCount = 0; // открытие файла для чтения $resource = fopen($filePath, 'r');; // построчное чтение while ($line = fgets($resource)) { // разбиение строки в массив $personData = str_getcsv($line, ';'); // формирование массива персон $persons[$personData[0]] = [ 'id' => $personData[0], 'name' => $personData[1], 'second_name' => $personData[2], 'sex' => $personData[3], 'birthday' => $personData[4] ]; // считаем мужчинн if ($personData[3] === 'M') { $maleCount++; } } // получаем персону $person123 = $persons[123]; // получим % мужчин $genderStats = $maleCount * 100 / count($persons);
Функциональный стиль программирования
Все та же википедия(в иных источниках определение такое же): “Функциональное программирование – парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних”. Для большего понимания, моими словами(ну может так все его объясняют) – программирование, при котором результат работы первой функции является входным параметром следующей.
Код моей программки, переписанный в этом стиле, будет таким
<?php $persons = []; $maleCount = 0; // открытие файла для чтения $resource = fopen($filePath, 'r');; // чтение файла в массив строк $lines = file($filePath); // обработка каждой строкм ф-ей parser $persons = array_map('parser', $lines); // получаем персону $person123 = getPeron(123, $persons); // получим % мужчин $maleStats = getMaleStats($persons); function parser($line) { $personData = str_getcsv($line, ';'); return [ 'id' => $personData[0], 'name' => $personData[1], 'second_name' => $personData[2], 'sex' => $personData[3], 'birthday' => $personData[4] ]; } function getPeron($id, $persons) { $index = array_search(['id' => $id], $persons); return $persons[$index] ?? "Персоны с этим идентификатором[{$index}] не существует"; } function getMaleStats($persons) { $count = 0; foreach ($persons as $person) { if ($person['sex'] === 'M') { $count++; } } return $count * 100 / count($persons); }
преимущества такого кода – появляется возможность пере использования кода, что приводит к возможности масштабирования приложения. Недостатком же есть увеличение времени работы скрипта(незначительное)…
Объектно-ориентированное программирование
Традиционно, начнем из определения в Вики: “Объектно-ориентированное программирование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования”. И добавить нечего… даже своими словами – все предельно четко и ясно(как по мне).
Перепишем код порги в этом стиле. сразу скажу, это ООП “курящего человека”, почему так – объясню в следующих статьях.
<?php // инициализация объекта $mankindObj = new Mankind($filePath); // поллучение массива персон $persons = $mankindObj->toArray(); // получаем персону $person123 = $mankindObj->getPersonById(123); // получим % мужчин $maleStats = $mankindObj->getMaleStats(); class Person { public int $id; public string $name; public string $secondName; public string $sex; public string $birthday; public function toArray() { return get_object_vars($this); } } class Mankind { public array $mankind; public function __construct($path) { $lines = file($path); $this->load($lines); } public function getPersonById($id) { return $this->mankind[$id] ?? "Персоны с этим идентификатором[{$id}] не существует"; } public function getMaleStats() { $count = 0; foreach ($this->mankind as $person) { if ($person->sex === 'M') { $count++; } } return $count * 100 / count($this->mankind); } public function toArray() { $mankind = []; foreach ($this->mankind as $person) { $mankind[$person->id] = $person->toArray(); } return $mankind; } protected function load($lines) { array_map([$this, 'addPerson'], $lines); } protected function addPerson($line) { $person = new Person(); $personData = str_getcsv($line, ';'); $person->id = (int)$personData[0]; $person->name = $personData[1]; $person->secondName = $personData[2]; $person->sex = $personData[3]; $person->birthday = $personData[4]; $this->mankind[(int)$personData[0]] = $person; } }
В этом стиле, несмотря на то, что код максимально длинный, все максимально понятно. Это помимо того что дает возможность масштабировать систему – так еще и делает этот процесс более понятным(при адекватном наименовании классов, методов и т.д.) и быстрым(относительно). Преимущества:
- Дополнительные пути для уникального нейминга(неймспейс, имя класса, имя метода/свойства);
- Удобное и, в принципе, возможное масштабирование.
Недостатком здесь выступает еще меньшая скорость работы, чем у функционального кода, однако оно незначительно по сравнению с достоинствами такого подхода.
Имхо
Говорят, эта тема холиварна в кругах программистов, но я, как экстра-интроверт, не в курсе и потому выскажусь. После изучения синтаксиса ЯП, переменных и др. его основ, изучите ООП(до изучения фреймворков, зная объектное вы быстрее поймете любой из них). Без него не выйдет написать ни один крупный проект да и найти работу программистом. К примеру, больше половины тех.собеседований начаты были вопросами об ООП; каждое тех.собеседование содержало о нем вопросы; единственный раз, когда меня не позвали на тех.собеседование — когда я тестовое задание выполнил в процедурно-функциональном стиле(тогда мне показалось что ООП для него излишек).