我正在开发游戏,在很多情况下我需要某种工厂模式。
为了不创建许多Factory类方法,我改用Supplier<T>
。这很好用,但如果有必要的参数,则不能。
在这种情况下有效:() -> new Spawn(3, 6, "example");
但是有时候我需要将其他参数传递给工厂。
Consumer
和BiConsumer
接受两个参数。但是没有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;
}
}
答案 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
也使用相同的模式这似乎有点多余之外)
您可能希望使其使用Game
和Living
作为构造函数参数,然后您的create()
将不需要任何参数。最后一步是制作类implement Supplier<Infection>
并添加只调用Infection get()
的{{1}}(除非您想将create()
重命名为create()
)。>