Android 디자인 모델 의 Builder 모델 이 실제 프로젝트 에서 의 활용
Builder 모델 은 디자인 모델 이다. Android 소스 코드 에서 AlertDialog 는 Build 디자인 모델 을 사용 하 는 것 이다. 이런 모델 의 주요 특징 은 체인 식 이 고 사용자 의 호출 을 편리 하 게 하 는 것 이다. 사용 자 는 내부 에서 어떻게 실현 하 는 지 에 관심 을 가지 지 않 아 도 편리 하 게 호출 할 수 있다.
왜 써 요?
먼저 정 의 를 알 아 보 자.
건설 자 모드 (Builder Pattern): 복잡 한 대상 의 구축 을 표시 와 분리 시 켜 같은 구축 과정 에서 서로 다른 표 시 를 만 들 수 있 습 니 다.건설 자 모드 는 대상 생 성 모드 입 니 다.
사용 필드:
UML 도해:
건축 자 모델 구조 도 에는 다음 과 같은 몇 가지 역할 이 포함 되 어 있다.
● Builder (추상 적 인 작성 자): 제품 대상 의 각 위 젯 을 만 들 기 위해 추상 적 인 인 터 페 이 스 를 지정 합 니 다. 이 인터페이스 에서 일반적으로 두 가지 방법 을 설명 합 니 다. 하 나 는 buildPartX () 입 니 다. 복잡 한 대상 의 각 위 젯 을 만 드 는 데 사 용 됩 니 다.다른 방법 은 getResult () 입 니 다. 복잡 한 대상 을 되 돌려 주 는 데 사 용 됩 니 다.Builder 는 추상 적 인 클래스 일 수도 있 고 인터페이스 일 수도 있다.
● ConcreteBuilder (구체 적 인 건설 자): Builder 인 터 페 이 스 를 실현 하고 각 부품 의 구체 적 인 구조 와 조립 방법 을 실현 하 며 만 든 복잡 한 대상 을 정의 하고 명 확 히 하 며 만 든 복잡 한 제품 대상 을 되 돌려 주 는 방법 도 제공 할 수 있다.
● Product (제품 역할): 구 축 된 복잡 한 대상 으로 여러 개의 구성 부품 을 포함 하고 구체 적 인 건설 자가 이 제품 을 만 드 는 내부 표시 와 조립 과정 을 정의 합 니 다.
● Director (지휘자): 지휘 자 는 감독 류 라 고도 부 르 는데 복잡 한 대상 의 건설 순 서 를 배정 하고 지휘자 와 추상 적 인 건축 자 간 에 관련 관계 가 있 으 며 construct () 건설 방법 에서 건축 자 대상 의 부품 구조 와 조립 방법 을 호출 하여 복잡 한 대상 의 건설 을 완성 할 수 있다.클 라 이언 트 는 일반적으로 지휘자 와 상호작용 을 하고 클 라 이언 트 에서 구체 적 인 건축 자의 유형 을 확정 하 며 구체 적 인 건축 자 대상 (파일 설정 과 반사 체 제 를 통 해) 을 예화 한 다음 에 지휘자 류 의 구조 함수 나 Setter 방법 으로 이 대상 을 지휘자 류 에 전송 할 수 있다.
Builder 모드 의 장단 점
장점:
변종 빌 더 모델 은 현실 안 드 로 이 드 개발 에 자주 사용 된다.현실 개발 에 서 는 디 렉 터 역할 이 자주 생략 된다.그리고 하나의 Builder 를 직접 사용 하여 대상 의 조립 을 한다. 이 Builder 는 보통 체인 호출 이다. 그의 관건 은 모든 setter 방법 이 자신 에 게 돌아 가 는 것 이다. 즉,
return this.다음 호출:new TestBuilder().setA("A").setB("B").create()
  좋 은 점:
대상 생 성 과정 에서 도 입 된 여러 개의 과부하 구조 함수, 선택 가능 한 매개 변수 와 setter 의 과도 한 사용 으로 불필요 한 복잡성 을 줄 이 는 데 목적 이 있다.
인 스 턴 스 를 활용 하면 맨 아래 참고 자료 3 에서 User 대상 속성 에 관 한 예 를 볼 수 있 습 니 다. 여 기 는 군말 이 아 닙 니 다.
다시 한 번 예 를 들다.
면접 을 본 학생 들 은
String 과 StringBuffer 의 차이 점 을 물 을 수 있 습 니 다. 여기 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
            )
        }
    }
         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. 변종 빌 더 모드: 우아 한 대상 구축 방식
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.