設計模式——構造者模式
我儘量不打錯別字,用詞準確,不造成閱讀障礙。
構造者模式是我知道的設計模式中在單例模式後最簡單的模式,入門理解很簡單。
解釋:將一個複雜物件的構造與它的表示分離,使得同樣的構造過程可以建立不同的表示。
表現形式:鏈式呼叫。
構造者模式可以用來做工具類的使用,還可以有效解決傳遞引數過多的情況。
概念難理解,舉例(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();
效果:
總體過程是這樣的:直接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中比較常見,所以還是決定這個例子,也就做個入門使用理解。