본문 바로가기

카테고리 없음

디자인 패턴 - 생성패턴 -Builder

디자인 패턴 종류

 

-Factory Method

-Abstaract Factory

-Builder

-Singleton

-ProtoType

 

 

-Builder 패턴 프로그래밍 중에 자주 사용되는 패턴이다 대부분 class 설계시에는 인수들이 적을 경우에는 생성자로 객체를 생성시에는 생성자를 1~5개 정도로 적게 만들 경우에는 프로그래밍중에 별 상관이 없다고 느껴진다 하지만,

인수들이 많아지고 필수로 받아야 하는 인자와 필수가 아닌 선택적인  인자들을 받아야 하는 경우와 생성자의 경우의 수가 많아질 경우에는 가독성이 떨어지고, 인수가 많아지는 경우에는 생성자를 만 들 경 우에 인수의 타입이 같을 경우에는 어떤 부분에 인수를 받아야 했는지 헷갈리는 경우가 많아진다.

 

이럴 경우에는 빌더 패턴을 이용하자.

 

user.java

public class User {

    private String userName;//필수
    private String phoneNumber;//필수
    private int age;//선택
    private String gender; //선택

    //빌더패턴을 사용하지않을 경우에는 점층적 생성자패턴을 자주 이용함.
    //하지만 이럴경우에는 간단하지만 인자들이 많아지면? 관리하기가 힘들어짐.
    public User(String userName, String phoneNumber) {
        this.userName = userName;
        this.phoneNumber = phoneNumber;
    }
    //선택생성자
    public User(int age, String gender) {
        this.age = age;
        this.gender = gender;
    }
}

위에 말했다시피 빌더 패턴을 사용하지 않을 경우에는 점층적 패턴으로 계속 사용하기 때문에 코드가 지저분해지면서 알아보기가 힘들어짐.

 

 

main.java

  public static void main(String args[]){
        User user = new User("괴발자","010-1111-1111");
    }

main.java에서는 간단한 경우지만 생성자 생성 시 받는 인자 값이 많아지고 타입이 같은 경우에는 순서를 잘못 대입하거나 그런 경우에는 계속해서 user.java에서 계속 확인을 하며, 프로그래밍을 해야 하는 경우가 있다.

(제일 불편하다 헷갈리고)

 

 

또 다른 경우에는 setter로 값을 넣어주는 것이다.

User users = new User();
users.setPhoneNumber("010-1111-1111");
user.setUserName("괴발자");

 

확실히 점층적 패턴으로 생성자를 만드는 것보다는 한눈에 어떤 값을 넣었는지 알아볼 수가 있어서 좋아 보인다. 하지만

단점으로는 한 번의 호출로 생성자가 만들어지지 않으며, 객체를 생성 후에 setter를 할 수 있기 때문에 객체의 내용이 변경될 가능성이 높으므로 위험하다. 일관성, 변경 불가능 원칙에 어긋난다..

 

이러한 이유 때문에 사용되는 빌더 패턴이다.

 

빌더 패턴 적용된

public class User {

    private String userName;//필수
    private String phoneNumber;//필수
    private int age;//선택
    private String gender; //선택

    //빈 생성자
    public User() {
    }

    //빌더패턴을 사용하지않을 경우에는 점층적 생성자패턴을 이용해야함.
    //하지만 이럴경우에는 간단하지만 인자들이 많아지면? 관리하기가 힘들어짐.
    public User(String userName, String phoneNumber) {
        this.userName = userName;
        this.phoneNumber = phoneNumber;
    }
    //선택생성자
    public User(int age, String gender) {
        this.age = age;
        this.gender = gender;
    }


    //빌더 생성자
    public User(UserBuilder userBuilder) {
        this.userName = userBuilder.userName;
        this.phoneNumber = userBuilder.phoneNumber;
        this.age = userBuilder.age;
        this.gender = userBuilder.gender;
    }


    //userBuilder
    public static class UserBuilder{
        private String userName;//필수
        private String phoneNumber;//필수
        private int age;//선택
        private String gender; //선택

    public UserBuilder(String userName, String phoneNumber){
        this.userName=userName;
        this.phoneNumber=phoneNumber;
    }

    public UserBuilder age(int age){
        this.age=age;
        return this;
    }

    public UserBuilder gender(String gender){
            this.gender=gender;
            return this;
    }
    public User build(){
        return new User(this);
    }


    }


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }



    public static void main(String args[]){
        User user = new User("괴발자","010-7222-2323");

        User users = new User();
        users.setPhoneNumber("010-1111-1111");
        user.setUserName("괴발자");

        User userB = new UserBuilder("괴발자","010-1111-1111")
                .age(10)
                .gender("남성")
                .build();
        System.out.println(userB.getGender());
    }
}

 

 

        User userB = new UserBuilder("괴발자","010-1111-1111")
                .age(10)
                .gender("남성")
                .build();
        System.out.println(userB.getGender());//"남성"

static의 UserBuilder를 만들고 필수인자 값들을 넣어주고 선택인자값도 필요시에 넣어준다.

훨씬 더 가시적이며 생성자를 원하는 인자값들을 넣어서 만들 수 있게 되었다 하지만 빌더 패턴에도 단점이 존재한다 일단 기본적으로 해당 class 빌더를 만들어줘야 하기 때문에 코드가 다른 패턴들 보다 길어진다....