java - 如何扩展防御性编码的实现?例如。 vert.x CorsHandlerImpl

标签 java vert.x

有像 vert.x 这样的防御性编码库。使用接口(interface)和静态工厂方式返回实现。开发人员可以使用他们的实现,但是当它不是完全所需要的时,就不可能扩展它。不幸的是,它甚至将实现绑定(bind)到接口(interface)中。为什么?

扩展此类类的推荐方法是什么?除了复制整个类并仅重写少数需要的行之外,必须有其他方法......

例如:io.vertx.ext.web.handler.CorsHandler 的 vert.x 实现

public interface CorsHandler {
  static CorsHandler create(String allowedOriginPattern) {
    return new CorsHandlerImpl(allowedOriginPattern);
  }
  ...
}


public class CorsHandlerImpl implements CorsHandler {
  private boolean isValidOrigin(String origin) {
  }
  ...
}


public class MyCorsHandler implement/extends CorsHandler/impl {
  @Override
  protected boolean isValidOrigin(String origin) {
    // my changes 
  }
}

最佳答案

可以包装一个类而不是扩展它,并仅更改需要不同实现的方法。

该解决方案称为 Adapter Pattern :

In software engineering, the adapter pattern is a software design pattern (also known as Wrapper, an alternative naming shared with the Decorator pattern) that allows the interface of an existing class to be used as another interface.1 It is often used to make existing classes work with others without modifying their source code.

考虑到扩展其他人编写的现有类通常不是一个好主意。事实上,在接下来的版本中,它们的内部实现可能会发生变化,并且这些变化可以反射(reflect)在扩展类上,从而以有时不可预测的方式改变它们的行为。

这里有一个例子表明:

想象一下,您需要使用自定义实现来扩展 ArrayList 以记录所有添加的项目。

实际上你可以重写add和addAll方法如下:

public void add(E e) {
   System.out.println("add item " + e);
   super.add(e);
}

public void addAll(Collection<? extends E> c) {
   for (E e : c) {
       System.out.println("add item " + e);
   }
   super.addAll(c);
}

这是可行的,因为 addAll 的内部实现不调用 add。但是,如果 addAll 的实现随着对集合 c 的循环而改变,并为每个元素调用 add ,那么您的代码将无法工作。因此,更改基类将更改派生类的行为。

关于java - 如何扩展防御性编码的实现?例如。 vert.x CorsHandlerImpl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41057903/

相关文章:

java - Android项目 "error: package R does not exist "的Maven编译错误

javascript - 用 Java Vert.x 客户端替换 JavaScript SockJS 客户端

java - 我正在寻找 Vertx JDBC SQLite 驱动程序

java - VertX 与 Jetty 性能问题

java - 使用 java 访问 dynamoDB(本地)时无法加载 AWS 凭证错误

java - 在 hibernate 中过滤计算列? (拥有)

java - 如何在jxpath中使用text()

java - 有没有更好的方法来切换注释代码?

java - 如何在vertx中传递系统属性

hazelcast - Vertx 集群事件总线不会删除 kubernetes 滚动部署上的旧节点