首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以下(反)模式的名称是什么?它的优点和缺点是什么?

以下(反)模式的名称是什么?它的优点和缺点是什么?
EN

Software Engineering用户
提问于 2013-12-15 22:19:30
回答 2查看 3.1K关注 0票数 28

在过去的几个月里,我在下面的技术/模式上跌跌撞撞了几次。然而,我似乎找不到一个特定的名字,也不能百分之百肯定它的所有优点和缺点。

模式如下:

在Java接口中,通常定义一组通用方法。但是,使用内部类,默认实例将通过接口泄漏。

代码语言:javascript
复制
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
         }
    }
 }

对我来说,最大的优势似乎在于开发人员只需要了解接口,而不需要了解它的实现,例如,如果开发人员想要快速创建实例的话。

代码语言:javascript
复制
 Vehicle someVehicle = Vehicle.Default.getInstance();
 someVehicle.accelerate();

此外,我看到这种技术与Spring一起使用,以便根据配置动态地提供实例。在这方面,这看起来也有助于模块化。

然而,我无法摆脱这样一种感觉,即这是对接口的滥用,因为它将接口与其实现之一耦合在一起。(依赖反演原理等)有谁能向我解释一下这种技术的名称,以及它的优点和缺点?

更新:

经过一段时间的考虑后,我重新检查并注意到下面的模式的单例版本被使用得更频繁了。在此版本中,通过接口公开公共静态实例,该接口只初始化一次(由于字段是最终的)。此外,实例几乎总是使用Spring或将接口与实现分离的通用工厂检索的。

代码语言:javascript
复制
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;

简单地说,这似乎是一种自定义的单例/工厂模式,它基本上允许通过它的接口公开一个实例或一个单例。关于缺点,在下面的答复和评论中列出了一些。到目前为止,其优势似乎在于它的方便。

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2013-12-16 07:49:10

Default.getInstance只是工厂法的一种非常特殊的形式,它与取自单例模式的命名约定(但不是后者的实现)混在一起。在当前的表单中,这违反了"单一责任原则",因为接口(已经用于声明类API的目的)承担了提供默认实例的额外责任,这将更好地放在单独的VehicleFactory类中。

这种构造的主要问题是它导致了VehicleCar之间的循环依赖。例如,在当前的表单中,不可能将Vehicle放在一个库中,Car放在另一个库中。使用一个单独的工厂类并将Default.getInstance方法放置在那里将解决这个问题。给该方法取一个不同的名称也可能是个好主意,以防止与单名相关的任何混淆。所以结果可能是

VehicleFactory.createDefaultInstance()

票数 24
EN

Software Engineering用户

发布于 2013-12-16 11:26:00

在我看来,这就像空对象模式。

但这在很大程度上取决于Car类是如何实现的。如果它是以“中性”方式实现的,那么它肯定是一个空对象。这意味着,如果您可以删除接口上的所有空检查,并将该类的实例放入其中,而不是每次出现null,那么代码仍然必须正确工作。

另外,如果是这种模式,那么在接口本身和空对象的实现之间创建紧密耦合就没有问题了。因为空对象可以在任何地方使用该接口。

票数 3
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/221442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档