通用对象工厂

时间:2019-07-12 09:14:20

标签: java generics factory

我有几个基于DataObject类创建的对象。 所以我想让通用工厂来构造它们。

我尝试过这样的事情:

interface FactoryObject<T> {
    T create(DataObject data);
}

public class Factory {
    List<FactoryObject> fromDataObjectArray(DataObject[] data, Class<? extends FactoryObject> cls) {
        return Arrays.stream(Optional.ofNullable(data).orElse(new DataObject[0]))
               .map(d -> cls.create()).collect(Collectors.toList());
    }
}

最后,我想打电话

List<MyClass> myClasses = Factory.fromDataObjectArray(data, MyClass.class);

但是方法create()无法解决,我该如何实现所需的条件?

1 个答案:

答案 0 :(得分:1)

如果我理解您的代码,那么您想创建一个实例列表;您可以这样做:

<T> List<T> fromDataObjectArray(DataObject[] data, FactoryObject<T> fac) {
    return Arrays.stream(Optional.ofNullable(data).orElse(new DataObject[0]))
           .map(d -> fac.create(d)).collect(Collectors.toList());
}

更新:

如果我理解您在下面的评论,则您需要一个组合工厂,该工厂将从DataObject中确定您要用于创建实例的实际工厂。

您可以执行以下操作:

public class CompositeFactory<T> implements FactoryObject<T> {
    private final Function<DataObject,FactoryObject<? extends T>>[] funcs;

    public CompositeFactory(
            Function<DataObject,FactoryObject<? extends T>>... funcs) {
        this.funcs = funcs;
    }

    @Override
    public T create(DataObject data) {
        for (Function<DataObject,FactoryObject<? extends T>> func: funcs) {
            FactoryObject<? extends T> fac = func.apply(data);
            if (fac != null) {
                return fac.create(data);
            }
        }
        return null; // or throw an exception
    }
}

另一种方法是条件工厂:

public class ConditionalFactory<T> implements FactoryObject<T> {
    private final Predicate<DataObject> cond;
    private final FactoryObject<? extends T> ifFac;
    private final FactoryObject<? extends T> elseFac;

    public ConditionalFactory(Predicate<DataObject> cond,
            FactoryObject<? extends T> ifFac,
            FactoryObject<? extends T> elseFac) {
        this.cond = cond;
        this.ifFac = ifFac;
        this.elseFac = elseFac;
    }

    @Override
    public T create(DataObject data) {
        return (cond.test(data) ? ifFac : elseFac).create(data);
    }
}

更新2:

示例:假设您有以下课程:

class MyClass1 extends MyClass {
    public MyClass1(DataObject data) {
    }
}

class MyClass2 extends MyClass {
    public MyClass2(DataObject data) {
    }
}

...

和相应的工厂:

FactoryObject<MyClass1> fac1 = (data) -> new MyClass1(data);
FactoryObject<MyClass2> fac2 = (data) -> new MyClass2(data);
FactoryObject<MyClass3> fac3 = (data) -> new MyClass3(data);
...

,假设您可以根据DataObject.getType()的值确定实际的类:

您可以这样做:

FactoryObject<MyClass> fact = new CompositeFactory<MyClass>(
    (data)-> data.getType().equals("value1") ? fac1 : null,
    (data)-> data.getType().equals("value2") ? fac2 : null,
    (data)-> data.getType().equals("value3") ? fac3 : null,
    ...
);

您也可以这样做:

FactoryObject<MyClass> fac = new CompositeFactory<MyClass>(
    (data)->{
        switch (data.getType()) {
            case "value1":
                return fac1;
            case "value2":
                return fac2;
    ...
            default:
                return null;
        }
    });

或:

FactoryObject<MyClass> fac = new ConditionalFactory<MyClass>(
        (data)->data.getType().equals("value1"), fac1,
        new ConditionalFactory<MyClass>(
                (data)->data.getType().equals("value2"), fac2,
                fac3));