BUILDER?MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞掂,这就是我的“我爱你”builder。(这一定比美军在伊拉克用的翻译机好卖) 建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
I love you(英语)
あなたのことが好きです(日语)
사랑해요(韩语)
请不要问我怎么会说这么多种语言
好吧,我要用设计模式实现它:
首先声明一个抽象类:
package com.soyoungboy.builder; public abstract class Builder { abstract String getString(); }
package com.soyoungboy.builder; public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public String construct(){ return builder.getString(); } }
package com.soyoungboy.builder; public class EnglishBuild extends Builder { @Override String getString() { return " I Love You"; } }
package com.soyoungboy.builder; public class JapaneseBuild extends Builder{ @Override String getString() { return "あなたのことが好きです"; } }
package com.soyoungboy.builder; public class KoreanBuild extends Builder { @Override String getString() { return "사랑해요"; } }
package com.soyoungboy.builder; public class Main { public static void main(String[] args) { Builder builder = new EnglishBuild(); Director d = new Director(builder); String love = d.construct(); System.out.println(love); Builder builder1 = new JapaneseBuild(); Director d1 = new Director(builder1); String love1 = d1.construct(); System.out.println(love1); Builder builder2 = new KoreanBuild(); Director d2 = new Director(builder2); String love2 = d2.construct(); System.out.println(love2); } }
运行结果为:
I Love You
あなたのことが好きです
사랑해요
建造者设计模式在android中的使用:
设计Ios风格的dialog的自定义dialog中,
使用Builder模式来替代多参数构造函数。
Builder模式的要点就是通过一个代理来完成对象的构建过程。这个代理职责就是完成构建的各个步骤,同时它也是易扩展的。
1 public class IosDialog extends Dialog { 2 3 public IosDialog(Context context) { 4 super(context); 5 } 6 7 public IosDialog(Context context, int theme) { 8 super(context, theme); 9 } 10 11 public static class Builder { 12 private Context context; // 上下文对象 13 private int color; // 上下文对象 14 private int messageColor; // 上下文对象 15 private int resid; // 上下文对象 16 private String title; // 对话框标题 17 private String message; // 对话框内容 18 private String confirm_btnText; // 按钮名称“确定” 19 private String cancel_btnText; // 按钮名称“取消” 20 private String neutral_btnText; // 按钮名称“隐藏” 21 private View contentView; // 对话框中间加载的其他布局界面 22 /* 按钮坚挺事件 */ 23 private DialogInterface.OnClickListener confirm_btnClickListener; 24 private DialogInterface.OnClickListener cancel_btnClickListener; 25 private DialogInterface.OnClickListener neutral_btnClickListener; 26 27 public Builder(Context context) { 28 this.context = context; 29 } 30 31 /* 设置对话框信息 */ 32 public Builder setMessage(String message) { 33 this.message = message; 34 return this; 35 } 36 37 public Builder setMessageColor(int messageColor) { 38 this.messageColor = messageColor; 39 return this; 40 } 41 42 public void setMessageBackGround(int resid) { 43 this.resid = resid; 44 } 45 46 /** 47 * Set the Dialog message from resource 48 * 49 * @param title 50 * @return 51 */ 52 public Builder setMessage(int message) { 53 this.message = (String) context.getText(message); 54 return this; 55 } 56 57 /** 58 * Set the Dialog title from resource 59 * 60 * @param title 61 * @return 62 */ 63 public Builder setTitle(int title) { 64 this.title = (String) context.getText(title); 65 return this; 66 } 67 68 public Builder setTitleTextColor(int color) { 69 this.color = color; 70 return this; 71 } 72 73 /** 74 * Set the Dialog title from String 75 * 76 * @param title 77 * @return 78 */ 79 public Builder setTitle(String title) { 80 this.title = title; 81 return this; 82 } 83 84 /** 85 * 设置对话框界面 86 * 87 * @param v 88 * View 89 * @return 90 */ 91 public Builder setContentView(View v) { 92 this.contentView = v; 93 return this; 94 } 95 96 /** 97 * Set the positive button resource and it's listener 98 * 99 * @param confirm_btnText 100 * @return 101 */ 102 public Builder setPositiveButton(int confirm_btnText, 103 DialogInterface.OnClickListener listener) { 104 this.confirm_btnText = (String) context.getText(confirm_btnText); 105 this.confirm_btnClickListener = listener; 106 return this; 107 } 108 109 /** 110 * Set the positive button and it's listener 111 * 112 * @param confirm_btnText 113 * @return 114 */ 115 public Builder setPositiveButton(String confirm_btnText, 116 DialogInterface.OnClickListener listener) { 117 this.confirm_btnText = confirm_btnText; 118 this.confirm_btnClickListener = listener; 119 return this; 120 } 121 122 /** 123 * Set the negative button resource and it's listener 124 * 125 * @param confirm_btnText 126 * @return 127 */ 128 public Builder setNegativeButton(int cancel_btnText, 129 DialogInterface.OnClickListener listener) { 130 this.cancel_btnText = (String) context.getText(cancel_btnText); 131 this.cancel_btnClickListener = listener; 132 return this; 133 } 134 135 /** 136 * Set the negative button and it's listener 137 * 138 * @param confirm_btnText 139 * @return 140 */ 141 public Builder setNegativeButton(String cancel_btnText, 142 DialogInterface.OnClickListener listener) { 143 this.cancel_btnText = cancel_btnText; 144 this.cancel_btnClickListener = listener; 145 return this; 146 } 147 148 /** 149 * Set the netural button resource and it's listener 150 * 151 * @param confirm_btnText 152 * @return 153 */ 154 public Builder setNeutralButton(int neutral_btnText, 155 DialogInterface.OnClickListener listener) { 156 this.neutral_btnText = (String) context.getText(neutral_btnText); 157 this.neutral_btnClickListener = listener; 158 return this; 159 } 160 161 /** 162 * Set the netural button and it's listener 163 * 164 * @param confirm_btnText 165 * @return 166 */ 167 public Builder setNeutralButton(String neutral_btnText, 168 DialogInterface.OnClickListener listener) { 169 this.neutral_btnText = neutral_btnText; 170 this.neutral_btnClickListener = listener; 171 return this; 172 } 173 174 public IosDialog create() { 175 LayoutInflater inflater = (LayoutInflater) context 176 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 177 // instantiate the dialog with the custom Theme 178 final IosDialog dialog = new IosDialog(context, R.style.mystyle); 179 View layout = inflater.inflate(R.layout.customdialog, null); 180 dialog.addContentView(layout, new LayoutParams( 181 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 182 TextView titleTv = (TextView) layout.findViewById(R.id.title); 183 titleTv.setText(title); 184 titleTv.setTextColor(color); 185 titleTv.getPaint().setFakeBoldText(false); 186 187 TextView messageTv = (TextView) layout.findViewById(R.id.message); 188 if (title == null || title.trim().length() == 0) { 189 messageTv.setGravity(Gravity.CENTER); 190 } 191 192 Button confirm_btn = (Button) layout.findViewById(R.id.confirm_btn); 193 if (neutral_btnText != null && confirm_btnText != null 194 && cancel_btnText != null) { 195 confirm_btn.setText(confirm_btnText); 196 Button neutral_btn = (Button) layout 197 .findViewById(R.id.neutral_btn); 198 if (neutral_btnClickListener != null) { 199 neutral_btn.setOnClickListener(new View.OnClickListener() { 200 public void onClick(View v) { 201 neutral_btnClickListener.onClick(dialog, 202 DialogInterface.BUTTON_NEUTRAL); 203 } 204 }); 205 } else { 206 neutral_btn.setOnClickListener(new View.OnClickListener() { 207 208 @Override 209 public void onClick(View v) { 210 dialog.dismiss(); 211 } 212 }); 213 } 214 } else { 215 // if no confirm button or cancle button or neutral just set the 216 // visibility to GONE 217 layout.findViewById(R.id.neutral_btn).setVisibility(View.GONE); 218 layout.findViewById(R.id.single_line).setVisibility(View.GONE); 219 } 220 // set the confirm button 221 if (confirm_btnText != null) { 222 confirm_btn.setText(confirm_btnText); 223 if (confirm_btnClickListener != null) { 224 confirm_btn.setOnClickListener(new View.OnClickListener() { 225 public void onClick(View v) { 226 confirm_btnClickListener.onClick(dialog, 227 DialogInterface.BUTTON_POSITIVE); 228 } 229 }); 230 } else { 231 confirm_btn.setOnClickListener(new View.OnClickListener() { 232 233 @Override 234 public void onClick(View v) { 235 dialog.dismiss(); 236 } 237 }); 238 } 239 } else { 240 // if no confirm button just set the visibility to GONE 241 layout.findViewById(R.id.confirm_btn).setVisibility(View.GONE); 242 layout.findViewById(R.id.second_line).setVisibility(View.GONE); 243 layout.findViewById(R.id.cancel_btn).setBackgroundResource( 244 R.drawable.single_btn_select); 245 } 246 // set the cancel button 247 if (cancel_btnText != null) { 248 ((Button) layout.findViewById(R.id.cancel_btn)) 249 .setText(cancel_btnText); 250 if (cancel_btnClickListener != null) { 251 ((Button) layout.findViewById(R.id.cancel_btn)) 252 .setOnClickListener(new View.OnClickListener() { 253 public void onClick(View v) { 254 cancel_btnClickListener.onClick(dialog, 255 DialogInterface.BUTTON_NEGATIVE); 256 } 257 }); 258 } else { 259 ((Button) layout.findViewById(R.id.cancel_btn)) 260 .setOnClickListener(new View.OnClickListener() { 261 262 @Override 263 public void onClick(View v) { 264 dialog.dismiss(); 265 } 266 }); 267 } 268 } else { 269 // if no cancel button just set the visibility to GONE 270 layout.findViewById(R.id.cancel_btn).setVisibility(View.GONE); 271 layout.findViewById(R.id.second_line).setVisibility(View.GONE); 272 layout.findViewById(R.id.confirm_btn).setBackgroundResource( 273 R.drawable.single_btn_select); 274 } 275 // set the content message 276 if (message != null) { 277 messageTv.setText(message); 278 messageTv.setTextColor(messageColor); 279 messageTv.setBackgroundResource(resid); 280 } else if (contentView != null) { 281 // if no message set 282 // add the contentView to the dialog body 283 ((LinearLayout) layout.findViewById(R.id.message)) 284 .removeAllViews(); 285 ((LinearLayout) layout.findViewById(R.id.message)).addView( 286 contentView, new LayoutParams( 287 LayoutParams.WRAP_CONTENT, 288 LayoutParams.WRAP_CONTENT)); 289 } 290 dialog.setContentView(layout); 291 return dialog; 292 } 293 294 } 295 }
在实际使用这个dialog,使用串使的set来设置dialog的参数,来修改dialog的风格,返回不同的builder对象:
ibuilder = new IosDialog.Builder(mContext) .setTitle("退出") .setTitleTextColor(getResources().getColor(R.color.c6)) .setMessageColor(getResources().getColor(R.color.c6)) .setMessage("确定要退出吗?") .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { arg0.cancel(); } }); ibuilder.create().show();
建造者设计模式封装了实现的细节,因为调用不同的方法,创建出来的对象所具有的属性特征就不同。当对象参数很多的时候比较适合采用建造者设计模式去实现,不必写冗长的构造方法。比较优雅的创建合适的带有不同特征的对象。
再实际开发过程中,Director角色经常会被忽略掉,而直接使用Builder来进行对象的组装,这个builder通常为链式调用,关键是每个setter方法返回自身,也就是说return this,整个结构变得更加简单,对对象的组装过程更精细的控制。