После изучения языка программирования, его синтаксиса, приходит вопрос: какой парадигмы придерживаться? На самом деле нет(в большинстве случаев). Парадигма программирования это архитектура кода, следование одной из них необходимо, чтоб другой разработчик мог быстрее понять как ваша прога работает. Почему-же этот выбор, за частую, сделан за вас? все просто: если это не одноразовый скриптик, а часть какой-то программы, писать его нужно будет в том же архитектурном стиле, что и предыдущий код(нынче программы редко пишутся с нуля). Итак, рассмотрим 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;
}
}
В этом стиле, несмотря на то, что код максимально длинный, все максимально понятно. Это помимо того что дает возможность масштабировать систему – так еще и делает этот процесс более понятным(при адекватном наименовании классов, методов и т.д.) и быстрым(относительно). Преимущества:
- Дополнительные пути для уникального нейминга(неймспейс, имя класса, имя метода/свойства);
- Удобное и, в принципе, возможное масштабирование.
Недостатком здесь выступает еще меньшая скорость работы, чем у функционального кода, однако оно незначительно по сравнению с достоинствами такого подхода.
Имхо
Говорят, эта тема холиварна в кругах программистов, но я, как экстра-интроверт, не в курсе и потому выскажусь. После изучения синтаксиса ЯП, переменных и др. его основ, изучите ООП(до изучения фреймворков, зная объектное вы быстрее поймете любой из них). Без него не выйдет написать ни один крупный проект да и найти работу программистом. К примеру, больше половины тех.собеседований начаты были вопросами об ООП; каждое тех.собеседование содержало о нем вопросы; единственный раз, когда меня не позвали на тех.собеседование — когда я тестовое задание выполнил в процедурно-функциональном стиле(тогда мне показалось что ООП для него излишек).