아무거나

[Design Pattern] Builder Pattern 본문

Java/Java

[Design Pattern] Builder Pattern

전봉근 2019. 12. 8. 22:47
반응형

빌더 패턴(Builder Pattern)

개념을 보기 앞서 빌더 패턴 2개를 소개하였는데 첫번째 빌더 패턴은 책에서 나용 내용이고 실질적으로 두번째 빌더 패턴을 많이 사용하므로 두번째를 숙지하는것이 좋다.

빌더 패턴이란 복잡한 단계를 거쳐야 생성되는 객체의 구현을 서브 클래스에게 넘겨주는 패턴

빌더 패턴 예시 - 1 ( 팩토리를 사용한 빌더 패턴 - 책 기준 )

먼저 복잡한 단계를 거쳐야 생성되는 객체를 Computer라는 객체로 생성해보자.
[Computer.java]

package com.bkjeon.builder;

public class Computer {

    private String cpu;
    private String ram;
    private String storage;

    public Computer(String cpu, String ram, String storage) {
        super();
        this.cpu = cpu;
        this.ram = ram;
        this.storage = storage;
    }

    public String getCpu() {
        return cpu;
    }

    public String getRam() {
        return ram;
    }

    public String getStorage() {
        return storage;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setRam(String ram) {
        this.ram = ram;
    }

    public void setStorage(String storage) {
        this.storage = storage;
    }

    @Override
    public String toString() {
        return cpu + "," + ram + "," + storage;
    }
}

메인 클래스를 생성해보자.
[Main.java]

package com.bkjeon.builder;

public class Main {

    public static void main(String[] args) {
        Computer computer = new Computer("i7", "16g", "256g ssd");
        System.out.println(computer.toString());
    }

}

실행결과

i7,16g,256g ssd

만약 컴퓨터가 원하는 것들이 인자가 엄청 많아지면 그 많은것들을 세팅하면 힘들 것이다. 그리고 cpu나 ram같은 경우도 다양한 방식이있고 모델이 존재할 것이다. 만약 그것들을 메인함수에서 사용한다고하면 코드 자체가 매우 복잡해진다. 그러면 생성하는것을 다른 객체들한테 넘겨주면 굉장히 쉬워질 수 있다.

[BluePrint.java]

package com.bkjeon.builder;

public abstract class BluePrint {

    abstract public void setCpu();
    abstract public void setRam();
    abstract public void setStorage();
    abstract public Computer getComputer();
}

[LgGramBlueprint.java]

package com.bkjeon.builder;

public class LgGramBlueprint extends BluePrint {

    private Computer computer;

    // 만약 컴퓨터가 없다고하면 컴퓨터가 가진 인자들을 이용해서 만들어 줄 수 있다.
    // 컴퓨터를 갖고 만든 부분은 주석처리 하였다.
    private String cpu;
    private String ram;
    private String storage;

    public LgGramBlueprint() {
//        computer = new Computer("default", "default", "default");
    }

    @Override
    public void setCpu() {
//        computer.setCpu("i7");
        cpu = "i7";

    }

    @Override
    public void setRam() {
//        computer.setRam("16g");
        ram = "8g";
    }

    @Override
    public void setStorage() {
//        computer.setStorage("256g ssd");
        storage = "256g ssd";
    }

    @Override
    public Computer getComputer() {
//        return computer;
        return new Computer(cpu, ram, storage);
    }

}

[ComputerFactory.java]

package com.bkjeon.builder;

public class ComputerFactory {

    private BluePrint print;

    public void setBlueprint(BluePrint print) {
        this.print = print;
    }

    public void make() {
        print.setRam();
        print.setCpu();
        print.setStorage();
    }

    public Computer getComputer() {
        return print.getComputer();
    }

}

[Main.java]

package com.bkjeon.builder;

public class Main {

    public static void main(String[] args) {
        // 설계도
        ComputerFactory factory = new ComputerFactory();
        // 다양한 Blueprint를 대입가능
        factory.setBlueprint(new LgGramBlueprint());
        factory.make();

        // 위의 설계도 과정에서 만들어진걸 넘겨준다.
        Computer computer = factory.getComputer();
        System.out.println(computer.toString());
    }

}

실행결과

i7,8g,256g ssd

즉, 복잡하게 생성되야 하는 객체를 보기 좋게 생성할 수 있도록 다른 객체에 책임을 떠넘겨서 사용하는 패턴을 빌더패턴이라고 한다.

빌더 패턴 예시 - 2 ( [제일 많이 쓰임] 팩토리를 사용한 빌더 패턴 - 실무 기준 )

많은 변수를 가진 객체의 생성가독성 높도록 코딩 할 수 있다.

먼저 Computer 클래스를 만들자.
[Computer.java]

package com.bkjeon.builder2;

public class Computer {

    private String cpu;
    private String ram;
    private String storage;

    public Computer(String cpu, String ram, String storage) {
        super();
        this.cpu = cpu;
        this.ram = ram;
        this.storage = storage;
    }

    public String getCpu() {
        return cpu;
    }

    public String getRam() {
        return ram;
    }

    public String getStorage() {
        return storage;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public void setRam(String ram) {
        this.ram = ram;
    }

    public void setStorage(String storage) {
        this.storage = storage;
    }

    @Override
    public String toString() {
        return cpu + "," + ram + "," + storage;
    }
}

그 다음 build 패턴을 사용하기위한 ComputerBuilder 클래스를 만들자.
[ComputerBuilder.java]

package com.bkjeon.builder2;

public class ComputerBuilder {

    private Computer computer;

    private ComputerBuilder() {
        computer = new Computer("default", "default", "default");
    }

    public static ComputerBuilder start() {
        return new ComputerBuilder();
    }

    public ComputerBuilder setCpu(String string) {
        computer.setCpu(string);
        return this;
    }

    public ComputerBuilder setRam(String string) {
        computer.setRam(string);
        return this;
    }

    public ComputerBuilder setStorage(String string) {
        computer.setStorage(string);
        return this;
    }

    public Computer build() {
        return this.computer;
    }

}

이제 메인 클래스에 적용해보자.
[Main.java]

package com.bkjeon.builder2;

public class Main {

    public static void main(String[] args) {
        // 아래 생성자 처럼 객체의 순서가 뒤바뀌는 문제가 생길수도 있다.
        // 이와 같은 상황을 주석 Document를 작성하면 되지만 객체가 많아진다면 사람이기 때문에 실수가 생길수도 있다.
        // 그러한 것들을 좀 더 명확하게 아래 빌더를 사용하면 예방할 수 있다.
        // Computer computer = new Computer("256g ssd", "i7", "8g");

        Computer computer = ComputerBuilder
                .start()
                .setCpu("i7")
                .setRam("8g")
                .setStorage("256g ssd")
                .build();
        System.out.println(computer.toString());
    }

}

실행결과

i7,8g,256g ssd

인자가 많은 객체를 생성할 때 해당 빌더 패턴을 사용하자.

 

참고: https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

반응형

'Java > Java' 카테고리의 다른 글

[Design Pattern] Bridge Pattern  (0) 2019.12.12
[Design Pattern] Abstract Factory Pattern  (0) 2019.12.10
[Design Pattern] Prototype Pattern  (0) 2019.12.08
[Design Pattern] Singleton Pattern  (0) 2019.12.07
[Design Pattern] Factory Method Pattern  (0) 2019.12.07
Comments