广泛应用工厂模式

时间:2018-11-21 21:26:57

标签: java design-patterns factory

我正在开发游戏,在很多情况下我需要某种工厂模式。 为了不创建许多Factory类方法,我改用Supplier<T>。这很好用,但如果有必要的参数,则不能。

在这种情况下有效:() -> new Spawn(3, 6, "example");

但是有时候我需要将其他参数传递给工厂。 ConsumerBiConsumer接受两个参数。但是没有3、4、5 ...的接口。

我想出了一个解决该问题的尴尬方案,但它说明了我正在尝试实现的目标。还有什么其他解决方案?

import java.util.function.Function;

public class FactoryExample {

    static class Args {
        Object[] objs;
        Args(Object ...objs) { this.objs = objs; }
        Object[] get() { return objs; }
    }

    static class Thing {
        int a; char b; boolean c;
        Thing(int a, char b, boolean c) {
            this.a = a; this.b = b; this.c = c; }
    }

    static class Number {
        int x;
        Number(int x) { this.x = x; }
    }


    public static void main(String[] args) {

        Function<Args, Number> factoryA = arg -> {
            int x = (int) arg.get()[0];
            return new Number(x);   
        };

        Function<Args, Thing> factoryB = arg -> {
            int a = (int) arg.get()[0];
            char b = (char) arg.get()[1];
            boolean c = (boolean) arg.get()[2];
            return new Thing(a, b, c);
        };

        factoryB.apply(new Args(3, 'a', true));
        factoryA.apply(new Args(3));
    }

}

示例:如何避免创建一堆这样的工厂?

public class InfectionFactory {

    private Integer damage;
    private Integer delay;
    private Integer hits;
    private Integer spikes;
    private Color color;

    public InfectionFactory setColor(Color color) {
        this.color = color;
        return this;
    }

    public InfectionFactory setSpikes(int spikes) {
        this.spikes = spikes;
        return this;
    }

    public InfectionFactory setDamage(int damage) {
        this.damage = damage;
        return this;
    }

    public InfectionFactory setDelay(int delay) {
        this.delay = delay;
        return this;
    }

    public InfectionFactory setHits(int hits) {
        this.hits = hits;
        return this;
    }

    public Infection create(Game game, Living target) {
        Infection infection = new Infection(game, target);

        if (damage  != null) infection.setDamage(damage);
        if (color   != null) infection.setColor(color);
        if (delay   != null) infection.setDelay(delay);
        if (hits    != null) infection.setHits(hits);
        if (spikes  != null) infection.setSpikes(spikes);

        return infection;
    }

}

1 个答案:

答案 0 :(得分:0)

您似乎有多个要求。首先,要使Supplier接受所需的所有参数,可以执行以下操作:

public class SpawnFactory implements Supplier<Spawn> {
  //todo: put members for all the arguments you need, make them final so that you don't miss any in the constructor

  public SpawnFactory( ... all the arguments you want ... ) {

  }

  public Spawn get() {
    return new Spawn( ... all the arguments you want ...);
  }
}

由于它实现了Supplier,因此您可以按照自己喜欢的方式直接实例化它们。不用() -> new Spawn(3, 6, "example"),而要做new SpawnFactory(3, 6, "example");

另一方面,您的InfectionFactory的示例遵循构建器模式(您可能希望将其重命名为InfectionBuilder)。一切都没错(除了Infection也使用相同的模式这似乎有点多余之外)

您可能希望使其使用GameLiving作为构造函数参数,然后您的create()将不需要任何参数。最后一步是制作类implement Supplier<Infection>并添加只调用Infection get()的{​​{1}}(除非您想将create()重命名为create())。