gpt4 book ai didi

java - 工厂模式和泛型

转载 作者:行者123 更新时间:2023-12-01 11:06:24 25 4
gpt4 key购买 nike

我有时会遇到这种情况,不确定我是否使用了不好的方法,或者我只是不知道如何解决它。

假设我有两个类和两个 bean,如下所示:

public class BeanOne {
public void methodBeanOne() {
//...
}
}

public class BeanTwo {
public void methodBeanTwo() {
//...
}
}

public class ClassOne {
private BeanOne bean;

public ClassOne(BeanOne bean) {
this.bean = bean;
}

public void methodclassOne() {
bean.methodBeanOne();
}
}

public class ClassTwo {
private BeanTwo bean;

public ClassTwo(BeanTwo bean) {
this.bean = bean;
}

public void methodClassTwo() {
bean.methodBeanTwo();
}
}

我想创建一个通用抽象类,这样我就可以从 ClassOneClassTwo 中提取一些逻辑,以及一个具有常用方法的抽象 bean:

public abstract class AbstractBean {
public void commonMethod() {
//...
}
}

public class BeanOne extends AbstractBean {
public void methodBeanOne() {
//...
}
}

public class BeanTwo extends AbstractBean {
public void methodBeanTwo() {
//...
}
}

public abstract class AbstractClass<T extends AbstractBean> {
protected T bean;

public AbstractClass(T bean) {
this.bean = bean;
}

public void commonClassMethod(){
bean.commonMethod();
}
}

public class ClassOne extends AbstractClass<BeanOne> {

public ClassOne(BeanOne bean) {
super(bean);
}

public void methodclassOne() {
bean.methodBeanOne();
}
}

public class ClassTwo extends AbstractClass<BeanTwo> {

public ClassTwo(BeanTwo bean) {
super(bean);
}

public void methodClassTwo() {
bean.methodBeanTwo();
}
}

到目前为止,一切顺利。

下一步是创建一个工厂来获得一个基于enum的实现,例如,这是我开始收到错误的地方:

public class ClassFactory {

public enum MyEnum {
ONE, TWO;
}

private ClassFactory() {
}

public static AbstractClass newInstance(MyEnum value, AbstractBean bean) {
switch(value){
case ONE:
return new ClassOne(bean);
case TWO:
return new ClassTwo(bean);
default:
throw new IllegalArgumentException();
}
}
}

这会产生以下编译错误:

The constructor ClassOne(AbstractBean) is undefined
The constructor ClassTwo(AbstractBean) is undefined

我也尝试过:

public class ClassFactory {

public enum MyEnum {
ONE, TWO;
}

private ClassFactory() {
}

public static <T extends AbstractBean> AbstractClass<T> newInstance(MyEnum value, T bean) {
switch(value){
case ONE:
return new ClassOne(bean);
case TWO:
return new ClassTwo(bean);
default:
throw new IllegalArgumentException();
}
}
}

但后来我得到:

Type mismatch: cannot convert from ClassOne to AbstractClass<T>
Type mismatch: cannot convert from ClassTwo to AbstractClass<T>

我几乎被困在那里。我想我理解这个错误,但是,是否可以创建这样一个工厂类试图避免强制转换

我还检查过this post ,但无法完全理解它对我有何帮助。

编辑:访客模式

好的,所以我尝试了上一篇文章中描述的访问者模式:

public interface Visitor<T> {
T visit(BeanOne bean);

T visit(BeanTwo bean);
}

public abstract class AbstractBean {
public void commonMethod() {
// ...
}

public abstract <T> T accept(Visitor<T> visitor);
}

public class BeanOne extends AbstractBean {
public void methodBeanOne() {
// ...
}

@Override
public <T> T accept(Visitor<T> visitor) {
return visitor.visit(this);
}
}

public class BeanTwo extends AbstractBean {
public void methodBeanTwo() {
// ...
}

@Override
public <T> T accept(Visitor<T> visitor) {
return visitor.visit(this);
}
}

public class ClassFactory {
private ClassFactory() {
}

public static AbstractClass<? extends AbstractBean> newInstance(AbstractBean bean) {
return bean.accept(new AbstractClassVisitor());
}
}

public class AbstractClassVisitor implements Visitor<AbstractClass<? extends AbstractBean>> {

@Override
public AbstractClass<? extends AbstractBean> visit(BeanOne bean) {
return ClassFactory.newInstance(bean);
}

@Override
public AbstractClass<? extends AbstractBean> visit(BeanTwo bean) {
return ClassFactory.newInstance(bean);
}
}

但是像这样使用它:

AbstractBean bean = new BeanOne();
AbstractClass<? extends AbstractBean> clazz = ClassFactory.newInstance(bean);
clazz.commonClassMethod();

我遇到以下异常:

Exception in thread "main" java.lang.StackOverflowError
at test.AbstractClassVisitor.<init>(AbstractClassVisitor.java:3)
at test.ClassFactory.newInstance(ClassFactory.java:9)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:7)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:1)
at test.BeanOne.accept(BeanOne.java:10)
at test.ClassFactory.newInstance(ClassFactory.java:9)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:7)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:1)
at test.BeanOne.accept(BeanOne.java:10)
at test.ClassFactory.newInstance(ClassFactory.java:9)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:7)
at test.AbstractClassVisitor.visit(AbstractClassVisitor.java:1)
at test.BeanOne.accept(BeanOne.java:10)
...

我明白为什么会发生这种情况,我是否错过了什么?

最佳答案

根据您自己提供的问题,请参阅以下答案:https://stackoverflow.com/a/12630501/144302

同样的原则适用于您的问题:使用具有重载方法的工厂

public class ClassFactory {

private ClassFactory() {
}

public static AbstractClass<BeanOne> newInstance(BeanOne bean) {
return new ClassOne(bean);
}

public static AbstractClass<BeanTwo> newInstance(BeanTwo bean) {
return new ClassTwo(bean);
}
}

或者,正如答案中所指出的,应用双分派(dispatch)等原则,在其中添加方法 AbstractClass<T> newInstance()AbstractBean并在各专业中适当实现。例如

class BeanOne { /* ... */ 
public AbstractBean<BeanOne> newInstance() {
return ClassFactory.newInstance(this);
}
}

您终于可以将以下方法添加到ClassFactory

public static <T> AbstractClass<T> newInstance(AbstractBean<T> bean) {
return bean.newInstance();
}

对于具体的优点和缺点,我建议您阅读另一个问题中的整个答案(非常好,我不想盲目复制别人的工作)。

关于java - 工厂模式和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32903267/

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