How to enforce order of setting parameters through Builder Pattern
Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.
I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?
class Example{
private int A;
private int B;
public static class Builder{
}
}
java builder-pattern
add a comment |
Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.
I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?
class Example{
private int A;
private int B;
public static class Builder{
}
}
java builder-pattern
3
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41
add a comment |
Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.
I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?
class Example{
private int A;
private int B;
public static class Builder{
}
}
java builder-pattern
Recently, I was asked in an interview to implement Builder Pattern in such a way that user cannot set a parameter B unless parameter A is set.
I suggested to pass A as a required parameter when constructing the Builder but he was not satisfied with my answer.
I also suggested to throw IllegelStateException if A is not set when setting B but again he was not satisfied.
Could anyone suggest how can we enforce user to set A before he sets B?
class Example{
private int A;
private int B;
public static class Builder{
}
}
java builder-pattern
java builder-pattern
asked Jan 1 at 9:32
rakkurakku
111
111
3
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41
add a comment |
3
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41
3
3
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41
add a comment |
2 Answers
2
active
oldest
votes
To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.
Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.
add a comment |
the main idea is to use a different return type in setA
setB
method, but those type must be the same type or subtype of the builder type.
public class ExampleBuilderImpl implements FullExampleBuilder {
private int a;
private int b;
public Example createExample() {
return new Example(a, b);
}
@Override
public PartExampleBuilder setB(int b) {
this.b = b;
return this;
}
@Override
public FullExampleBuilder setA(int a) {
this.a = a;
return this;
}
public static void main(String args) {
ExampleBuilderImpl builder = new ExampleBuilderImpl();
// compiler error
// builder.setB(1).setA();
builder.setA(1).setB(2);
}
}
public interface FullExampleBuilder extends PartExampleBuilder {
FullExampleBuilder setA(int a);
}
public interface PartExampleBuilder {
PartExampleBuilder setB(int b);
}
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%2f53994370%2fhow-to-enforce-order-of-setting-parameters-through-builder-pattern%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.
Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.
add a comment |
To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.
Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.
add a comment |
To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.
Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.
To do it in plain Java, you would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
One of the limitations of this approach is that it is very verbose, and doesn't scale well to having lots of optional parameters.
Alternatively, I have done this by writing a compiler plugin (I used Error Prone, since that is easiest to do with Google's build system, but there is no reason another tool couldn't be used) which checks the method call order.
answered Jan 1 at 9:42
Andy TurnerAndy Turner
83.4k983141
83.4k983141
add a comment |
add a comment |
the main idea is to use a different return type in setA
setB
method, but those type must be the same type or subtype of the builder type.
public class ExampleBuilderImpl implements FullExampleBuilder {
private int a;
private int b;
public Example createExample() {
return new Example(a, b);
}
@Override
public PartExampleBuilder setB(int b) {
this.b = b;
return this;
}
@Override
public FullExampleBuilder setA(int a) {
this.a = a;
return this;
}
public static void main(String args) {
ExampleBuilderImpl builder = new ExampleBuilderImpl();
// compiler error
// builder.setB(1).setA();
builder.setA(1).setB(2);
}
}
public interface FullExampleBuilder extends PartExampleBuilder {
FullExampleBuilder setA(int a);
}
public interface PartExampleBuilder {
PartExampleBuilder setB(int b);
}
add a comment |
the main idea is to use a different return type in setA
setB
method, but those type must be the same type or subtype of the builder type.
public class ExampleBuilderImpl implements FullExampleBuilder {
private int a;
private int b;
public Example createExample() {
return new Example(a, b);
}
@Override
public PartExampleBuilder setB(int b) {
this.b = b;
return this;
}
@Override
public FullExampleBuilder setA(int a) {
this.a = a;
return this;
}
public static void main(String args) {
ExampleBuilderImpl builder = new ExampleBuilderImpl();
// compiler error
// builder.setB(1).setA();
builder.setA(1).setB(2);
}
}
public interface FullExampleBuilder extends PartExampleBuilder {
FullExampleBuilder setA(int a);
}
public interface PartExampleBuilder {
PartExampleBuilder setB(int b);
}
add a comment |
the main idea is to use a different return type in setA
setB
method, but those type must be the same type or subtype of the builder type.
public class ExampleBuilderImpl implements FullExampleBuilder {
private int a;
private int b;
public Example createExample() {
return new Example(a, b);
}
@Override
public PartExampleBuilder setB(int b) {
this.b = b;
return this;
}
@Override
public FullExampleBuilder setA(int a) {
this.a = a;
return this;
}
public static void main(String args) {
ExampleBuilderImpl builder = new ExampleBuilderImpl();
// compiler error
// builder.setB(1).setA();
builder.setA(1).setB(2);
}
}
public interface FullExampleBuilder extends PartExampleBuilder {
FullExampleBuilder setA(int a);
}
public interface PartExampleBuilder {
PartExampleBuilder setB(int b);
}
the main idea is to use a different return type in setA
setB
method, but those type must be the same type or subtype of the builder type.
public class ExampleBuilderImpl implements FullExampleBuilder {
private int a;
private int b;
public Example createExample() {
return new Example(a, b);
}
@Override
public PartExampleBuilder setB(int b) {
this.b = b;
return this;
}
@Override
public FullExampleBuilder setA(int a) {
this.a = a;
return this;
}
public static void main(String args) {
ExampleBuilderImpl builder = new ExampleBuilderImpl();
// compiler error
// builder.setB(1).setA();
builder.setA(1).setB(2);
}
}
public interface FullExampleBuilder extends PartExampleBuilder {
FullExampleBuilder setA(int a);
}
public interface PartExampleBuilder {
PartExampleBuilder setB(int b);
}
answered Jan 1 at 11:42
宏杰李宏杰李
8,76921123
8,76921123
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%2f53994370%2fhow-to-enforce-order-of-setting-parameters-through-builder-pattern%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
3
You would need to create separate Builder classes, the first for setting the A, whereupon the returned value is an instance of the second Builder which is for setting B.
– Andy Turner
Jan 1 at 9:35
@AndyTurner, say, i have another field C, I would not be able to set the value of C, if I had set the value of A first, as it would return the builder for field B. Or would I be able to?
– Ankur
Jan 1 at 9:41