Can a builder pattern do too much?

I recently studied design patterns in a research team and realized that a builder pattern can be very useful for creating complex objects that consist of many (potentially optional) parts.

However, is there ever a moment when a builder does too much? Say we have a class that has many different combinations of objects, is there another template that might be better suited for this, instead of creating dozens of different developers? Is it possible to reduce the number of builders that you need without creating completely specific builders?

An example of my research team, and I kept coming back, was an auto builder, for example, on a car company website. Any car company has dozens of cars, each of which has many different functions, colors, additions, etc. As I understand it, your builder should be specific to the specific object that you are doing, so applying a builder pattern to this example will give hundreds of builders that look like "RedSUVWithSunroofBuilder", "BlueSUVWithSunroofBuilder", "RedSUVBuilder, etc.

Is there any reason that, using the builder pattern, I could not pass some of these values ​​in order to reduce the number of developers that I would need to create? For example, instead of having RedSUVWithSunroofBuilder or BlueSUVWithSunroofBuilder, is the build template still suitable for SUVWithSunroofBuilder ("Red") and SUVWithSunroofBuilder ("Blue"), or is it more suitable for another template?

+3
source share
5 answers

, , , , , , factory. , , :

, :

public class Car {
    private final boolean hasSunroof;
    private final Color color;
    private final int horsePower;
    private final String modelName;

    private Car(Color color, int horsePower, String modelName, boolean hasSunroof) {
        this.color = color;
        this.horsePower = horsePower;
        this.hasSunroof = hasSunroof;
        this.modelName = modelName;
    }

    public static Builder builder(Color color, int horsePower) {
        return new Builder(color, horsePower);
    }

    public static class Builder {
        private final Color color;
        private final int horsePower;
        private boolean hasSunroof;
        private String modelName = "unknown";

        public Builder(Color color, int horsePower) {
            this.color = color;
            this.horsePower = horsePower;
        }

        public Builder withSunroof() {
            hasSunroof = true;
            return this;
        }

        public Builder modelName(String modelName) {
            this.modelName = modelName;
            return this;
        }

        public Car createCar() {
            return new Car(color, horsePower, modelName, hasSunroof);
        }
    }
}

Builder , , API. , . :

Car car = Car.builder(Color.WHITE, 500).withSunroof().modelName("Mustang").createCar();
+5

, , step builder pattern ( ).

, .

:

  • , , .
  • .
  • - BuildStep, , .
+5

Builder, ( Java), Builder , . , Java, Java.

, -- , , . , , .

, , - , , 5-7 , .

, , , .

, , , , .. , , .

+2

, , . . , . . .

Car c = new SUVBuilder().withSunroof().withColor("Red").build();

, SUV . , SUV .

+2

. , AssemblyLine , :

buildChassis();
buildDriveTrain();
buildBody();
assemble();
paint();

You may need separate concrete collectors for different chassis, drive trains and bodies, but you can probably get away with just one for paint - you just parameterize it for color in c'tor. Your director class knows what the details of your builder are, so he creates the right concrete builders; your assembly line customer just follows the steps in order. You can parameterize specific assemblers for any parts that are not fundamental (and what is fundamental to the solution).

0
source

Source: https://habr.com/ru/post/1786438/


All Articles