Builder设计模式构建整个应用的万能Dialog.docx
- 文档编号:28132979
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:22
- 大小:167.20KB
Builder设计模式构建整个应用的万能Dialog.docx
《Builder设计模式构建整个应用的万能Dialog.docx》由会员分享,可在线阅读,更多相关《Builder设计模式构建整个应用的万能Dialog.docx(22页珍藏版)》请在冰豆网上搜索。
Builder设计模式构建整个应用的万能Dialog
Builder设计模式-构建整个应用的万能Dialog
1.概述
上一期的热修复相对来说有点难度,我其实也没往深里说如果实在看不懂可以看看视频,其实最主要的还是思路代码也就那么几行,这一期我们又回归到设计模式,相对来说要简单不少,这一期要讲的是一行代码如何显示所有弹出框效果。
2.模式介绍
模式的定义
将一个复杂对象的构建与它的表示分离,使得不同的构建过程可以创建不同的显示,但其根本还是不变。
模式的使用场景
相同的方法,不同的执行顺序,产生不同的事件结果时;
多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时;
产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
3.UML类图
角色介绍
-Product产品类:
产品的抽象类;
-Builder:
抽象类,规范产品的组建,一般是由子类实现具体的组件过程;
-ConcreteBuilder:
具体的构建器;
-Director:
统一组装过程(可省略)。
4.模式的简单实现
简单实现的介绍
电脑的组装过程较为复杂,步骤繁多,但是顺序却是不固定的。
下面我们以组装电脑为例来演示一下简单且经典的builder模式。
实现源码
packagecom.dp.example.builder;
/**
*Computer产品抽象类,为了例子简单,只列出这几个属性
*
*@authormrsimple
*
*/
publicabstractclassComputer{
protectedintmCpuCore=1;
protectedintmRamSize=0;
protectedStringmOs="Dos";
protectedComputer(){
}
//设置CPU核心数
publicabstractvoidsetCPU(intcore);
//设置内存
publicabstractvoidsetRAM(intgb);
//设置操作系统
publicabstractvoidsetOs(Stringos);
@Override
publicStringtoString(){
return"Computer[mCpuCore="+mCpuCore+",mRamSize="+mRamSize
+",mOs="+mOs+"]";
}
}
packagecom.dp.example.builder;
/**
*Apple电脑
*/
publicclassAppleComputerextendsComputer{
protectedAppleComputer(){
}
@Override
publicvoidsetCPU(intcore){
mCpuCore=core;
}
@Override
publicvoidsetRAM(intgb){
mRamSize=gb;
}
@Override
publicvoidsetOs(Stringos){
mOs=os;
}
}
packagecom.dp.example.builder;
packagecom.dp.example.builder;
/**
*builder抽象类
*
*/
publicabstractclassBuilder{
//设置CPU核心数
publicabstractvoidbuildCPU(intcore);
//设置内存
publicabstractvoidbuildRAM(intgb);
//设置操作系统
publicabstractvoidbuildOs(Stringos);
//创建Computer
publicabstractComputercreate();
}
packagecom.dp.example.builder;
publicclassApplePCBuilderextendsBuilder{
privateComputermApplePc=newAppleComputer();
@Override
publicvoidbuildCPU(intcore){
mApplePc.setCPU(core);
}
@Override
publicvoidbuildRAM(intgb){
mApplePc.setRAM(gb);
}
@Override
publicvoidbuildOs(Stringos){
mApplePc.setOs(os);
}
@Override
publicComputercreate(){
returnmApplePc;
}
}
packagecom.dp.example.builder;
publicclassDirector{
BuildermBuilder=null;
/**
*
*@parambuilder
*/
publicDirector(Builderbuilder){
mBuilder=builder;
}
/**
*构建对象
*
*@paramcpu
*@paramram
*@paramos
*/
publicvoidconstruct(intcpu,intram,Stringos){
mBuilder.buildCPU(cpu);
mBuilder.buildRAM(ram);
mBuilder.buildOs(os);
}
}
/**
*经典实现较为繁琐
*
*@authormrsimple
*
*/
publicclassTest{
publicstaticvoidmain(String[]args){
//构建器
Builderbuilder=newApplePCBuilder();
//Director
DirectorpcDirector=newDirector(builder);
//封装构建过程,4核,内存2GB,Mac系统
pcDirector.construct(4,2,"MacOSX10.9.1");
//构建电脑,输出相关信息
System.out.println("ComputerInfo:
"+builder.create().toString());
}
}
通过Builder来构建产品对象,而Director封装了构建复杂产品对象对象的过程,不对外隐藏构建细节。
5.Android源码中的模式实现
在Android源码中,我们最常用到的Builder模式就是AlertDialog.Builder,使用该Builder来构建复杂的AlertDialog对象。
简单示例如下:
//显示基本的AlertDialog
privatevoidshowDialog(Contextcontext){
AlertDialog.Builderbuilder=newAlertDialog.Builder(context);
builder.setIcon(R.drawable.icon);
builder.setTitle("头部");
builder.setMessage("内容");
builder.setPositiveButton("Button1",
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhichButton){
setTitle("点击了对话框上的Button1");
}
})
.setNeutralButton("Button2",
newDialogInterface.OnClickListener(){
publicvoidonClick(DialogInterfacedialog,intwhichButton){
setTitle("点击了对话框上的Button2");
}
});
builder.create().show();//构建AlertDialog,并且显示
}
效果就不演示了没什么好看的,如果是v7包中的AlertDialog还看得下去,如果是v4包中的惨目忍睹。
下面我们看看AlertDialog的相关源码,你看的可能和我的不一样但大致差不多你懂的:
//AlertDialog
publicclassAlertDialogextendsDialogimplementsDialogInterface{
//Controller,接受Builder成员变量P中的各个参数
privateAlertControllermAlert;
//构造函数
protectedAlertDialog(Contextcontext,inttheme){
this(context,theme,true);
}
//4:
构造AlertDialog
AlertDialog(Contextcontext,inttheme,booleancreateContextWrapper){
super(context,resolveDialogTheme(context,theme),createContextWrapper);
mWindow.alwaysReadCloseOnTouchAttr();
mAlert=newAlertController(getContext(),this,getWindow());
}
//实际上调用的是mAlert的setTitle方法
@Override
publicvoidsetTitle(CharSequencetitle){
super.setTitle(title);
mAlert.setTitle(title);
}
//实际上调用的是mAlert的setCustomTitle方法
publicvoidsetCustomTitle(ViewcustomTitleView){
mAlert.setCustomTitle(customTitleView);
}
publicvoidsetMessage(CharSequencemessage){
mAlert.setMessage(message);
}
//AlertDialog其他的代码省略
//************Builder为AlertDialog的内部类*******************
publicstaticclassBuilder{
//1:
存储AlertDialog的各个参数,例如title,message,icon等.
privatefinalAlertController.AlertParamsP;
//属性省略
/**
*Constructorusingacontextforthisbuilderandthe{@linkAlertDialog}itcreates.
*/
publicBuilder(Contextcontext){
this(context,resolveDialogTheme(context,0));
}
publicBuilder(Contextcontext,inttheme){
P=newAlertController.AlertParams(newContextThemeWrapper(
context,resolveDialogTheme(context,theme)));
mTheme=theme;
}
//Builder的其他代码省略......
//2:
设置各种参数
publicBuildersetTitle(CharSequencetitle){
P.mTitle=title;
returnthis;
}
publicBuildersetMessage(CharSequencemessage){
P.mMessage=message;
returnthis;
}
publicBuildersetIcon(inticonId){
P.mIconId=iconId;
returnthis;
}
publicBuildersetPositiveButton(CharSequencetext,finalOnClickListenerlistener){
P.mPositiveButtonText=text;
P.mPositiveButtonListener=listener;
returnthis;
}
publicBuildersetView(Viewview){
P.mView=view;
P.mViewSpacingSpecified=false;
returnthis;
}
//3:
构建AlertDialog,传递参数
publicAlertDialogcreate(){
//调用newAlertDialog构造对象,并且将参数传递个体AlertDialog
finalAlertDialogdialog=newAlertDialog(P.mContext,mTheme,false);
//5:
将P中的参数应用的dialog中的mAlert对象中
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if(P.mCancelable){
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
if(P.mOnKeyListener!
=null){
dialog.setOnKeyListener(P.mOnKeyListener);
}
returndialog;
}
}
}
可以看到,通过Builder来设置AlertDialog中的title,message,button等参数,这些参数都存储在类型为AlertController.AlertParams的成员变量P中,AlertController.AlertParams中包含了与之对应的成员变量。
在调用Builder类的create函数时才创建AlertDialog,并且将Builder成员变量P中保存的参数应用到AlertDialog的mAlert对象中,即P.apply(dialog.mAlert)代码段。
我们看看apply函数的实现:
publicvoidapply(AlertControllerdialog){
if(mCustomTitleView!
=null){
dialog.setCustomTitle(mCustomTitleView);
}else{
if(mTitle!
=null){
dialog.setTitle(mTitle);
}
if(mIcon!
=null){
dialog.setIcon(mIcon);
}
if(mIconId>=0){
dialog.setIcon(mIconId);
}
if(mIconAttrId>0){
dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
}
}
if(mMessage!
=null){
dialog.setMessage(mMessage);
}
if(mPositiveButtonText!
=null){
dialog.setButton(DialogInterface.BUTTON_POSITIVE,mPositiveButtonText,
mPositiveButtonListener,null);
}
if(mNegativeButtonText!
=null){
dialog.setButton(DialogInterface.BUTTON_NEGATIVE,mNegativeButtonText,
mNegativeButtonListener,null);
}
if(mNeutralButtonText!
=null){
dialog.setButton(DialogInterface.BUTTON_NEUTRAL,mNeutralButtonText,
mNeutralButtonListener,null);
}
if(mForceInverseBackground){
dialog.setInverseBackgroundForced(true);
}
//Foralist,theclientcaneithersupplyanarrayofitemsoran
//adapterorarsor
if((mItems!
=null)||(mCursor!
=null)||(mAdapter!
=null)){
createListView(dialog);
}
if(mView!
=null){
if(mViewSpacingSpecified){
dialog.setView(mView,mViewSpacingLeft,mViewSpacingTop,mViewSpacingRight,
mViewSpacingBottom);
}else{
dialog.setView(mView);
}
}
}
实际上就是把P中的参数挨个的设置到AlertController中,也就是AlertDialog中的mAlert对象。
从AlertDialog的各个setter方法中我们也可以看到,实际上也都是调用了mAlert对应的setter方法。
在这里,Builder同时扮演了上文中提到的builder、ConcreteBuilder、Director的角色,简化了Builder模式的设计。
6.构建整个应用的万能Dialog
AlertDialog其实在我们的开发过程中可能没卵用,一般设计师设计出来的基本都是仿照的iOS的效果,这样一来就算再好用也与我们无缘。
而且在我们的开发过程中效果千奇百怪时而这样,时而那样头疼得很啊,接下来我们就打算采用系统已经提供好的Builder设计模式构建整个应用的万能Dialog,代码可以参考系统的AlertDialog,最终无论什么复杂的效果一行能搞定算得上勉勉强强。
publicstaticclassBuilder{
privateAlertController.AlertParamsP;
publicBuilder(Contextcontext){
this(context,0);
}
publicBuilder(Contextcontext,intthemeResId){
P=newAlertController.AlertParams();
P.themeResId=themeResId;
P.context=context;
}
publicBuildersetText(intviewId,CharSequencetext){
P.textArray.put(viewId,text);
returnthis;
}
publicBuildersetOnClickListener(intviewId,View.OnClickListenerlistener){
P.clickArray.put(viewId,listener);
returnthis;
}
publicBuildersetContentView(intlayoutId){
P.view=null;
P.layoutId=layoutId;
returnthis;
}
publicBuildersetContentView(Viewview){
P.layoutId=0;
P.view=view;
returnthis;
}
/**
*Setswhetherthedialogiscancelableornot.Defaultistrue.
*
*@returnThisBuilderobjecttoallowforchainingofcallstosetmethods
*/
publicBuildersetCancelable(booleancancelable){
P.cancelable=cancelable;
returnthis;
}
/**
*Setsthecallbackthatwillbecalledifthedialogiscanceled.
*
*
Eveninacancelabledialog,thedialogmaybedismissedforreasonsotherthan
*beingcanceledoroneofthesuppliedchoicesbeingselected.
*Ifyouareinterestedinlisteningforallcaseswherethedialogisdismissed
*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Builder设计模式 构建整个应用的万能Dialog Builder 设计 模式 构建 整个 应用 万能 Dialog