Applying Factory Pattern Extensively
I'm developing a game and there are tons of occasions where I need some sort of factory pattern involved.
In an attempt not to create lots of Factory class methods, I used Supplier<T>
instead. This works great but not if there are required arguments.
It works in this case: () -> new Spawn(3, 6, "example");
But sometimes I need to pass other parameters to the factory.
There's the Consumer
and BiConsumer
which accept two parameters. But there's no interface for 3, 4, 5...
I came up with an embarassing solution to this problem, but it illustrates what I'm trying to achieve. What other solutions are there?
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));
}
}
Example: how do I avoid creating a bunch of these factories?
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;
}
}
java design-patterns factory
add a comment |
I'm developing a game and there are tons of occasions where I need some sort of factory pattern involved.
In an attempt not to create lots of Factory class methods, I used Supplier<T>
instead. This works great but not if there are required arguments.
It works in this case: () -> new Spawn(3, 6, "example");
But sometimes I need to pass other parameters to the factory.
There's the Consumer
and BiConsumer
which accept two parameters. But there's no interface for 3, 4, 5...
I came up with an embarassing solution to this problem, but it illustrates what I'm trying to achieve. What other solutions are there?
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));
}
}
Example: how do I avoid creating a bunch of these factories?
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;
}
}
java design-patterns factory
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30
add a comment |
I'm developing a game and there are tons of occasions where I need some sort of factory pattern involved.
In an attempt not to create lots of Factory class methods, I used Supplier<T>
instead. This works great but not if there are required arguments.
It works in this case: () -> new Spawn(3, 6, "example");
But sometimes I need to pass other parameters to the factory.
There's the Consumer
and BiConsumer
which accept two parameters. But there's no interface for 3, 4, 5...
I came up with an embarassing solution to this problem, but it illustrates what I'm trying to achieve. What other solutions are there?
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));
}
}
Example: how do I avoid creating a bunch of these factories?
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;
}
}
java design-patterns factory
I'm developing a game and there are tons of occasions where I need some sort of factory pattern involved.
In an attempt not to create lots of Factory class methods, I used Supplier<T>
instead. This works great but not if there are required arguments.
It works in this case: () -> new Spawn(3, 6, "example");
But sometimes I need to pass other parameters to the factory.
There's the Consumer
and BiConsumer
which accept two parameters. But there's no interface for 3, 4, 5...
I came up with an embarassing solution to this problem, but it illustrates what I'm trying to achieve. What other solutions are there?
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));
}
}
Example: how do I avoid creating a bunch of these factories?
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;
}
}
java design-patterns factory
java design-patterns factory
edited Nov 21 '18 at 21:32
Afonso Matos
asked Nov 21 '18 at 21:26


Afonso MatosAfonso Matos
1,027920
1,027920
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30
add a comment |
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30
add a comment |
1 Answer
1
active
oldest
votes
You seem to have multiple requirements. First of all, to make the Supplier
take all the arguments you want, you can do something like:
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 ...);
}
}
Since it implements Supplier
, you can pass them directly instantiated the way you like. Instead of () -> new Spawn(3, 6, "example")
just do new SpawnFactory(3, 6, "example");
The example of your InfectionFactory
on the other hand is following the builder pattern (you might want to rename it InfectionBuilder
). Nothing is wrong with this (apart from the fact that it seems a bit redundant since Infection
is using the same pattern too)
You might want to make it take the Game
and Living
as constructor arguments instead, and then your create()
will not need any arguments. Your last step would be to make the class implement Supplier<Infection>
and add Infection get()
which just calls create()
(unless you want to rename create()
to get()
).
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420684%2fapplying-factory-pattern-extensively%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You seem to have multiple requirements. First of all, to make the Supplier
take all the arguments you want, you can do something like:
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 ...);
}
}
Since it implements Supplier
, you can pass them directly instantiated the way you like. Instead of () -> new Spawn(3, 6, "example")
just do new SpawnFactory(3, 6, "example");
The example of your InfectionFactory
on the other hand is following the builder pattern (you might want to rename it InfectionBuilder
). Nothing is wrong with this (apart from the fact that it seems a bit redundant since Infection
is using the same pattern too)
You might want to make it take the Game
and Living
as constructor arguments instead, and then your create()
will not need any arguments. Your last step would be to make the class implement Supplier<Infection>
and add Infection get()
which just calls create()
(unless you want to rename create()
to get()
).
add a comment |
You seem to have multiple requirements. First of all, to make the Supplier
take all the arguments you want, you can do something like:
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 ...);
}
}
Since it implements Supplier
, you can pass them directly instantiated the way you like. Instead of () -> new Spawn(3, 6, "example")
just do new SpawnFactory(3, 6, "example");
The example of your InfectionFactory
on the other hand is following the builder pattern (you might want to rename it InfectionBuilder
). Nothing is wrong with this (apart from the fact that it seems a bit redundant since Infection
is using the same pattern too)
You might want to make it take the Game
and Living
as constructor arguments instead, and then your create()
will not need any arguments. Your last step would be to make the class implement Supplier<Infection>
and add Infection get()
which just calls create()
(unless you want to rename create()
to get()
).
add a comment |
You seem to have multiple requirements. First of all, to make the Supplier
take all the arguments you want, you can do something like:
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 ...);
}
}
Since it implements Supplier
, you can pass them directly instantiated the way you like. Instead of () -> new Spawn(3, 6, "example")
just do new SpawnFactory(3, 6, "example");
The example of your InfectionFactory
on the other hand is following the builder pattern (you might want to rename it InfectionBuilder
). Nothing is wrong with this (apart from the fact that it seems a bit redundant since Infection
is using the same pattern too)
You might want to make it take the Game
and Living
as constructor arguments instead, and then your create()
will not need any arguments. Your last step would be to make the class implement Supplier<Infection>
and add Infection get()
which just calls create()
(unless you want to rename create()
to get()
).
You seem to have multiple requirements. First of all, to make the Supplier
take all the arguments you want, you can do something like:
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 ...);
}
}
Since it implements Supplier
, you can pass them directly instantiated the way you like. Instead of () -> new Spawn(3, 6, "example")
just do new SpawnFactory(3, 6, "example");
The example of your InfectionFactory
on the other hand is following the builder pattern (you might want to rename it InfectionBuilder
). Nothing is wrong with this (apart from the fact that it seems a bit redundant since Infection
is using the same pattern too)
You might want to make it take the Game
and Living
as constructor arguments instead, and then your create()
will not need any arguments. Your last step would be to make the class implement Supplier<Infection>
and add Infection get()
which just calls create()
(unless you want to rename create()
to get()
).
answered Nov 21 '18 at 21:39
jbxjbx
11.5k1060111
11.5k1060111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420684%2fapplying-factory-pattern-extensively%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Rather than posting a solution, can you post your real problem in code?
– jbx
Nov 21 '18 at 21:29
Sure @jbx ... updating
– Afonso Matos
Nov 21 '18 at 21:30