1. 程式人生 > >設計模式——構造者模式

設計模式——構造者模式

我儘量不打錯別字,用詞準確,不造成閱讀障礙。

構造者模式是我知道的設計模式中在單例模式後最簡單的模式,入門理解很簡單。

解釋:將一個複雜物件的構造與它的表示分離,使得同樣的構造過程可以建立不同的表示。

表現形式:鏈式呼叫。

構造者模式可以用來做工具類的使用,還可以有效解決傳遞引數過多的情況。

概念難理解,舉例(Android),把例子看明白了再回頭看看概念其實最合適:

AlertDialog

AlertDialog dialog = new AlertDialog.Builder(this)
  .setIcon(...)
  .setTitle("..."
) .setPositiveButton(...) .setNegationButton(...) .create(); dialog.show();

OKHttp

OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
OkHttpClient client = httpBuilder.connectTimeout(50, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30
, TimeUnit.SECONDS) .build();

簡單明瞭的鏈式呼叫。

手寫簡單構造者

手寫一個構造者,以自定義Dialog為例。

public class DialogUtil extend Dialog{
  private Context mContext;
  private int img;
  private String content;
  private boolean CancelOnTouchOutside = true;

  private DialogUtil(DialogBuilder builder){
    super
(builder.context); } //可以設定style private DialogUtil2(DialogBuilder builder, int style) { super(builder.context, style); mContext = builder.context; img = builder.img; text = builder.text; CanceledOnTouchOutside = builder.CanceledOnTouchOutside; } //重寫onCreate方法 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View view = View.inflate(mContext, R.layout.dialog_result, null); //自定義佈局 ImageView img_view = (ImageView) view.findViewById(R.id.iv_img); TextView text_view = (TextView) view.findViewById(R.id.tv_text); img_view.setImageResource(img); text_view.setText(content); setContentView(view); Window win = getWindow(); WindowManager.LayoutParams lp = win.getAttributes(); setCanceledOnTouchOutside(CanceledOnTouchOutside); lp.gravity = Gravity.CENTER; } //重寫show方法 @Override public void show() { super.show(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000);//顯示2秒後自動消失,視情況修改方法 dismiss(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } public static class DialogBuilder { private Context context; private String content = "操作成功"; private int img; private boolean CanceledOnTouchOutside = true; private int style = -1; public DialogBuilder(Context context) { this.context = context; img= R.drawable.toast_1; } public Builder setText(String content) { this.context = content; return this; //重要的是這句 } public Builder setImg(int imgResource) { this.img = imgResource; return this; } public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) { CanceledOnTouchOutside = canceledOnTouchOutside; } public Builder setStyle(int style) { this.style = style; return this; } public DialogUtil2 build() { if (style != -1) { return new DialogUtil2(this, style); } else { return new DialogUtil2(this); } } } }

使用:

DialogUtil2.DialogBuilder builder = new DialogUtil2.DialogBuilder(this);
builder.setText("xxxxxx").setStyle(R.style.loading_dialog).build().show();

效果:

builder_show

總體過程是這樣的:直接new一個DialogUtil的內部類Builder,將想要新增的內容設定到Builder的屬性中去,每次設定屬性時通過return this;的方式返回builder物件,所有屬性設定完成後,通過build方法new外部類的物件並將builder物件傳遞進去,然後在構造方法中將builder的屬性設定到外部類的屬性中去,最後呼叫外部類的show()方法顯示。

理論解釋:

上面的舉例其實不能很好的解釋構造者模式的構成,只是開發中經常這麼寫,我覺得從日常開發角度理解可以快速入門,之後才是深層次的理解。實際上構造者模式由四部分構成:Builder(抽象建造者)ConcreteBuilder(具體建造者)Product(產品)Director(指揮者)

Builder:是為建立一個Product物件的各個部件指定的抽象介面,本例中並沒有寫,因為寫了內部類。

ConcreteBuilder:具體建造者,實現Builder介面,構造和裝配各個部件,本例中的DialogBuilder。

Product:具體的產品,本例中的並不容易看出來,實際上是具體的Dialog,我們的最終目的就是建造出Dialog。

Director:構建一個使用Builder介面的物件,本例中的DialogUtil2。

怎麼理解概念:將一個複雜物件的構造與它的表示分離,使得同樣的構造過程可以建立不同的表示。

在上例中的意思就是,我想要創造一個畫著”x”符號的dialog,並寫上“操作失敗”,直接重新new一個DialogUtil2.DialogBuilder(this)就好了,這樣就改變了內部表示,而具體的建造方式和建造流程卻沒有絲毫改變

總覺得寫的不好,本人實際開發中主要是Android中使用,所以舉例Android,舉例雖然不能很好的詮釋傳統建造者模式,但是在Android中比較常見,所以還是決定這個例子,也就做個入門使用理解。