Builder 모드 와 체인 호출

6881 단어
저작권 성명: 본 고 는 작가 의 오리지널 이 므 로 전재 할 때 출처 를 밝 혀 주 십시오.
머리말
모두 가 알다 시 피 Builder 모델 은 안 드 로 이 드 에서 광범 위 하 게 응용 되 고 매우 중요 한 디자인 모델 이다.그러나 실제 개발 과정 에서 저 는 체인 호출 도 Builder 모델 이 완성 한 기능 을 실현 할 수 있 을 것 같 습 니 다. 그러면 왜 체인 호출 을 간단하게 사용 하지 않 습 니까?
가능 한 한 빨리 본론 에 들 어가 기 위해 개념 과 관련 된 소 개 는 본문의 마지막 부분 에 있다.
AlertDialog
AlertDialog 는 Android 소스 코드 에서 Builder 모델 을 사용 하 는 대표 적 인 사례 로 본 고 는 AlertDialog 에 착안 하여 분석 하고 자 한다.
AlertDialog 의 일반적인 사용 은 다음 과 같다.
AlertDialog alertDialog = new AlertDialog.Builder(this)
    .setTitle(title)
    .setMessage(msg)
    .setCancelable(false)
    .setPositiveButton(btn,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            }).show();

분명히 표준 체인 호출 입 니 다. 그러면 문제 가 생 겼 습 니 다. Builder 를 없 애고 new 대상 으로 직접 실현 할 수 있 습 니까?다음 코드 와 유사 합 니 다.
AlertDialog alertDialog = new AlertDialog(this)
    .setTitle(title)
    .setMessage(msg)
    .setCancelable(false)
    .setPositiveButton(btn,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            }).show();

아래 의 분석 을 계속 보 세 요.
AlertDialog 소스 코드
일단 쇼 방법 을 볼 게 요.
/**
 * Creates an {@link AlertDialog} with the arguments supplied to this
 * builder and immediately displays the dialog.
 * 

* Calling this method is functionally identical to: *


 *     AlertDialog dialog = builder.create();
 *     dialog.show();
 * 
*/
public AlertDialog show() {
final AlertDialog dialog = create();
dialog.show();
return dialog;
}
AlertDialog 대상 은 create () 방법 으로 생 성 된 것 으로 보인다.create () 방법 을 살 펴 보 겠 습 니 다.
/**
 * Creates an {@link AlertDialog} with the arguments supplied to this
 * builder.
 * 

* Calling this method does not display the dialog. If no additional * processing is needed, {@link #show()} may be called instead to both * create and display the dialog. */ public AlertDialog create() { // Context has already been wrapped with the appropriate theme. final AlertDialog dialog = new AlertDialog(P.mContext, 0, false); P.apply(dialog.mAlert); dialog.setCancelable(P.mCancelable); if (P.mCancelable) { dialog.setCanceledOnTouchOutside(true); } dialog.setOnCancelListener(P.mOnCancelListener); dialog.setOnDismissListener(P.mOnDismissListener); if (P.mOnKeyListener != null) { dialog.setOnKeyListener(P.mOnKeyListener); } return dialog; }


이 를 통 해 알 수 있 듯 이 AlertDialog 를 구축 할 때 create () 방법 에서 기본 값 설정, 감청 설정 등 대량의 작업 을 했다.create () 방법 은 AlertDialog 대상 의 산출 결 과 를 제어 하고 있다.
show () 와 create () 는 모두 AlertDialog. Builder 류 의 방법 으로 소스 코드 는 다음 과 같 습 니 다.
public static class Builder {
    //      ,     set  
    private final AlertController.AlertParams P;

    public Builder(Context context) {
        this(context, resolveDialogTheme(context, 0));
    }

    public Builder(Context context, int themeResId) {
        P = new AlertController.AlertParams(new ContextThemeWrapper(
                context, resolveDialogTheme(context, themeResId)));
    }

    public Context getContext() {
        return P.mContext;
    }

    public Builder setTitle(@StringRes int titleId) {
        P.mTitle = P.mContext.getText(titleId);
        return this;
    }

    public Builder setTitle(CharSequence title) {
        P.mTitle = title;
        return this;
    }

    public AlertDialog create() {
        // Context has already been wrapped with the appropriate theme.
        final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
        P.apply(dialog.mAlert);
        dialog.setCancelable(P.mCancelable);
        if (P.mCancelable) {
            dialog.setCanceledOnTouchOutside(true);
        }
        dialog.setOnCancelListener(P.mOnCancelListener);
        dialog.setOnDismissListener(P.mOnDismissListener);
        if (P.mOnKeyListener != null) {
            dialog.setOnKeyListener(P.mOnKeyListener);
        }
        return dialog;
    }

    public AlertDialog show() {
        final AlertDialog dialog = create();
        dialog.show();
        return dialog;
    }
}

create () 방법의 필요 성
위의 분석 을 통 해 알 수 있 듯 이 핵심 방법 은 create () 방법 이다. 그러면 우 리 는 create () 방법 중의 실행 코드 를 모두 show () 방법 에 넣 어 실현 할 수 있 을 까?또는 create () 방법 을 보류 하지만 Builder 류 를 제거 하고 create () 와 show () 를 AlertDialog 류 로 옮 겨 실행 할 까요?
결론 이 정 해 졌 는 지 아 닌 지.
어떤 의미 에서 빌 더 를 없 애 더 라 도 이동 방법 은 실 행 될 수 있다.그러나 이 는 AlertDialog, 심지어 Builder 모델 자체 의 사상 과 배치 된다.
추상 적 으로 보면 create () 는 '생산 제조' 절차 와 같 고 show () 는 '사용 체험' 절차 와 같다. 이들 은 상대 적 으로 독립 된 방법 이다. 업무 논리 가 매우 복잡 할 때 '생산' 과 '사용' 을 분리 하면 특히 중요 하 다. 코드 의 가 독성 도 증가 하고 코드 의 확장 성도 증가 했다.
더 중요 한 것 은 Builder. create () 자체 가 대상 구축 에 대한 '제약' 으로 제품 의 세부 사항 을 외부 에 노출 하지 않 고 사용 자 는 필요 에 따라 구축 할 수 있 으 며 사용자 도 '제약' 자 체 를 수정 하여 대상 의 구축 결 과 를 통제 할 수 있다.
실제 와 결합 하 다
Builder 모드 가 이렇게 좋 은 점 이 많 고 확장 성 이 증가 하 는 등 을 읽 어 본 친구 들 은 이런 제안 이 들 어 있다 는 것 을 알 수 있 습 니 다.
세 개 이상 의 구조 적 매개 변수 가 필요 할 때 Builder 를 사용 하여 이 대상 을 구성 합 니 다.좀 수 다스 러 울 수도 있 는데 이렇게 신축성 과 가 독성 이 좋아요.
그렇다면 Builder 모드 를 우선 사용 하여 대상 의 구축 을 완성 하 는 것 이 아 닐 까?결론 도 부정 적 이다.
디자인 모델 의 사용 은 반드시 실제 장면 과 결합 해 야 한다. 그렇지 않 으 면 과도 한 디자인 이다.
필드 를 사용 하여 다음 조건 을 만족 시 킬 때 Builder 모드 를 사용 할 수 있 습 니 다.
  • 같은 방법 으로 서로 다른 집행 순서 로 서로 다른 사건 결과 가 발생 한다.또는 방법의 호출 순서 가 다 르 면 서로 다른 역할 을 할 수 있다
  • 여러 부품 이나 부품 을 같은 대상 에 조립 할 수 있 으 나 발생 하 는 운행 결 과 는 다르다
  • .
  • 대상 이 매우 복잡 한 대상 을 초기 화 해 야 합 니 다. 이 대상 은 매개 변수 가 많 고 기본 값
  • 이 있 습 니 다.

  • 한 마디 로 하면 실제 장면 이 특히 복잡 할 때 Builder 모델 은 당신 의 정확 한 선택 중 하나 입 니 다.
    그 밖 에 체인 호출 (또는 일반적인 대상 구조) 을 간단하게 실현 하 는 것 이 가장 좋 은 방안 이다.
    관련 개념 소개
    빌 더 모드
    복잡 한 대상 의 구축 과 그 표 시 를 분리 시 켜 같은 구축 과정 에서 서로 다른 표 시 를 만 들 수 있 습 니 다.
    체인 호출
    public class MsgInfo {
    
        private long msgId;
        private String type;
    
        pulic MsgInfo() {
            
        }
        
        public MsgInfo setMsgId(long msgId) {
            this.msgId = msgId;
            return this;
        }
        
        public MsgInfo setType(String type) {
            this.type = type;
            return this;
        }
        
        public void show() {
            // do something
        }
    
    }
    
    MsgInfo msgInfo = new MsgInfo().setMsgId(99).setType("A").show();
    

    참고 자료
  • https://juejin.im/post/58f630a544d904006c0eedc9
  • http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0527/1299.html
  • http://www.jianshu.com/p/cb9cd6a8dd51
  • 《Effective Java》
  • 좋은 웹페이지 즐겨찾기