В качестве примера использования ООП приведу следующий. Мне он кажется наиболее простым и понятным, и в то же время лаконичным.
Задача: реализовать механизм перебора символов (брутфорса) с возможностью изменения символов без изменения кода. На пример имеются символы 123, нужно чтоб код вывел 123, 132, 213 и др.
Процедурник задумался бы скорее всего об алгоритмах перебора, проверки существования числа и разбора строки на компоненты. Объектнику достаточно было бы вспомнить принципы организации чисел в математике.
Предметная область:
Разряд - конкретная позиция числа;
Число - совокупность разрядов и символов числа на этих разрядах;
Символ числа - один из возможных символов, используемых при составлении числа.
На пример число 123ABC имеет 6 разрядов, символ на первом разряде (самый правый) имеет вид C, на втором B, на третьем A и т.д. Для данной системы счисления используются символы: 1, 2, 3, A, B, C что эквивалентно десятичной - 1, 2, 3, 4, 5, 6 - но вместо 4,5,6 используются буквы латинского алфавита.
Если к числу C добавляется единица, число увеличивается на разряд: C + 1 = 10.
Объектная реализация задачи:
/**
* Класс представляет конкретный символ числа (конкретную цифру).
*/
class Discharge{
/**
* Набор символов для обозначения элемента числа. Упорядочен в порядке возрастания их весового коэффициента.
* @var integer[]
*/
protected $numerals = [1, 2, 3, 4, 5, 'A', 'B', 'C']; // Доступные символы
/**
* Текущий символ элемента числа. Не может быть больше, чем число символов.
* @var integer
*/
protected $point = 0;
/**
* Система счисления (число элементов массива $numerals)
* @var integer
*/
protected $numberSystem;
function __construct(){
$this->numberSystem = count($this->numerals);
}
/**
* Возвращает текущее значение элемента числа.
* @return string
*/
public function getNumber(){
return (string)$this->numerals[$this->point];
}
/**
* Добавляет к элементу числа монаду (единицу)
* @return boolean true - если число удачно инкрементированно, false - если инкрементация вызвала сброс элемента числа.
*/
public function plus(){
$this->point++;
if($this->point == $this->numberSystem){
$this->point = 0;
return false;
}
return true;
}
}
/**
* Класс представляет собой совокупность символов числа (само число).
*/
class Number{
/**
* Массив элементов числа, упорядоченный по возрастанию разрядности.
* @var Discharge[]
*/
protected $number = [];
/**
* Длина числа.
* @var integer
*/
protected $length;
/**
* @param integer $length Длина числа
*/
function __construct($length){
$this->length = $length;
for($i = 0; $i < $length; $i++){
$this->number[] = new Discharge;
}
}
/**
* Метод увеличивает заданный разряд на монаду.
* @param integer $discharge Номер разряда начиная с 0
*/
protected final function incrementDischarge($discharge){
if($discharge < $this->length){
if(!$this->number[$discharge]->plus()){
$this->incrementDischarge($discharge+1);
}
}
}
/**
* Метод увеличивает число на монаду.
*/
public function increment(){
$this->incrementDischarge(0);
}
/**
* Метод возвращает число.
* @return string Текущее значение числа
*/
public function showNumber(){
$resultNumber = '';
for($i=$this->length; $i--; ){
$resultNumber .= $this->number[$i]->getNumber();
}
return $resultNumber;
}
}
$n = new Number(5);
for($i=0; $i<10; $i++){
echo $n->showNumber()."\n";
$n->increment();
}
echo $n->showNumber()."\n";
/*
Результат
11111
11112
11113
11114
11115
1111A
1111B
1111C
11121 - повышение разряда
11122
11123
*/