首先,我无处不在的语言是PHP,我正在考虑学习Java。
因此,让我将问题分成两个密切相关的部分。
这是第一部分。
假设我有一个域模型类。它有一些getter,setter,一些查询方法等。有一天我想有可能比较它们。所以它看起来像:
class MyEntity extends AbstractEntity
{
public function getId()
{
// get id property
}
public function setId($id)
{
// set id property
}
// plenty of other methods that set or retrieve data
public function compareTo(MyEntity $anotherEntity)
{
// some compare logic
}
}
如果它是Java,我应该实现Comparable
接口。但为什么?多态性? Readbility?或者是其他东西?如果它是PHP - 我应该为自己创建Comparable
接口吗?
所以这是第二部分。
我的同事告诉我,在Java中为每个行为方面创建一个接口是一个经验法则。例如,如果我想将此对象呈现为字符串,我应该通过implements Stringable
之类的内容来表示此行为,其中如果PHP Stringable
看起来像:
interface Stringable
{
public function __toString();
}
这真的是经验法则吗?这种方法有什么好处?它在PHP中值得吗?在Java?
答案 0 :(得分:6)
如果它是Java,我应该实现一个Comparable接口。但为什么?
嗯,你已经提供了一种比较“this”和另一个实例的方法......如果你实现Comparable
,你告诉系统的其余部分你支持这种能力,这样就可以了比较可以用于排序,找到“最大”或“最小”值等...所有在对你的类型一无所知的例程中。
我的同事告诉我,在Java中为每个行为方面创建一个界面是一个经验法则。
这对我来说听起来有些过分。 (你的例子不是很好,因为toString()
上已经有Object
。)不要随意创建接口 - 但是如果你希望代码使用那个行为,就创建它们不需要知道你的具体类型,只知道它支持的内容。一个很好的例子就是可测试性 - 如果你编写一个“authenticator”类,那么你可以想象要么交换生产代码中的不同验证者或模拟/伪造验证者您正在测试使用身份验证的其他组件。
答案 1 :(得分:2)
实施Comparable
的一个非常实际的原因是能够执行
List<MyEntity> entities = // ( initialize and populate )
Collections.sort(entities);
无需编写单行排序代码。
这说明了使用接口的基本理念,即允许其他人使用您的代码(对您个人而言更有用),允许您的代码以可靠的方式使用其他人的代码。
至于“每个类行为方面的界面”,这听起来有点矫枉过正,或者说它可能有点矫枉过正。您希望接口有意义,例如,TelephoneThatIsAlsoAToaster
接口不好 - 您应该有两个接口:Telephone
和Toaster
。另一方面,你不应该有大量的接口Pluggable
,Visible
,HasButtons
,Flammable
......等等。
必要的详细程度取决于申请。