使用附加方法在类中实现接口
我试图接受干净的代码和设计模式,并遇到了以下场景。
我的接口
interface SystemLogInterface
{
public function log(string $type);
}
和我的 class
实现
class LogDownloadService implements SystemLogInterface
{
public function log(string $type)){}
}
我有另一个日志记录 class
,与上面的类似。
class LogUserService
{
public function setAttr(){}
public function log(string $type)){}
}
因为此类有一个额外的方法 setAttr()
,所以它没有实现相同的接口
。
例如,假设我的 LogUserService
class
正在实现 SystemLogInterface
public function foo(LogUserService $service)
{
$service->setAttr($this->getAttr())
$service->log()
}
如果我想将注入的服务更改为另一个实现,我必须更改方法 foo()
的主体,因为 setAttr()
方法将不存在。
如果可能的话,我希望实现让两个类实现相同接口或另一个解决方案的结果。
注意: setAttr(
) 不能移至构造函数
I'm trying to embrace clean code and design patterns and came across to the following scenario.
My interface
interface SystemLogInterface
{
public function log(string $type);
}
And my class
implementation
class LogDownloadService implements SystemLogInterface
{
public function log(string $type)){}
}
I have another logging class
, similar to the one above.
class LogUserService
{
public function setAttr(){}
public function log(string $type)){}
}
Because this class has an extra method setAttr()
it does not implement same interface
.
For example, let's suppose that my LogUserService
class
was implementing SystemLogInterface
public function foo(LogUserService $service)
{
$service->setAttr($this->getAttr())
$service->log()
}
If I want to change the injected service to another implementation, i would have to change the body of the method foo()
, because the setAttr()
method will not exist.
I want to achieve, if possible, a result to have both classes implementing the same interface or another solution.
Note: setAttr(
) can not be moved to the constructor
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您误解了接口的意义。
实际上,接口定义了类之间的契约。这对类有两个视角:
在类中,实现接口,它表明该接口具有哪些功能。并且每个类可以实现多个接口,其中一些接口不相关,一些接口重叠。
在类中,需要接口,它指示以下代码需要给定对象的哪些特定功能。
那么...我将如何处理这个问题。
您需要创建另一个接口,其中包含
setAttr
方法(我们称之为:WithAttributes
)。然后您需要创建一个继承SystemLogInterface
和WithAttribures
的接口。这一“复合接口”将是您的 LogUserService 实际实现的接口。然后,您可以将它的实例传递给需要新创建的复合材料和需要 SystemLogInterface 功能的旧代码的方法。
PS 为什么你调用你的接口
SystemLogInterface
而不是你的类LogUserServiceClass
....你真的应该更加一致:PI think you are misunderstanding the point of interfaces.
An interface, in effect, defines the contract between classes. This has two perspectives for classes:
in class, that implements an interface, it indicates what capabilities the has. And each class can implement multiple interfaces, some of which will be unrelated and some of which will overlap.
in class, that requires an interface, it indicates which specific capabilities the following code will need from a given object.
So ... how I would approach this.
You need to create another interface, that contains your
setAttr
method (let's call it:WithAttributes
). Then you need to create an interface, that inheritsSystemLogInterface
andWithAttribures
.This "composite interface" would be the one that your
LogUserService
actually implements. And you would be able to then pass the instance of it both to the methods, that require the new;y created composite AND the old code requiring theSystemLogInterface
functionality.P.S. why do you call your interface
SystemLogInterface
but not your classLogUserServiceClass
.... you really should be more consistent :P