Android 와 결합 하여 Builder 모드
Builder 모드, 대상 생 성 형 디자인 모드.디자인 모델 에 대해 말하자면 약간 심오 하 다 고 느 낄 수 있 습 니 다. 사실은 그렇지 않 습 니 다. 우 리 는 매일 코드 를 쓰 는 것 이 얼마나 적은 지 다양한 디자인 모델 과 접촉 하고 있 습 니 다. 다만 눈치 채 지 못 했 을 뿐 입 니 다.여기 서 Builder 모드 를 말씀 드 리 겠 습 니 다.
Android 의 Builder 모드
Android 개발 에 서 는 언제 Builder 모드 를 사용 합 니까?사실은 간단 하 다. 컨트롤 을 사용 하고 싶 을 때 나 대상 을 사용 하고 싶 을 때 그 를 직접 새로 만 들 수 없다 는 것 이다.그렇다면 이 컨트롤 (대상) 의 실현 은 대부분 Builder 모드 를 사용 한 것 이다.
AlertDialog.Builder
    private void InitView() {
        //      
        TextView mTextView = new TextView(this);
        Button mButton = new Button(this);
        //  Builder    Dialog
        AlertDialog.Builder builder=new 
                AlertDialog.Builder(this)
                .setTitle("My Dialog")
                .setMessage("This is Test Dialog")
                .setIcon(R.drawable.application_icon);
        AlertDialog dialog=builder.create();
    }  위의 코드 와 같이, 우 리 는 일반적인 방식 (new) 에 따라 TextView 대상 과 Button 대상 을 만 들 수 있 습 니 다. 그러나 AlertDialog 차례 가 되 었 을 때, 먼저 AlertDialog. Builder 대상 을 만 든 다음, 이 Builder 대상 을 통 해 AlertDialog 의 인 스 턴 스 를 만 들 수 있 습 니 다. 마찬가지 로 모두 Android 의 컨트롤 입 니 다. 차이 가 왜 이렇게 큽 니까? (Dialog 가 복잡 하기 때 문 입 니 다! o(╯□╰)o)。
다음은 AlertDialog 의 소스 코드 를 결합 하여 간단하게 분석 할 수 있다.
    protected AlertDialog(@NonNull Context context) {
        this(context, 0);
    }          public static class Builder {
        private final AlertController.AlertParams P;
        public Builder(@NonNull Context context) {
            this(context, resolveDialogTheme(context, 0));
        }
        public Builder(@NonNull Context context, @StyleRes int themeResId) {
            P = new AlertController.AlertParams(new ContextThemeWrapper(
                    context, resolveDialogTheme(context, themeResId)));
            mTheme = themeResId;
        }
        public Builder setTitle(@Nullable CharSequence title) {
            P.mTitle = title;
            return this;
        }
        public Builder setMessage(@Nullable CharSequence message) {
            P.mMessage = message;
            return this;
        }
        public Builder setIcon(@DrawableRes int iconId) {
            P.mIconId = iconId;
            return this;
        }
    .....
}          public AlertDialog create() {
            // We can't use Dialog's 3-arg constructor with the createThemeContextWrapper param,
            // so we always have to re-set the theme
            final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
            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;
        }  OKHttp 에 대해 서 는 모두 가 낯 설 지 않다 고 믿 습 니 다. Request 대상 을 구성 할 때 Request. Builder 를 사 용 했 습 니 다. 말 그대로 Builder 모드 도 사 용 했 습 니 다.
        findViewById(R.id.get).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.setText("");
                loading.setVisibility(View.VISIBLE);
                OkHttpClient client = new OkHttpClient();
                Request.Builder builder = new Request.Builder()
                        .url(BASE_URL)
                        .method("GET", null);
                Request request = builder.build();
                Call mCall = client.newCall(request);
                mCall.enqueue(new MyCallback());
            }
        });  이상 은 OKHttp 에 대한 전형 적 인 사용 방식 입 니 다. 여기 서 Request 대상 은 직접 만 드 는 것 이 아니 라 Request. Builder 대상 을 먼저 만 든 다음 그의 build 방법 으로 최종 request 대상 을 만 듭 니 다. Request 류 의 소스 코드 를 대충 볼 수 있 습 니 다.
public final class Request {
  private final HttpUrl url;
  private final String method;
  private final Headers headers;
  private final RequestBody body;
  private final Object tag;
  private Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tag = builder.tag != null ? builder.tag : this;
  }
    //     ....
  public static class Builder {
    private HttpUrl url;
    private String method;
    private Headers.Builder headers;
    private RequestBody body;
    private Object tag;
    public Builder() {
      this.method = "GET";
      this.headers = new Headers.Builder();
    }
    public Builder url(HttpUrl url) {
      if (url == null) throw new NullPointerException("url == null");
      this.url = url;
      return this;
    }
    /**
     * Sets the URL target of this request.
     *
     * @throws IllegalArgumentException if {@code url} is not a valid HTTP or HTTPS URL. Avoid this
     * exception by calling {@link HttpUrl#parse}; it returns null for invalid URLs.
     */
    public Builder url(String url) {
      if (url == null) throw new NullPointerException("url == null");
      // Silently replace websocket URLs with HTTP URLs.
      if (url.regionMatches(true, 0, "ws:", 0, 3)) {
        url = "http:" + url.substring(3);
      } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
        url = "https:" + url.substring(4);
      }
      HttpUrl parsed = HttpUrl.parse(url);
      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
      return url(parsed);
    }
    /**
     * Sets the URL target of this request.
     *
     * @throws IllegalArgumentException if the scheme of {@code url} is not {@code http} or {@code
     * https}.
     */
    public Builder url(URL url) {
      if (url == null) throw new NullPointerException("url == null");
      HttpUrl parsed = HttpUrl.get(url);
      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
      return url(parsed);
    }
    /**
     * Sets the header named {@code name} to {@code value}. If this request already has any headers
     * with that name, they are all replaced.
     */
    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }
    /** Removes all headers on this builder and adds {@code headers}. */
    public Builder headers(Headers headers) {
      this.headers = headers.newBuilder();
      return this;
    }
    public Builder method(String method, RequestBody body) {
      if (method == null) throw new NullPointerException("method == null");
      if (method.length() == 0) throw new IllegalArgumentException("method.length() == 0");
      if (body != null && !HttpMethod.permitsRequestBody(method)) {
        throw new IllegalArgumentException("method " + method + " must not have a request body.");
      }
      if (body == null && HttpMethod.requiresRequestBody(method)) {
        throw new IllegalArgumentException("method " + method + " must have a request body.");
      }
      this.method = method;
      this.body = body;
      return this;
    }
    public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }
  }
}  왜 Android 시스템 에서 AlertDialog 를 만 드 는 것 은 이렇게 복잡 합 니까? TextView 처럼 하나의 인 스 턴 스 를 직접 new 로 만 들 고 set 의 각종 속성 도 똑 같이 사용 할 수 있 지 않 습 니까? Request 대상 의 생 성 은 Builder 모드 를 사용 하지 않 아 도 됩 니까? 위의 여러 가지 이상 처리, 방법 집행 은 일반적인 방식 으로 도 가능 합 니 다. Builder 모드 의 가 치 는 어디 에 있 습 니까?
이런 의문 을 가지 고 Builder 모드 를 잘 이해 해 봅 시다.
빌 더 모드
정의.
복잡 한 대상 의 구축 과 그 표 시 를 분리 시 켜 같은 구축 과정 에서 서로 다른 표 시 를 만 들 수 있 습 니 다.
적용 필드
1. 같은 방법, 서로 다른 실행 순서, 서로 다른 사건 결과 발생 2. 여러 개의 부품 이나 부품 은 모두 같은 대상 에 조립 할 수 있 지만 발생 하 는 운행 결 과 는 다르다 3. 제품 류 가 매우 복잡 하거나 제품 의 호출 순서 가 다 르 면 서로 다른 역할 을 한다 4. 한 대상 이 매우 복잡 한 대상 을 초기 화해 야 한다. 이 대상 은 많은 매개 변수 가 있 고기본 값 이 있 음
이러한 개념 을 보면 추상 적일 수 있 습 니 다. 다음은 코드 를 통 해 보 겠 습 니 다. 이전 공장 방법 모델 에서 우 리 는 공장 방법 모델 로 Mobike 가 Ofo 대상 에서 생 성 된 예 를 들 었 습 니 다. 여 기 는 여전히 두 가 지 를 예 로 들 어 Builder 모델 로 어떻게 쓰 는 지 보 겠 습 니 다.
public final class Bicycle {
    public static final int SHARED = 1;
    public static final int PRIVATE = 0;
    @IntDef({SHARED, PRIVATE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface bicycleType {
    }
    protected String color;
    protected String name;
    protected double charge;
    protected int number;
    protected int type;
    protected Bicycle(BicycleBuilder builder) {
        this.color = builder.color;
        this.name = builder.name;
        this.charge = builder.chager;
        this.number = builder.number;
        this.type = builder.type;
    }
    public static class BicycleBuilder {
        private String color;
        private String name;
        private double chager;
        private int number;
        private int type;
        public BicycleBuilder() {
            this.color = "  ";
            this.name = "  ";
            this.chager = 0;
            this.number = 0;
            this.type = Bicycle.PRIVATE;
        }
        public BicycleBuilder setColor(String color) {
            this.color = color;
            return this;
        }
        public BicycleBuilder setName(String name) {
            this.name = name;
            return this;
        }
        public BicycleBuilder setCharge(double chager) {
            this.chager = chager;
            return this;
        }
        public BicycleBuilder setNumber(int number) {
            this.number = number;
            return this;
        }
        public BicycleBuilder setType(@bicycleType int type) {
            this.type = type;
            return this;
        }
        public Bicycle build(){
            return new Bicycle(this);
        }
    }
    @Override
    public String toString() {
        String typeStr= type == SHARED ? "    ": "    ";
        return "Bicycle{" +
                "color='" + color + '\'' +
                ", name='" + name + '\'' +
                ", charge=   " + charge +"/ "+
                ", number=" + number +
                ", type=" + typeStr +
                '}';
    }
}  여기 서 Bicycle 클래스 는 5 개의 고유 한 속성 을 포함 하고 있 으 며, 동시에 그 구조 방법 을 proctected 로 설정 합 니 다. Bicycle Builder 클래스 를 통 해 Bicycle 을 만 드 는 인 스 턴 스 를 실현 합 니 다. 여기 서 Bicycle Builder 의 기본 구조 방법 은 일반적인 검은색 영구 표 개인 자전 거 를 만 들 것 입 니 다. Bicycle Builder 가 제공 하 는 몇 가지 방법 을 통 해 우 리 는 서로 다른 Bicycle 인 스 턴 스 를 만 들 수 있 습 니 다.예 를 들 어 다음 과 같은 실현:
public class BuilderPatternActivity extends AppCompatActivity {
    private TextView bike_result;
    private Bicycle mBicycle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_builder_pattern);
        bike_result = V.f(this, R.id.bike_result);
    }
    /**
     *      
     * @param view
     */
    public void NormalBike(View view) {
        Bicycle.BicycleBuilder builder=new Bicycle.BicycleBuilder();
        mBicycle=builder.build();
        updateView(mBicycle);
    }
    /**
     *     
     * @param view
     */
    public void Mobike(View view) {
        Bicycle.BicycleBuilder builder=new Bicycle.BicycleBuilder()
                .setColor("  ")
                .setName("    ")
                .setCharge(1.0)
                .setNumber(10010)
                .setType(Bicycle.SHARED);
        mBicycle=builder.build();
        updateView(mBicycle);
    }
    /**
     * OFO   
     * @param view
     */
    public void Ofo(View view) {
        Bicycle.BicycleBuilder builder=new Bicycle.BicycleBuilder()
                .setColor("  ")
                .setName("OFO  ")
                .setCharge(0.5)
                .setNumber(40010)
                .setType(Bicycle.SHARED);
        mBicycle=builder.build();
        updateView(mBicycle);
    }
    private void updateView(Bicycle mBicycle) {
        bike_result.setText("");
        bike_result.setText(mBicycle.toString());
    }
}  Bicycle. Bicycle Builder 가 제공 하 는 일련의 set 방법 을 통 해 우 리 는 mobike 인 스 턴 스 와 of 자전거 인 스 턴 스 를 만 들 었 습 니 다.
이것 이 바로 Builder 모드 입 니 다. 장면 에서 언급 한 바 와 같이 Builder 모드 를 통 해 같은 구축 과정 에서 우 리 는 서로 다른 결 과 를 만 들 수 있 습 니 다. 일반적으로 우리 가 만 들 대상 은 매우 복잡 하고 많은 매개 변수 가 있 습 니 다. 이런 매개 변수 중 일 부 는 필수 적 입 니 다. 예 를 들 어 OKHttp 에서 Request 의 url 매개 변 수 는 기본 값 도 있 습 니 다. 한 마디 로 하면, Builder 모드, 대상 생 성 형 디자인 모델, 우리 가 대상 을 만 드 는 데 방향 을 제공 합 니 다.
마지막 으로 Builder 모드 를 사용 한 것 - RxJava. RxJava 하면 관찰자 모드 를 쉽게 떠 올 릴 수 있 습 니 다. 좋 습 니 다. RxJava 의 가장 핵심 적 인 사상 은 관찰자 모드 입 니 다. 하지만 RxJava 를 사용 하 는 과정 을 생각해 보 세 요.
        ArrayList datas = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            datas.add("item_" + i);
        }
        Observable.just(datas)
                .flatMap(new Func1, Observable>() {
                    @Override
                    public Observable call(ArrayList strings)   {
                        return Observable.from(strings);
                    }
                })
                .map(new Func1() {
                    @Override
                    public Integer call(String s) {
                        return s.hashCode();
                    }
                })
                .subscribe(new Action1() {
                    @Override
                    public void call(Integer Integer) {
                        Log.e(MainActivity.class.getSimpleName(), "call---->" + Integer);
                    }
                });       위 코드 에서 보 듯 이 subscribe 방법 이 실행 되 기 전에 다양한 조작 자 를 통 해 원시 데이터 인 Array List 는 Integer 형식의 데이터 가 되 었 습 니 다. 즉, 우리 가 조작 자 를 사용 하 는 과정 은 Builder 모델 을 구축 하 는 과정 입 니 다. 우리 가 최종 적 으로 필요 로 하 는 제품 이 생 성 될 때 까지 입 니 다. 이것 은 Builder 모델 의 정의 와 사용 장면 과 완전히 일치 합 니 다.맞았어
Builder 모드 VS 공장 방법 모드
공장 모델 은 일반적으로 하나의 제품 을 만 드 는 것 입 니 다. 이 제품 을 만 드 는 것 을 중시 합 니 다. 만 들 기만 하면 이 제품 의 구성 부분 에 관심 이 없습니다. 코드 로 볼 때 공장 모델 은 하나의 방법 입 니 다. 이 방법 으로 제품 을 생산 할 수 있 습 니 다.
건설 자 모델 도 하나의 제품 을 만 들 지만 이 제품 을 만 들 뿐만 아니 라 이 제품 의 구성 디 테 일, 구성 과정 과 도 관련 이 있다. 코드 를 보면 건설 자 모델 은 제품 을 만 들 때 이 제품 은 여러 가지 방법 이 있다. 건설 자 모델 은 이 같은 방법 이지 만 실행 순서에 따라 서로 다른 디 테 일 을 구성 하 는 제품 을 만든다.
공장 모델 은 전체 에 관심 을 가지 고 건설 자 모델 은 세부 사항 에 관심 을 가진다.
마지막.
지금 우리 가 전에 제기 한 문제 로 돌아 가면 Builder 모델 의 의 미 는 무엇 입 니까? 다 본 후에 당신 은 이미 답 을 얻 었 을 것 입 니 다. 실질 적 인 의미 가 없습니다. Builder 모델 의 사용 은 우리 의 코드 운행 속 도 를 가속 화하 지 않 습 니 다. 디자인 모델 은 전체적으로 포장, 계승, 다 형 과 관련 된 반복 적 인 사용 입 니 다. 프로 그래 밍 기술 로 우리 가 쓸 수 있 습 니 다.고 품질 코드 의 기교.
마지막 으로 다시 한 번 말씀 드 리 지만, 엄 밀 히 말 하면 본 논문 에서 논의 한 Builder 모델 은 표준 적 인 의미 의 Builder 모델 이 아 닙 니 다. 여기 서 우 리 는 Android 소스 코드 의 측면 에서 Builder 모델 을 간소화 하고 체인 호출 과 습관 을 편리 하 게 하기 위해 원래 있 던 Director 역할 을 버 렸 습 니 다. 정통 적 인 Builder 모델 에 관심 이 있 는 학생 들 은 다시 깊이 연구 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.