在过去的几个月里,我在下面的技术/模式上跌跌撞撞了几次。然而,我似乎找不到一个特定的名字,也不能百分之百肯定它的所有优点和缺点。
模式如下:
在Java接口中,通常定义一组通用方法。但是,使用内部类,默认实例将通过接口泄漏。
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static Vehicle getInstance() {
return new Car(); // or use Spring to retrieve an instance
}
}
}对我来说,最大的优势似乎在于开发人员只需要了解接口,而不需要了解它的实现,例如,如果开发人员想要快速创建实例的话。
Vehicle someVehicle = Vehicle.Default.getInstance();
someVehicle.accelerate();此外,我看到这种技术与Spring一起使用,以便根据配置动态地提供实例。在这方面,这看起来也有助于模块化。
然而,我无法摆脱这样一种感觉,即这是对接口的滥用,因为它将接口与其实现之一耦合在一起。(依赖反演原理等)有谁能向我解释一下这种技术的名称,以及它的优点和缺点?
经过一段时间的考虑后,我重新检查并注意到下面的模式的单例版本被使用得更频繁了。在此版本中,通过接口公开公共静态实例,该接口只初始化一次(由于字段是最终的)。此外,实例几乎总是使用Spring或将接口与实现分离的通用工厂检索的。
public interface Vehicle {
public void accelerate();
public void decelerate();
public static class Default {
public static final Vehicle INSTANCE = getInstance();
private static Vehicle getInstance() {
return new Car(); // or use Spring/factory here
}
}
}
// Which allows to retrieve a singleton instance using...
Vehicle someVehicle = Vehicle.Default.INSTANCE;简单地说,这似乎是一种自定义的单例/工厂模式,它基本上允许通过它的接口公开一个实例或一个单例。关于缺点,在下面的答复和评论中列出了一些。到目前为止,其优势似乎在于它的方便。
发布于 2013-12-16 07:49:10
Default.getInstance只是工厂法的一种非常特殊的形式,它与取自单例模式的命名约定(但不是后者的实现)混在一起。在当前的表单中,这违反了"单一责任原则",因为接口(已经用于声明类API的目的)承担了提供默认实例的额外责任,这将更好地放在单独的VehicleFactory类中。
这种构造的主要问题是它导致了Vehicle和Car之间的循环依赖。例如,在当前的表单中,不可能将Vehicle放在一个库中,Car放在另一个库中。使用一个单独的工厂类并将Default.getInstance方法放置在那里将解决这个问题。给该方法取一个不同的名称也可能是个好主意,以防止与单名相关的任何混淆。所以结果可能是
VehicleFactory.createDefaultInstance()
发布于 2013-12-16 11:26:00
在我看来,这就像空对象模式。
但这在很大程度上取决于Car类是如何实现的。如果它是以“中性”方式实现的,那么它肯定是一个空对象。这意味着,如果您可以删除接口上的所有空检查,并将该类的实例放入其中,而不是每次出现null,那么代码仍然必须正确工作。
另外,如果是这种模式,那么在接口本身和空对象的实现之间创建紧密耦合就没有问题了。因为空对象可以在任何地方使用该接口。
https://softwareengineering.stackexchange.com/questions/221442
复制相似问题