我只是想在我的Java代码中注入一些设计模式,但我不知道使用哪种样式 - 是继承还是接口首选?为什么?
答案 0 :(得分:9)
设计模式不是随机注入应用程序的东西。它们是设计时的各种东西,而不是在你的代码已经烘烤后撒在你的代码上的帕玛森奶酪。
尽管如此,Josh Bloch的开创性 Effective Java 强烈鼓励开发人员使用接口来实现共享行为,而不是使用继承。这符合我自己的经验。
ETA:除其他原因外,如果您正在实现一个接口,您可以轻松地创建该接口的模拟以用于测试,而不必担心继承层次结构的其余部分。
答案 1 :(得分:5)
设计模式不会“注入”您的代码 - 您首先需要注意的是,您的问题类似于许多其他人解决的问题,并且他们已经提炼出一种解决问题的模式。最着名的是here
另外,是否要使用继承(也称为扩展)或接口依赖。通常界面和构图效果更好。
答案 2 :(得分:2)
这两个功能并不相互排斥。接口和实现指定类型和与类型的兼容性。继承允许有效地共享代码。在经典设计中,类型层次结构使用接口表示,而代码重用是使用继承实现的。
答案 3 :(得分:1)
我同意不应该考虑使用某些设计模式注入OR。设计模式旨在解决给定环境中的非常具体的问题。
关于接口和继承:
当您需要运行时多态时,正在使用接口。因此,您定义了一个接口,您可以拥有多个不同的实现。在客户端代码中,您只需将引用声明为接口类型即可。现在,您不必担心在运行时传递给客户端的实际对象类型。您只关心在引用上调用方法。
interface Car {
void startEngine();
void stopEngine();
}
class Maruti implements Car {
public void startEngine() {
System.out.println("Maruti engine started");
}
@Override
public void stopEngine() {
System.out.println("Maruti engine stopped");
}
}
class Porsche implements Car {
@Override
public void startEngine() {
System.out.println("Porsche engine started");
}
@Override
public void stopEngine() {
System.out.println("Porsche engine stopped");
}
}
在上面作为客户端的示例中,您只需将引用声明为Car类型。在运行时,你可以拥有Maruti对象或保时捷对象,你不关心。你关心的只是调用startEngine或stopEngine。
继承通常用于代码可重用性和可扩展性。因此,您在两个类中有共同的代码,并且两者似乎都属于一个公共类型,然后您可以创建一个父类(有时候是抽象的)并在父类中移动公共代码。这样你就可以摆脱重复的代码。另一个用例是可扩展性,有时您无法控制类的源代码,仍然希望添加/更改某些行为。您可以使用继承并覆盖某些方法。
还有一个名为“composition”的东西,它是一种优于继承可扩展性的方法。