Reputation: 1
I have such a construction :
private Plan createPlan() {
return new Plan(
project(),
"Plan Name", "PLANKEY")
.description("Plan created from (enter repository url of your
plan)")
.stages(
new Stage("Stage 1")
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”))),
new Stage("Stage 2”)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”))),
new Stage("Stage 3”)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”))),
new Stage("Stage 4”)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”))),
);
}
How to avoid duplication of code? Pieces of code inside "new stage" are identical, with same paramertrs except name of new stage ("Stage 1", "Stage 2", "Stage 3"...).
Thank you!
Upvotes: 0
Views: 120
Reputation: 420
(The long and hard solution (but will benefit you later on)) One solution could be to hide the instance creation away with a Factory design pattern: https://www.youtube.com/watch?v=ub0DXaeV6hA
That's usually the solution if you don't want to write long class installations.
(The easy and quick solution): You could also just make a method called CreateStage(String stageName) that takes a String input, namely the name of the stage, and returns a new created Stage object:
public Stage CreateStage(String stageName){
return new Stage(stageName)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”)));
}
And just call that for each stage you want in your stages collection. :-)
For more tips, Google: How to avoid code-duplication.
Upvotes: 1
Reputation: 11739
You add the same object 4 times:
Job commonJob = new Job("Build & run", "RUN").tasks(
new ScriptTask().inlineBody("echo Hello!”));
Why not assigning it to a variable and just use it instead?
new Stage("Stage 1").jobs(commonJob),
new Stage("Stage 2").jobs(commonJob),
...
Which is still not ideal because you have to create Stage
objects "manually". If Plan#stages
has an var-args signature Plan.stages(Stage ... stages)
, you can use a for-loop
.
Stage[] stages = new Stage[4];
for(int i = 0; i < stages.length; i ++) {
stages[i] = new Stage("Stage " + (i + 1)).jobs(commonJob);
}
and later on new Plan().stages(stages);
Or you can even do in a functional way if you wish using java-9
IntStream.interate
method:
new Plan().stages(
IntStream.iterate(1, i -> i < 5, i -> i + 1)
.mapToObj(i -> new Stage("Stage " + i).jobs(commonJob))
.toArray()
);
Upvotes: 0
Reputation: 533
This assumes that the function stages takes an array of stages as a parameter. Create a list of stages then convert to an array and pass that in.
private Plan createPlan() {
List<Stage> stagesList = new ArrayList<>();
for(int i = 1; i < 5; i++) {
stages.add(new Stage("Stage " + i)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”)))
} // end of for
Stage[] stagesArray = new Stage[stagesList];
stagesArray = stagesList.toArray(stagesArray);
return new Plan(
project(),
"Plan Name", "PLANKEY")
.description("Plan created from (enter repository url of your
plan)")
.stages(stagesArray);
} // end of createPlan
Upvotes: 0
Reputation: 2890
Extract a method:
private Stage createStage(String name) {
return new Stage(name)
.jobs(new Job("Build & run", "RUN")
.tasks(
new ScriptTask().inlineBody("echo Hello!”))
}
and simply pass the stage names
...
.stages(createStage("Stage 1"), createStage("Stage 2"), createStage("Stage 3"), createStage("Stage 4"))
Upvotes: 1
Reputation: 2923
Be careful about trying to over-optimize your code. If a Plan has four stages, then you will need to add the four stages. You could add a loop, but that implies you have some source of values for your loop, such as a List of some sort. Personally, I would stick with what you have, until your requirements lead you to refactor.
Upvotes: 0