我有一个Converter,它使用Resolver来确定在将Resource转换为Entity时使用哪个Factory。要做到这一点,我需要确保Factory有一个createFromResource方法。
问题是:由于参数的反差,我无法创建一个处理工厂的接口。FactoryInterface不能设置createFromResource方法的参数,因为它在每个Factory实现中都会发生变化,并且没有一个公共的父级。
How我可以在不破坏Liskov替换原则的情况下设计这些类吗?我做错什么了?这设计不好吗?
以下是我的课程:
interface EntityInterface {}class UserEntity implements EntityInterface {}interface ResourceInterface {}class UserResource implements ResourceInterface {}class Converter
{
private FactoryResolver $factoryResolver;
public function convert(ResourceInterface $resource): EntityInterface
{
$factory = $this->factoryResolver->resolveFromResource($resource);
// Need to ensure that $factory has createFromResource() method
return $factory->createFromResource($resource);
}
}class FactoryResolver
{
public function resolveFromResource(ResourceInterface $resource): FactoryInterface;
}interface FactoryInterface
{
// Cannot be implemented because of contravariance
public function createFromResource(ResourceInterface $resource): EntityInterface;
}class UserFactory implements FactoryInterface
{
// This signature break contravariance
public function createFromResource(UserResource $user): UserEntity;
}PHP版本: 7.4
Thanks很多!
发布于 2020-11-22 19:09:47
我认为您的错误突出了一点:如果 Is FactoryInterface**?**,甚至可以处理 UserFactory <#>as。
因为UserFactory.createFromResource需要一个UserResource,所以它没有FactoryInterface.createFromResource那么宽松。这意味着将UserResource转换为FactoryInterface是不安全的,无论您如何看待它。
协方差和反向方差只告诉您在自动类型转换方面什么是安全的。在实现继承函数时,参数类型永远不会比父函数所允许的限制更严格;否则,将其实际用作父函数的实例是不安全的。
总之,在这种情况下,FactoryInterface似乎并不表示其子级的公共属性,因为您不能放弃对底层实现的了解。
https://softwareengineering.stackexchange.com/questions/419163
复制相似问题