gpt4 book ai didi

java - 避免在基于通用工厂的 MVP 框架中进行强制转换

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:35:22 26 4
gpt4 key购买 nike

我试图在 MVP 模式中实现一种将 View 和 Presenter 解耦的方法,以提供一个框架,它正是这样做的,但后来我感到困惑。

背景

我有一个连接演示者的通用类型的 View 界面,​​反之亦然。这些接口(interface)将由实现开发人员扩展。这个问题对具体接口(interface)不感兴趣,但它们的类定义如下所示:

public interface Presenter<T extends View>


public interface View<T extends Presenter>

这个想法是 View 和 Presenter 都知道相反的接口(interface)。

为了使用这种结构,开发人员应该提供一个工厂,实例化他想要显示的 View 和处理这个 View 的演示者。他将它们都交给了一个名为 SuperController 的类。它们由 View 的类关联。

创建 Presenter 的 PresenterFactory 接口(interface)没有参数并返回一个 Presenter 实现,如下所示:
public interface PresenterFactory<T extends View> {

<S extends Presenter<T>> S create();

}

创建 View 的 ViewFactory 接口(interface)基于 Presenter 创建了一个 View 实现,如下所示:
public interface ViewFactory<T extends View, S extends Presenter<T>> {

T create(S presenter);

}

问题

我遇到的问题如下:

我想提供一个带有 TestView 和 TestPresenter 的示例。那些看起来像这样:
public interface TestPresenter extends Presenter<TestView> {...}

public interface TestView extends View<TestPresenter> {...}

此外,还提供了一个 ViewFactory,如下所示:
class TestViewFactory implements ViewFactory<TestView, TestPresenter> {

@Override
public TestView create(TestPresenter presenter) {
return new TestViewImpl(presenter);
}
}

这是 TestPresenterFactory:
private class TestPresenterFactory implements PresenterFactory<TestView> {

@Override
public <S extends Presenter<TestView>> S create() {
return new TestPresenterImpl();
}
}

此代码 不能 被编译。问题是 TestPresenterFactory 的返回值。 Java 说,它需要 S 而不是 TestPresenterImpl。此外,转换到 TestPresenter 将不起作用。但是,类型转换到 S 工作。它可以编译并成功运行,但这不是我希望实现开发人员做的事情。

为什么会存在这个问题?为什么转换到具体接口(interface)不起作用?在我看来,这应该可行,因为 TestPresenterImpl 实现了 TestPresenter,它扩展了泛型类型 TestView 的 Presenter 但它是不可编译的。

以下 工作。如果您像这样更改 PresenterFactory 定义:
public interface PresenterFactory<T extends View, S extends Presenter<T>> {

S create();

}

示例实现现在看起来像这样:
private class TestPresenterFactory implements PresenterFactory<TestView, TestPresenter> {

@Override
public TestPresenter create() {
return new TestPresenterImpl();
}
}

它可以被编译和运行,就像我在上面的例子中强制转换为 S 一样。

然而,这是 不是 我想要的是。泛型类型声明是多余的。让实现开发人员声明 View 演示者,只创建演示者看起来很尴尬。如果可以在方法中推断出类型,那就太好了。

另外,我不想强​​迫实现开发人员强制转换为 S。

有没有更优雅的方法呢?

编辑

一个问题被提出作为重复,我想远离 this question .

由此产生的问题与Producer Extends Consumer Super无关。我有两个生产者(工厂)在使用。两者都在产生一个类。一个依赖于另一个类(View 依赖于Presenter),而另一个没有依赖(Presenter 可以用默认构造函数实例化)。所有受尊重的接口(interface)都具有 T 扩展 XYZ 定义,以允许产生继承该接口(interface)(Presenter 或 View)的接口(interface)。

这里真正的问题是 ViewFactory 中的泛型可以被 Java 推断出来。这两种泛型类型都在类定义中声明。在 PresenterFactory 中,Java 无法推断方法级泛型。尽管如此,泛型类型与 View 工厂中的类型相同 <S extends Presenter<T>> ;在方法中,无法推断出这种类型。

解决方案是强制转换(我不希望使用开发人员这样做)或在类定义中声明 PresenterType(这似乎是多余的。唯一感兴趣的是, View 已定义并且任何 Presenter返回该 View )。

我的问题是我可以做些什么来解决由 extends 子句导致的上述问题?

最佳答案

对于初学者来说,这将解决问题:

interface PresenterFactory<T extends View, S extends Presenter<T>> {
S create();
}

class TestPresenterFactory implements PresenterFactory<TestView, TestPresenterImpl> {

@Override
public TestPresenterImpl create() {
return new TestPresenterImpl();
}
}

但我还是不喜欢:
  • View 和 Presenter 之间的循环依赖;
  • 原始类型的使用:实际上,如果你盲目使用 View<?>Presenter<?>在它们各自的接口(interface)声明中,然后它也不会编译(TestPresenterFactory 会失败)。

  • --- 编辑 ---

    那么如何解决最后两点以及您的原始问题:
    interface Presenter<P extends Presenter<P, V>, V extends View<P, V>> {

    }

    interface View<P extends Presenter<P, V>, V extends View<P, V>> {

    }

    interface PresenterFactory<P extends Presenter<P, V>, V extends View<P, V>> {

    P create();

    }

    interface ViewFactory<P extends Presenter<P, V>, V extends View<P, V>> {

    V create(P presenter);

    }

    interface TestPresenter extends Presenter<TestPresenter, TestView> {}

    class TestPresenterImpl implements TestPresenter {

    }

    interface TestView extends View<TestPresenter, TestView> {}

    class TestViewImpl implements TestView {

    public TestViewImpl(Presenter<?, ?> presenter) {
    }
    }

    class TestViewFactory implements ViewFactory<TestPresenter, TestView> {

    @Override
    public TestView create(TestPresenter presenter) {
    return new TestViewImpl(presenter);
    }
    }

    class TestPresenterFactory implements PresenterFactory<TestPresenter, TestView> {

    @Override
    public TestPresenter create() {
    return new TestPresenterImpl();
    }
    }

    关于java - 避免在基于通用工厂的 MVP 框架中进行强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52082791/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com