I have Entities and Repositories in my project. To simplify, I have
EntityInterface
UserEntity
BusinessEntity
Interface:
interface Entity
{
/**
* @return EntityId
*/
public function getId();
}
Implementations
class UserEntity implements Entity
{
/**
* @return EntityId
*/
public function getId(){
//...do something here for return
return $userId;
}
}
and
class BusinessEntity implements Entity
{
/**
* @return EntityId
*/
public function getId(){
//...do something here for return
return $userId;
}
}
I would like to define a Repository base-functionality, like save
, so my interface looks like:
interface Repository
{
/**
* @param Entity $entity
*
* @throws \InvalidArgumentException If argument is not match for the repository.
* @throws UnableToSaveException If repository can't save the Entity.
*
* @return Entity The saved entity
*/
public function save(Entity $entity);
}
Later, I have different interfaces for different type of Repositories, like UserRepository
and BusinessRepository
interface BusinessRepository extends Repository
{
/**
* @param BusinessEntity $entity
*
* @throws \InvalidArgumentException If argument is not match for the repository.
* @throws UnableToSaveException If repository can't save the Entity.
*
* @return Entity The saved entity
*/
public function save(BusinessEntity $entity);
}
The above code fails, because Declaration must be compatible with Repository...
however BusinessEntity implements Entity, so it's compatible.
I have many type of entities, so If I can't type-hint, I always need to check, that the passed instance is instanceof what I need. It's stupid.
The following code fails again:
class BusinessRepository implements Repository
{
public function save(BusinessEntity $entity)
{
//this will fail, however BusinessEntity is an Entity
}
}