Android 디자인 모델 의 Builder 모델 이 실제 프로젝트 에서 의 활용

글 목록
  • 배경
  • 왜 써 요?
  • 사용 장면:
  • UML 도해:
  • Builder 모델 의 장단 점
  • 변종 빌 더 모드
  • 실제 프로젝트 의 사례:
  • 네트워크 요청 시 유 니 버 설 매개 변수 설정
  • MaterialDialog 대화 상자
  • 소결
  • 배경
    Builder 모델 은 디자인 모델 이다. Android 소스 코드 에서 AlertDialog 는 Build 디자인 모델 을 사용 하 는 것 이다. 이런 모델 의 주요 특징 은 체인 식 이 고 사용자 의 호출 을 편리 하 게 하 는 것 이다. 사용 자 는 내부 에서 어떻게 실현 하 는 지 에 관심 을 가지 지 않 아 도 편리 하 게 호출 할 수 있다.
    왜 써 요?
    먼저 정 의 를 알 아 보 자.
    건설 자 모드 (Builder Pattern): 복잡 한 대상 의 구축 을 표시 와 분리 시 켜 같은 구축 과정 에서 서로 다른 표 시 를 만 들 수 있 습 니 다.건설 자 모드 는 대상 생 성 모드 입 니 다.
    사용 필드:
  • 같은 방법, 서로 다른 집행 순서, 서로 다른 사건 결과 가 발생 할 때;
  • 여러 부품 이나 부품 을 한 대상 에 조립 할 수 있 으 나 발생 하 는 운행 결 과 는 같 지 않다.
  • 제품 류 가 매우 복잡 하거나 제품 류 중의 호출 순서 가 다 르 기 때문에 서로 다른 효능 이 생 겼 다. 이때 건축 자 모델 을 사용 하 는 것 이 매우 적합 하 다.
  • 대상 을 초기 화 하 는 것 은 매우 복잡 하 다. 예 를 들 어 매개 변수 가 많 고 많은 매개 변수 가 기본 값 을 가지 고 있 을 때.

  • UML 도해:
    건축 자 모델 구조 도 에는 다음 과 같은 몇 가지 역할 이 포함 되 어 있다.
    ● Builder (추상 적 인 작성 자): 제품 대상 의 각 위 젯 을 만 들 기 위해 추상 적 인 인 터 페 이 스 를 지정 합 니 다. 이 인터페이스 에서 일반적으로 두 가지 방법 을 설명 합 니 다. 하 나 는 buildPartX () 입 니 다. 복잡 한 대상 의 각 위 젯 을 만 드 는 데 사 용 됩 니 다.다른 방법 은 getResult () 입 니 다. 복잡 한 대상 을 되 돌려 주 는 데 사 용 됩 니 다.Builder 는 추상 적 인 클래스 일 수도 있 고 인터페이스 일 수도 있다.
    ● ConcreteBuilder (구체 적 인 건설 자): Builder 인 터 페 이 스 를 실현 하고 각 부품 의 구체 적 인 구조 와 조립 방법 을 실현 하 며 만 든 복잡 한 대상 을 정의 하고 명 확 히 하 며 만 든 복잡 한 제품 대상 을 되 돌려 주 는 방법 도 제공 할 수 있다.
    ● Product (제품 역할): 구 축 된 복잡 한 대상 으로 여러 개의 구성 부품 을 포함 하고 구체 적 인 건설 자가 이 제품 을 만 드 는 내부 표시 와 조립 과정 을 정의 합 니 다.
    ● Director (지휘자): 지휘 자 는 감독 류 라 고도 부 르 는데 복잡 한 대상 의 건설 순 서 를 배정 하고 지휘자 와 추상 적 인 건축 자 간 에 관련 관계 가 있 으 며 construct () 건설 방법 에서 건축 자 대상 의 부품 구조 와 조립 방법 을 호출 하여 복잡 한 대상 의 건설 을 완성 할 수 있다.클 라 이언 트 는 일반적으로 지휘자 와 상호작용 을 하고 클 라 이언 트 에서 구체 적 인 건축 자의 유형 을 확정 하 며 구체 적 인 건축 자 대상 (파일 설정 과 반사 체 제 를 통 해) 을 예화 한 다음 에 지휘자 류 의 구조 함수 나 Setter 방법 으로 이 대상 을 지휘자 류 에 전송 할 수 있다.
    Builder 모드 의 장단 점
    장점:
  • 좋 은 포장 성 을 가지 고 건축 자 모델 을 사용 하면 클 라 이언 트 가 제품 내부 로 구 성 된 디 테 일 을 알 필요 가 없다
  • .
  • 건설 자 는 독립 적 이 고 확장 하기 쉽다
  • 단점:
  • 여분의 Builder 대상 과 Director 대상 이 발생 하여 메모리 소모
  • 변종 빌 더 모드
    변종 빌 더 모델 은 현실 안 드 로 이 드 개발 에 자주 사용 된다.현실 개발 에 서 는 디 렉 터 역할 이 자주 생략 된다.그리고 하나의 Builder 를 직접 사용 하여 대상 의 조립 을 한다. 이 Builder 는 보통 체인 호출 이다. 그의 관건 은 모든 setter 방법 이 자신 에 게 돌아 가 는 것 이다. 즉, return this.다음 호출:
    new TestBuilder().setA("A").setB("B").create()
    

    좋 은 점:
    대상 생 성 과정 에서 도 입 된 여러 개의 과부하 구조 함수, 선택 가능 한 매개 변수 와 setter 의 과도 한 사용 으로 불필요 한 복잡성 을 줄 이 는 데 목적 이 있다.
    인 스 턴 스 를 활용 하면 맨 아래 참고 자료 3 에서 User 대상 속성 에 관 한 예 를 볼 수 있 습 니 다. 여 기 는 군말 이 아 닙 니 다.
    다시 한 번 예 를 들다.
    면접 을 본 학생 들 은 StringStringBuffer 의 차이 점 을 물 을 수 있 습 니 다. 여기 StringBuilder 라 는 문자열 구축 기 가 있 습 니 다. 이 구축 기의 용법 을 간단히 살 펴 보 겠 습 니 다!
      String sb = new StringBuilder().append("I ")
                    .append("am ")
                    .append("student.").toString();
    
    	//         append()     
    	@Override
        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }
    

    StringBuilder 는 들 어 오 는 append() 부모 클래스 를 호출 하 는 방법 으로 대상 문자열 뒤에 추가 하고 이 대상 을 되 돌려 줍 니 다. 그러면 연속 적 으로 호출 str 방법 을 사용 할 수 있 고 대상 의 유일 성 append() 을 유지 할 수 있 습 니 다.
    실제 프로젝트 의 사례:
  • 네트워크 요청 시 유 니 버 설 매개 변수 설정
  •  	private const val DEFAULT_CONNECT_TIMEOUT = 5_000L
        private const val OTHER_TIME_OUT = 5_000L    
    
    	/**
         *           
         */
        fun testConfig() {
            val httpConfig = HttpConfig.Builder().baseUrl(CommonApi.apiBaseUrl)
                //     http    
                .setLogLevel(HttpLoggingInterceptor.Level.BODY)
                //         
                .connectTimeoutMillis(DEFAULT_CONNECT_TIMEOUT)
                .readTimeoutMillis(OTHER_TIME_OUT)
                .writeTimeoutMillis(OTHER_TIME_OUT).build()
            HttpUtil.initHttpConfig(httpConfig)
        }
    
    	/**
         *          
         */
        class Builder {
            private var baseUrl = ""
            private var interceptors: ArrayList = ArrayList()
            private var networkInterceptors: ArrayList = ArrayList()
            private var defaultConnectTimeout = 10_000L
            private var defaultReadTimeout = 10_000L
            private var defaultWriteTimeout = 10_000L
            private var retryOnConnectionFailure = false
            private var isUseCookie = false
            private var isUseCache = false
            private var logLevel = HttpLoggingInterceptor.Level.NONE
            private val commonHeaders = ArrayMap()
            private val commonParams = ArrayMap()
            private var sslParam: SSLParam = HttpsUtil.getSslSocketFactory()
            private var hostnameVerifier: HostnameVerifier = HttpsUtil.UnSafeHostnameVerifier
    
            fun baseUrl(url: String): HttpConfig.Builder {
                baseUrl = url
                return this
            }
    
            fun addInterceptor(interceptor: Interceptor): HttpConfig.Builder {
                interceptors.add(interceptor)
                return this
            }
    
            fun addNetworkInterceptor(interceptor: Interceptor): HttpConfig.Builder {
                networkInterceptors.add(interceptor)
                return this
            }
    
            /**
             *       
             * @param millis      (  10 )
             */
            fun connectTimeoutMillis(millis: Long): HttpConfig.Builder {
                if (millis <= 0) {
                    throw IllegalArgumentException("connect timeout must Greater than 0")
                }
                defaultConnectTimeout = millis
                return this
            }
    
            /**
             *       
             * @param millis      (  10 )
             */
            fun readTimeoutMillis(millis: Long): HttpConfig.Builder {
                if (millis <= 0) {
                    throw IllegalArgumentException("read timeout must Greater than 0")
                }
                defaultReadTimeout = millis
                return this
            }
    
            /**
             *       
             * @param millis      (  10 )
             */
            fun writeTimeoutMillis(millis: Long): HttpConfig.Builder {
                if (millis <= 0) {
                    throw IllegalArgumentException("write timeout must Greater than 0")
                }
                defaultWriteTimeout = millis
                return this
            }
    
            /**
             *                
             * @param retryOnConnectionFailure    false
             */
            fun retryOnConnectionFailure(retryOnConnectionFailure: Boolean): HttpConfig.Builder {
                this.retryOnConnectionFailure = retryOnConnectionFailure
                return this
            }
    
            /**
             *     cookie
             * @param isUseCookie    false
             */
            fun useCookie(isUseCookie: Boolean): HttpConfig.Builder {
                this.isUseCookie = isUseCookie
                return this
            }
    
            /**
             *       
             * @param isUseCache    false
             */
            fun useCache(isUseCache: Boolean): HttpConfig.Builder {
                this.isUseCache = isUseCache
                return this
            }
    
            /**
             *       ,  [HttpLoggingInterceptor.Level]
             * @param level    [HttpLoggingInterceptor.Level.NONE]
             */
            fun setLogLevel(level: HttpLoggingInterceptor.Level): HttpConfig.Builder {
                logLevel = level
                return this
            }
    
            /**
             *       header
             * @param key header 
             * @param value header 
             */
            fun commonHeader(key: String, value: String): HttpConfig.Builder {
                commonHeaders[key] = value
                return this
            }
    
            /**
             *         
             * @param key    
             * @param value    
             */
            fun commonParam(key: String, value: String): HttpConfig.Builder {
                commonParams[key] = value
                return this
            }
    
            /**
             *   ssl
             * @param param ssl  ,           
             */
            fun sslSocketFactory(param: SSLParam): HttpConfig.Builder {
                sslParam = param
                return this
            }
    
            /**
             *      
             * @param verifier          
             */
            fun hostnameVerifier(verifier: HostnameVerifier): HttpConfig.Builder {
                hostnameVerifier = verifier
                return this
            }
    
            fun build(): HttpConfig {
                return HttpConfig(
                    baseUrl, interceptors, networkInterceptors, defaultConnectTimeout
                    , defaultReadTimeout, defaultWriteTimeout, retryOnConnectionFailure, isUseCookie
                    , isUseCache, logLevel, commonHeaders, commonParams, sslParam, hostnameVerifier
                )
            }
        }
    
  • MaterialDialog 대화 상자
  •    private fun showSavePromptDialog() {
            MaterialDialog(this)
                .message(text ="      ")
                .positiveButton("  ") {
                   // do something
                }
                .negativeButton(“  ”) {
                   // do something
                }
                .showByCZConfig()
        }
    
    /**
    *MaterialDialog  
    */
    fun MaterialDialog.showByCZConfig(): MaterialDialog {
        show()
        doAsync {
            SystemClock.sleep(50L)
            uiThread {
             val positiveButton = findViewById(R.id.md_button_positive)
             val negativeButton = findViewById(R.id.md_button_negative)
             val neutralButton = findViewById(R.id.md_button_neutral)
    
             positiveButton.setTextColor(ResourcesUtil.getColor(R.color.common_font_red))
             negativeButton.setTextColor(ResourcesUtil.getColor(R.color.common_font_black))
             neutralButton.setTextColor(ResourcesUtil.getColor(R.color.common_font_black))
            }
        }
        return this
    }
    

    기타: 예 를 들 어 개 원 된 이미지 프레임 워 크 ImageLoader 는 ImageLoader Config 를 통 해 설정 하 는 등 입 니 다.
    작은 매듭
    개발 과정 에서 하나의 구조 기 나 정적 공장 에 여러 개의 매개 변 수 를 가지 고 있 습 니 다. 특히 대부분의 매개 변 수 는 선택 할 수 있 을 때 Builder 모델 을 사용 하여 너무 많은 setter 방법 을 피 할 수 있 습 니 다.Builder 모델 에서 흔히 볼 수 있 는 실현 형식 은 호출 체인 을 통 해 이 루어 져 코드 를 더욱 간결 하고 이해 하기 쉽다.
    참고 자료:
    1. 디자인 모델 시리즈 - 건축 자 모델 - Builder Pattern
    2. 생 성 형 디자인 모드 의 Builder 모드
    3. Android: Builder 모드 상세 설명 및 학습 사용
    4. 변종 빌 더 모드: 우아 한 대상 구축 방식

    좋은 웹페이지 즐겨찾기