@OneTwoThreeFourFive

Как правильно сделать типизацию объектов?

Я использую паттерн DataMapper и использую общий абстрактный класс для всех дата мапперов, чтобы не копировать похожий код (findByID и другое).
abstract class DataMapperAbstract {
	public function findByID( int $id ) {
		$this->database->read...
	}

	protected function setDatabase( Database $database ) {
		$this->database = $database;
	}

	protected function setTable( string $table) {
		$this->table = $table;
	}

	abstract protected function mapToObject( array $data );

	abstract protected function mapToArray( $object ): array;

	abstract public function save( $object );
}


Есть дата маппер для пользователей
class UserMapper extends DataMapperAbstract {
	public function __construct( Database $database ) {
		$this->setDatabase( $database );
		$this->setTable( 'users' );
	}

	protected function mapToObject( array $data ): User {
		...
	}

	protected function mapToArray( $user ): array {
		if ( !( $user instanceof User ) ) {
			throw new \Exception( 'Not User' );
		}

		...
	}

	public function save( $user ) {
		...
	}
}


Чтобы проверить, является ли значение в $user mapToArray( $user ) объектом класса User, я использую конструкцию
if ( !( $user instanceof User ) ) {
	throw new \Exception( 'Not User' );
}


В абстрактном классе нельзя указать тип объекта User
abstract protected function mapToArray( User $object ): array;

потому что другие дата мапперы будут использовать другие объекты (не User).

Проверка с исключением нормальное решение? И чтобы не писать каждый раз такую конструкцию, добавить её в абстрактный класс function checkObject() { ... }?

Или как сделать лучше?
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Vitsliputsli
Вы можете воспользоваться контравариантностью (php>=7.4), т.е. указать в абстрактном классе родительский класс для User:
abstract protected function mapToArray(Model $object ): array;

...

class User extends Model

Либо ввести DTO, чтобы mapper брал данные из него и вообще никак не обращался к бизнесовым сущностям.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы