ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java 언어로 배우는 디자인 패턴 입문]Ch07. Builder
    Development/[디자인패턴] 2019. 6. 26. 18:27
    반응형
    SMALL

    Builder

    복잡한 인스턴스 조립하기

     

    복잡한 객체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공할 수 있도록 합니다.

    빌더 패턴은 객체 생성과 객체를 표현하는 방법을 분리하는 패턴입니다.

     

    책의 예제보다 아래 예제가 더 이해하기 좋아서, 아래 것으로 대체합니다.

    (출처 :https://jdm.kr/blog/217)

     

    /**
     * 제약사항 : 이 객체는 한번 생성되면 읽기(Read)만 가능해야 합니다.
     */
    public class PersonInfo {
        private String name;
        private Integer age;
        private String favoriteColor;
        private String favoriteAnimal;
        private Integer favoriteNumber;
    
        public PersonInfo(String name, Integer age, String favoriteColor, String favoriteAnimal, Integer favoriteNumber){
            this.name = name;
            this.age = age;
            this.favoriteColor = favoriteColor;
            this.favoriteAnimal = favoriteAnimal;
            this.favoriteNumber = favoriteNumber;
        }
    
        public String getName() {
            return name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public String getFavoriteColor() {
            return favoriteColor;
        }
    
        public String getFavoriteAnimal() {
            return favoriteAnimal;
        }
    
        public Integer getFavoriteNumber() {
            return favoriteNumber;
        }
    
        public String getPersonInfo(){
            String personInfo = String.format("name:%s, age:%d, favoriteColor:%s, favoriteAnimal:%s, favoriteNumber:%d"
                    , name, age, favoriteColor, favoriteAnimal, favoriteNumber);
            return personInfo;
        }
    }

    위의 클래스를 생성하려면, 생성자에 name, age, favoriteColor, favoriteAnimal 등의 정보를 다 넣어야 합니다.

    모르는 것은 default 값을 따로 넣어주어야 합니다. 그렇지 않으면 객체를 생성하지 못합니다.

    빌더 패턴은 생성과 표현을 분리합니다.

     

    public class PersonInfoBuilder {
        private String name;
        private Integer age;
        private String favoriteColor;
        private String favoriteAnimal;
        private Integer favoriteNumber;
    
        public PersonInfoBuilder setName(String name) {
            this.name = name;
            return this;
        }
    
        public PersonInfoBuilder setAge(Integer age) {
            this.age = age;
            return this;
        }
    
        public PersonInfoBuilder setFavoriteColor(String favoriteColor) {
            this.favoriteColor = favoriteColor;
            return this;
        }
    
        public PersonInfoBuilder setFavoriteAnimal(String favoriteAnimal) {
            this.favoriteAnimal = favoriteAnimal;
            return this;
        }
    
        public PersonInfoBuilder setFavoriteNumber(Integer favoriteNumber) {
            this.favoriteNumber = favoriteNumber;
            return this;
        }
    
        public PersonInfo build(){
            PersonInfo personInfo = new PersonInfo(name, age, favoriteColor, favoriteAnimal, favoriteNumber);
            return personInfo;
        }
    }

    위와 같이 빌더 패턴을 적용하면, 아래와 같이 사용할 수 있습니다.

    public class BuilderPattern {
        public static void main(String[] args) {
            // 빌더 객체를 하나 만듭니다.
            PersonInfoBuilder personInfoBuilder = new PersonInfoBuilder();
            // 빌더 객체에 원하는 데이터를 입력합니다. 순서는 상관 없습니다.
            PersonInfo result = personInfoBuilder
                    .setName("MISTAKE")
                    .setAge(20)
                    .setFavoriteAnimal("cat")
                    .setFavoriteColor("black")
                    .setName("JDM") // 다시 같은 메소드를 호출한다면 나중에 호출한 값이 들어갑니다.
                    .setFavoriteNumber(7)
                    // 마지막에 .build() 메소드를 호출해서 최종적인 결과물을 만들어 반환합니다.
                    .build();
            // print is "name:JDM, age:20, favoriteColor:black, favoriteAnimal:cat, favoriteNumber:7"
            System.out.println(result.getPersonInfo());
        }
    }

    setFavoriteColor()를 호출하지 않으며, 만들어진 객체는 그 값이 빈 string만 있습니다. 기존 클래스에서는 생성자에서 favoriteColor값을 넣어줘야만 생성이 가능했습니다.

     

    안드로이드 개발자라면 아래 코드가 많이 익숙할 텐데요.

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("AlertDialog Title");
            builder.setMessage("AlertDialog Content");
            builder.setPositiveButton("예",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(getApplicationContext(),"예를 선택했습니다.",Toast.LENGTH_LONG).show();
                        }
                    });
            builder.setNegativeButton("아니오",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(getApplicationContext(),"아니오를 선택했습니다.",Toast.LENGTH_LONG).show();
                        }
                    });
            builder.show();

    빌더 패턴입니다.

    alertdialog에 title이 없는 경우도 있는데, 이 경우 setTitle을 호출하지 않으면 됩니다.

    버튼도 마찬가지고요. 메시지도 없는 다이얼로그를 생성하는 건 그냥 Builder에서 create만 하면 될 겁니다.

    표현은 각각의 메서드를 사용하면 됩니다.

     

    실제 AlertDialog의 구현은 아래 url에서 확인해 보실 수 있습니다.

    https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/AlertDialog.java

    반응형
    LIST

    댓글

Designed by Tistory.