1. 程式人生 > >設計模式之構建者Builder模式

設計模式之構建者Builder模式

在前一段時間因為業務需求,標題欄的樣式變得越來越多的元素增加,導致在TitleBarView(標題欄)的構造方法變得十分的累贅,於是我開始著手優化TitleBarView。

場景分析

    public void initBannerView(String title) {
        initBannerView(title, mBack, null);
    }

    public void initBannerView(String title, View.OnClickListener l, View.OnClickListener r) {
        initBannerView(title, l, r, 0
); } public void initBannerView(String title, View.OnClickListener l, View.OnClickListener r, int rightIcon) { ··· }

這是原本的TitleView的方法,但是新的需求下,需要新增構造方法,TitleBarView將會越來越複雜。首先我們看一下這種採用重疊構造器的不足,引數不多的情況下,是比較方便快捷的,一旦引數多了,程式碼可讀性大大降低,並且難以維護,對呼叫者來說也造成一定困惑;在《Effective Java》中提及到,當遇到多個構造器引數時,我們要考慮選擇用構建器。

Builder模式

Builder模式是不直接生成想要的物件,而是讓客戶端利用所有必要的引數呼叫構造器,得到一個builder物件,然後客戶端在builder物件上呼叫類似setter方法,來設定每一個相關的可選引數,最後客戶端再呼叫無參的builder方法來生成所需的物件。下面就是他的示例:

public class TitleBarView {
    private String title;
    private OnClickListener leftListener;
    private OnClickListener rightListener;
    private
int rightIcon; public static final class Builder { private String title = "預設值標題"; private OnClickListener leftListener = null; private OnClickListener rightListener = null; private int rightIcon = -1; public Builder(String title, OnClickListener leftListener) { this.title = title; this.leftListener = leftListener; } public Builder rightClickListener(OnClickListener rightListener) { this.rightListener = rightListener; return this; } public Builder rightIcon(int rightIcon) { this.rightIcon = rightIcon; return this; } public TitleBarView builder() { // TODO Auto-generated constructor stub return new TitleBarView(this); } } private TitleBarView(Builder builder) { this.title = builder.title; this.leftListener = builder.leftListener; this.rightListener = builder.rightListener; this.rightIcon = builder.rightIcon; } }

呼叫方式

new TitleBarView.Builder("Builder模式", null).rightIcon(R.drawable.ic_launcher).builder();

這樣客戶端可以根據需要來對用到的值進行設定。同時在需求變更的時候,可以在TitleBarView類下進行修改,Builder模式採用鏈式呼叫,可讀性和擴充套件性都很好。

Builder模式例子

  • Android中的AlertDialog.Builder
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle("Title");
        builder.setMessage("message");
        builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        builder.setCancelable(false);
        builder.show();
  • Retrofit2中Retrofit物件的建立
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();

從官方的AlertDialog,到現在熱門的第三方開源庫都採用了Builder模式來構建其對應的使用物件,可想而知Builder的確是一個不錯的選擇。在《Effective Java》中的總結是如果類的構造器或者靜態工廠中具有多個引數,設計這種類時,Builder模式就是中不錯的選擇,特別是當大多數引數都是可選的時候,與使用傳統的重疊構造器模式想比,使用Builder模式的客戶端程式碼更易於閱讀和編寫,構建器也比JavaBeans更加安全。

下面我來介紹一下Android Studio的外掛InnerBuilder:

下載外掛:
這裡寫圖片描述
重啟Android Studio

寫好要準備構建的類的變數:

    private String title;
    private View.OnClickListener leftListener;
    private View.OnClickListener rightListener;
    private int rightIcon;

按ALT+SHIFT+S在Generate找到Builder:
這裡寫圖片描述

選中要使用 Builder 構建的物件,然後勾選使用的配置,點選OK:
這裡寫圖片描述
程式碼一鍵生成,我就不重複貼程式碼了,大家可以嘗試一下。