java - 创建 `Copyable` 类型接口(interface)而不是使用 `Cloneable` 是否有意义?

标签 java design-patterns

我有一些代码需要发送对象的副本。此要求是因为调用的服务(运行时库)会修改发送的对象。该对象还需要公开 setter ,以防下面的 doThing 方法需要设置 ImportantObj 类中的任何字段。此实现正在等待更改,但没有合理预期会在不久的将来发生更改。我的解决方法是提供一个执行以下操作的类:

public class DangerousCallWrapper<T> implements DangerousCaller<T> {
  public T doThing(T dataObject) {

      T cloneOfDataObject = #Clone of dataObject

      // This service modifies the cloneOfDataObject... dangerous! 
      Optional<T> result = service.doThing(cloneOfDataObject);

      return result.orElseThrow(() -> new RuntimeException("No data object returned");
  }
}

public interface DangerousCaller<T> {

  /**
  * Performs the functionality of the DangerousService
  */
  public T doThing(T);
}


public DangerousService<T> {


  public T doThing(T data) {
   data.importantField = null;
   data.thing = "Done!";

   return data;
  }
}

public static void main() {

  DangerousService service = new DangerousService<ImportantObj>();
  ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
  service.doThing(important);
  //would fail this check
  assertNotNull(important.importantField);

  DangerousCallWrapper wrapper = new DangerousCallWrapper<ImportantObj>();
  ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
  service.doThing(important);
  //would not fail this check
  assertNotNull(important.importantField);
}

所以该方法的第一行是我陷入困境的地方。它是通用类型,因此我无法显式调用某些克隆实用程序,例如 Jackson 或类似的实用程序。

所以我想我只需将 T extends Cloneable 添加到该方法中...但我打开了 Cloneable 超出禁忌的蠕虫 jar ( https://www.artima.com/intv/bloch13.html ) 。我还读到,复制构造函数可能是处理这个问题的最佳方法...但是,我不确定如何使用泛型来表示这一点。

所以我的想法是提供一个接口(interface)Copyable,它可以完成您期望Cloneable做的事情:公开一个方法,copy()这将创建该类的一个新实例。

这是否是一种可行的方法?

最佳答案

要解决您的问题,您需要以多态方式创建 dataObject 的副本,如下所示:

T cloneOfDataObject = dataObject.clone();

问题是 Cloneable 没有 clone() 方法,因此上面的代码无法编译。

鉴于这个前提,创建您自己的 Copyable 接口(interface)来定义 clone() 方法确实有意义,这样您就可以利用已经实现的 clone( ) 数据对象的类上的方法(如果存在)。为了获得最大的效率,这个接口(interface)也需要是通用的:

interface Copyable<T> {
    public T clone();
}

和类型绑定(bind):

public class DangerousCallWrapper<T extends Copyable<T>> 
    implements DangerousCaller<T> {

关于java - 创建 `Copyable` 类型接口(interface)而不是使用 `Cloneable` 是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56814316/

相关文章:

java - Spring 启动 Spring 安全AngularJS

oop - 铁路票价计算可以使用哪种设计模式?

database - 访问/更新数据库是否需要安静的服务?

java - 装饰器模式 - 如何同时装饰两种类型

java - 使用 JQL 通过 Java 查询 Jira 问题出现 404

java - 在 AnyLogic 中模拟人口密度

java - 查询内存中的集合

java - Java中的URL编码和解码特殊字符

java - 在实体生命周期的某个时刻改变实体的类型

c# - 工厂方法模式和抽象工厂模式