【发布时间】:2011-06-16 16:04:27
【问题描述】:
我有一个用于验证来自数据库的数据的接口,它的实现使用查找和检查功能做不同的事情。一些实现需要额外的功能才能完成它们的任务,这是一种糟糕的做法吗?
【问题讨论】:
-
附加方法是公开的还是私有的/受保护的?
标签: php oop interface implementation factory
我有一个用于验证来自数据库的数据的接口,它的实现使用查找和检查功能做不同的事情。一些实现需要额外的功能才能完成它们的任务,这是一种糟糕的做法吗?
【问题讨论】:
标签: php oop interface implementation factory
听起来您的问题是,实现接口的类是否可以拥有比接口中实际定义的方法更多的方法?答案是肯定的,这很好,事实上也很正常。
【讨论】:
在我看来,只要你不暴露那些超出接口定义的附加功能,这不是一个糟糕的做法;比如让他们protected 或private
编辑:
他的问题中也有标签factory。所以我假设他正在使用factory method。因此,如果给定的接口实现暴露了更多在接口中定义的方法,那将是很糟糕的。
【讨论】:
public 方法也很好。根据您当前的答案,这意味着实现Iterator 的类Foo 不能有除Iterator 中定义的方法之外的任何公共方法。这可能会使您的课程无用。
只要他们尊重接口签名(即根据他们的签名实现接口方法),我认为实现添加额外方法没有问题。
【讨论】:
接口是“服务契约”,其中实现接口的类必须提供接口上描述的功能......该类可以使用(或不使用)不同的功能来提供该服务,所以,它不是不好的做法
【讨论】:
通常会看到类实现接口和附加方法。重要的是您继续遵守单一职责原则。也就是说,您的类的客户会根据您的对象实现的接口对您的对象的行为有所了解,并且您希望确保您不会违反他们的期望。
【讨论】:
如果你正确使用它,这不是一个糟糕的做法。让我举个例子。有了这些:
interface Foo {
public function foo();
}
class Baz implements Foo {
public function foo() {
// implementation of Foo::foo()
}
public function baz() {
// specific to Baz
}
}
以下是不好的做法:
function test(Foo $foo) {
$foo->foo();
$foo->baz();
}
test(new Baz);
在 PHP 中,它可以工作。在预编译的语言中,它没有。这是因为你的论点$foo 是Foo 类型,它没有baz 方法。这将是一个编译错误:编译器检查Foo 类型的参数,而Foo::baz 是无效引用。但是,这些在 PHP 中不存在,因此只要将 Baz 对象传递给函数,它就可以工作。但它为奇怪的运行时错误打开了大门。
正确的做法是:
function test(Baz $foo) {
$foo->foo();
$foo->baz();
}
test(new Baz);
【讨论】:
这本身并不是一个坏习惯。重要的是您是否可以使用与父类完全相同的函数调用来使用扩展类(就这个接口而言)。
【讨论】: