Пример реализации интерфейсов, абстрактных классов, сингтона, трейта и фасада в PHP

abstrat-php-code-singletone-trait-interface-example-facade

В данном участке(пример) когда применены — трейты, абстрактные классы, наследование, сингтон, и фасад на языке программирования PHP.

<?php
declare(strict_types = 1);

# Single-responsibility principle | Принцип единственной ответственности
# Open–closed principle | Принцип открытости/закрытости
# Liskov substitution principle | Принцип подстановки Барбары Лисков
# Interface segregation principle | Принцип разделения интерфейса
# Dependency inversion principle | Принцип инверсии зависимостей 

namespace Cars;

/** 
 * Интерфейс для Car
 */
interface ICar {
	/** 
	 * Обязательные методы
	 */
	public function moveX(int $offset):int;
	public function moveY(int $offset):int;
	public function sound():string;
	public function toggle_doors():string;
}
/**
 * Интерфейс специально для Cybertruck, он умеет бибикать :)
 */
interface ICybertruck {
	public static function beep():string;
}

interface ITesla {
	public static function fly():bool;
}

# Трейт
trait TMoving {
	public $x = 0;
	public $y = 0;

	public function calculate_x(int $offset) {
		return $this->x += $offset;
	}

	public function calculate_y(int $offset) {
		return $this->x += $offset;
	}
}

/** 
 * Абстрактный класс для передвижения
 * с использованием трейта
 */
// abstract
abstract class Moving  {
	use TMoving; 

	public function moveX(int $offset):int {
		$this->x = $this->calculate_y($offset);
		return $this->x;
	}

	public function moveY(int $offset):int {
		$this->y = $this->calculate_y($offset);
		return $this->y;
	}

	public function getCoors():array {
		return [$this->x, $this->y];
	}
}
/** 
 * Абстрактный класс Car
 */
abstract class Car extends Moving {
	public $name = 'unknown';
	public bool $door_opened = false;
	// public $x = 0;
	// public $y = 0;

	public function __construct(string $name) {
		$this->name = $name;
	}

	public function getName():string {
		return $this->name;
	}

	public function toggle_doors():string {
		$this->door_opened = !($this->door_opened);
		return 'Toggle doors! \\ //';
	}

	public function doors_opened(bool $state) {
		$this->door_opened = $state;
	}
}

/**
 * Singletone
 */
class CarsDB  {
	static protected $instance;
	public $cars = [];

	public static function getInstance()
	{
		if (!(static::$instance instanceof static)) {static::$instance = new static();}
		return static::$instance;
	}

	public function save(Car $obj) {
		// echo '<strong>Saving to db...</strong>: ', $obj->getName();
		$this->cars[] = $obj;
	}

	public function fetchAll() {
		return $this->cars;
	}

	public function print() {
		echo '<pre>';var_dump(self::getInstance());echo '<pre>';
	}
}

/**
 * Класс Tesla на основе абстрактного класса Car и с интерфейсом ICar
 */
class Tesla extends Car implements ICar {
	public function sound():string {
		return 'Tesla sound!';
	}
}

/**
 * Класс Cybertruck на основе абстрактного класса Car и с интерфейсом ICar
 */
class Cybertruck extends Car implements ICar, ICybertruck {
	public function sound():string {
		return 'Cybertruck sound!';
	}

	public static function beep():string {
		return 'Beep! (●\'◡\'●)';
	}
}

# Facade
class ClientCars {
	protected $db;

	public function __construct(CarsDB $data = null) {
		$this->db = $data ?? new CarsDB();
	}

	// public function load_db(CarsDB $data) {
	// 	$this->db = $data;
	// }

	public function add_car(Car $data) {
		$this->db->save($data);
	}

	public function movex_and_door(int $num, int $offset, bool $opened_doors) {
		if(isset($this->db->cars[$num])) {
			$this->db->cars[$num]->moveX($offset);
			$this->db->cars[$num]->doors_opened($opened_doors);
			return true;
		}
		return false;
	}

	public function movex_and_door_all(int $offset, bool $opened_doors) {
		foreach ($this->db->cars as $car) {
			$car->moveX($offset);
			$car->doors_opened($opened_doors);
		}
	}
}

# Processing

var_dump('PHP v.' . phpversion());
echo '<hr>';

# Create new object - Tesla
$tesla = new Tesla('SpaceX');
$tesla->moveX(1); # →
$tesla->moveY(1); # ↑
$tesla->moveY(1); # ↑
var_dump($tesla);
var_dump($tesla->getName());
var_dump($tesla->sound());
var_dump($tesla->getCoors());
var_dump($tesla->toggle_doors());
CarsDB::getInstance()->save($tesla);

echo '<hr>';

# Create new object - Cybertruck
$cybertruck = new Cybertruck('Trampoline is working');
$cybertruck->moveX(1); # →
$cybertruck->moveY(-2); # ↑
var_dump($cybertruck);
var_dump($cybertruck->getName());
var_dump($cybertruck::beep());
var_dump($cybertruck->sound());
var_dump($cybertruck->getCoors());
var_dump($cybertruck->toggle_doors());
var_dump($cybertruck->toggle_doors());
CarsDB::getInstance()->save($cybertruck);

echo '<hr>';

# Print cars db
CarsDB::getInstance()->print();

# Facade
$Client = new ClientCars(CarsDB::getInstance());
$Client->add_car($cybertruck);
$Client->movex_and_door(0, 999, true); # Двигаем по X, открываем двери - первой
$Client->movex_and_door_all(50, false); # Двигаем все по X, открываем всем двери
var_dump($Client);
| Опубликовано: 08.07.2020
❤ 1