I often find myself wanting to be able to have a trait implement an interface, so that when I add the trait to a class, I can know the trait's requirements are met. For example, in Laravel I will create traits for many of my relationships like below:
trait HasOwner
{
public function owner()
{
return $this->belongsTo(User::class);
}
}
In the case of Laravel, I can be pretty well assured that every model I add this to will have a belongsTo method, however it still feels like I should be able to enforce this.
The only way I know to enforce this is to support it with a HasOwnerInterface or HasRelationshipsInterface, but the fact that by failing to add that when I'm adding the trait prevents it squawking feels like having airbags in a car, but which you need to turn on every time you start the engine.
This is what I think would be perfect:
trait HasOwner expects RelationshipInterface
{
public function owner()
{
return $this->belongsTo(User::class);
}
}
interface RelationshipInterface
{
public function belongsTo(Model $model): Relationship;
}
class Property implements RelationshipInterface
{
use HasOwner;
}
Is there another design pattern I should be using for this, or should I role up my sleeves and start fighting for this with the PHP core team to add this?