在 Java 中将内核模型转换为输出模型

发布于 2024-12-16 20:38:19 字数 857 浏览 1 评论 0原文

这里我有一些代码可以将内部核心模型“传输”到外部插件的“输出”模型。

为此,我根据传递的 OldConnection 的具体子类型创建新实例,并将旧实例传递(通过强制转换)到构造函数中,这样我就可以轻松维护 getter 和 setter 的内部数据。

因此,OldIncoming、OldOutgoing 和 OldExpected 是 OldConnection 的子类型。 MyNewIncoming、MyNewOutgoing 和 MyNewExpected 是 MyNewConnection 的子类型。不幸的是,我无法更改内核模型,并且我需要构造函数中的具体类型。

代码看起来很丑陋,但我只是找不到更好的解决方案,有什么想法吗?

private MyNewConnection createIConnectedSubtypeInstance(OldConnection connection) {

    if (connection instanceof OldIncoming){
        return new MyNewIncoming((OldIncoming) connection);
    }
    if (connection instanceof OldOutgoing){
        return new MyNewOutgoing((OldOutgoing) connection);
    }
    .
    .
    .
    if (connection instanceof OldExpected){
        return new MyNewExpected((OldExpected) connection);
    }

    return new MyNewConnection(connection);
}

Here i've got some code to "transfer" an inner core model to an "output" model for external plugins.

For doing this, I create new instances based on the concrete subtype of a passed OldConnection and pass (with a cast) the old instance into the constructor, so i can easily maintain the inner data for getters and setters.

So, OldIncoming, OldOutgoing and OldExpected are subtypes of OldConnection. MyNewIncoming, MyNewOutgoing and MyNewExpected are subtypes of MyNewConnection. Unfortunately, I cant change the inner core model and I need concrete types in the constructors.

Code looks pretty ugly, but I just cant find a better solution for it, any ideas?

private MyNewConnection createIConnectedSubtypeInstance(OldConnection connection) {

    if (connection instanceof OldIncoming){
        return new MyNewIncoming((OldIncoming) connection);
    }
    if (connection instanceof OldOutgoing){
        return new MyNewOutgoing((OldOutgoing) connection);
    }
    .
    .
    .
    if (connection instanceof OldExpected){
        return new MyNewExpected((OldExpected) connection);
    }

    return new MyNewConnection(connection);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绮筵 2024-12-23 20:38:19

另一种选择是一堆重载方法,如下所示:

private MyNewIncoming createIConnectedSubtypeInstance( OldIncoming connection ) {
  return new MyNewIncoming( connection );
}

但是,只有调用者知道 connection 的类型时,这种方法才有效,否则您必须依赖那些 instanceof< /代码> 检查。

在这种情况下,您还可以进行一些映射 OldClass->NewClass 并使用反射来创建实例,但我怀疑这值得这么麻烦,除非您需要大量的映射。

示例:

Map<Class<? extends OldConnection>, Class<? extends NewConnection>> mapping; //initializing is up to you

public NewConnection  createIConnectedSubtypeInstance(OldConnection connection) {
  try {
    Class<? extends NewConnection> subtype = mapping.get( connection.getClass() );
    return subtype.getConstructor( connection.getClass() ).newInstance( connection );
  } catch( Exception e) { //you might want to catch the more specific types
    //handle appropriateley
  }
} 

请注意,这依赖于直接映射的 connection 类。如果您映射超类,则可能必须检查这些超类是否找不到 connection 的实际类的映射。

此外,这依赖于新实例的构造函数只接受映射类类型的一个参数。

An alternative would be a bunch of overloaded methods, like this:

private MyNewIncoming createIConnectedSubtypeInstance( OldIncoming connection ) {
  return new MyNewIncoming( connection );
}

That, however, works only if the caller knows what type connection is of, otherwise you'd have to rely on those instanceof checks.

In that case you could also have some mapping OldClass->NewClass and use reflection to create instances, but I doubt that would be worth the hassle unless you need a huge amount of mappings.

Example:

Map<Class<? extends OldConnection>, Class<? extends NewConnection>> mapping; //initializing is up to you

public NewConnection  createIConnectedSubtypeInstance(OldConnection connection) {
  try {
    Class<? extends NewConnection> subtype = mapping.get( connection.getClass() );
    return subtype.getConstructor( connection.getClass() ).newInstance( connection );
  } catch( Exception e) { //you might want to catch the more specific types
    //handle appropriateley
  }
} 

Note that this relies on the class of connection being mapped directly. If you map super classes you might have to check those if no mapping for the actual class of connection can be found.

Additionally, this relies on the constructors of the new instances to accept exactly one parameter of the mapped class type.

心房敞 2024-12-23 20:38:19

您可以重载您的工厂方法:

private MyNewConnection createIConnectedSubtypeInstance(OldIncoming conn) {
   return new MyNewIncoming(conn);
}

private MyNewConnection createIConnectedSubtypeInstance(OldOutgoing conn) {
   return new MyNewOutgoing(conn);
}
...

正如托马斯在他的回答中指出的那样,只有当您使用正确的静态类型调用这些方法时,这才有效:

OldIncoming a;
...
MyNewConnection b = createIConnectedSubtypeInstance(a); // will return MyNewIncoming

由于重载使用静态绑定,因此您不能在 this 中使用 OldConnection案件。如果这不适合您,那么在某些时候您将不得不执行instanceof。

You could overload your factory method:

private MyNewConnection createIConnectedSubtypeInstance(OldIncoming conn) {
   return new MyNewIncoming(conn);
}

private MyNewConnection createIConnectedSubtypeInstance(OldOutgoing conn) {
   return new MyNewOutgoing(conn);
}
...

As Thomas points out in his answer this will only work if you call these methods with the correct static type:

OldIncoming a;
...
MyNewConnection b = createIConnectedSubtypeInstance(a); // will return MyNewIncoming

As overloading uses static binding, you cannot use OldConnection for a in this case. If this is not an option for you, then you will be stuck with doing instanceof at some point.

じее 2024-12-23 20:38:19

您可以将包装器的创建移至 OldConnection 及其派生类。在 OldConnection 中,定义了方法

public MyNewConnection createNewConnectiom() {
    return MyNewConnection(this);
}

In OldIncoming override with

public MyNewConnection createNewConnectiom() {
    return MyNewIncoming(this);
}

和 in OldExpected override with

public MyNewConnection createNewConnectiom() {
    return MyNewExpected(this);
}

这样,您就可以摆脱分支和强制转换。

You can move the creation of the wrapper to OldConnection and its derived classes. In OldConnection, defined the method

public MyNewConnection createNewConnectiom() {
    return MyNewConnection(this);
}

In OldIncoming override with

public MyNewConnection createNewConnectiom() {
    return MyNewIncoming(this);
}

and in OldExpected override with

public MyNewConnection createNewConnectiom() {
    return MyNewExpected(this);
}

In that way you get rid of the branches and the casts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文