设计模式(二)AlertDialog中的建造者模式

一、基本概念:

1、定义:

将一个复杂对象构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2、适用场景:
  • 多个组成部分,都可以装配到同一个对象,但是产生的结果不相同
  • 相同的方法,不同的执行顺序,产生不同的事件结果
  • 产品特别复杂,参数比较多的情况 例:电脑含有很多零配件,可以算是一个复杂对象。其中内存卡,主板、CPU等都是电脑的组成部分,如果构建一台电脑,不需要知道是如何组装的,只需要提供所需要的零配件型号,此时就可以用构建者模式。
3、优点:
  • 封装性好,可以使使用者不必知道内部组成的细节
  • 建造者独立,容易扩展
4、类图:

  • Director:导演类,负责安排模块顺序,通知Builder开始构建
  • Builder:抽象Builder类,规范产品的组建
  • ConcreteBuilder:构造者实现类,实现抽象类的所有方法,并且返回一个组建好的对象
  • Product:产品类

二、实例:

1、产品实体类:
public class Computer {
    private String cpu;
    private String mainBoard;
    private String ram;

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getMainBoard() {
        return mainBoard;
    }

    public void setMainBoard(String mainBoard) {
        this.mainBoard = mainBoard;
    }

    public String getRam() {
        return ram;
    }

    public void setRam(String ram) {
        this.ram = ram;
    }
}
复制代码
2、抽象Builder:
public abstract class Builder {
    public abstract void buildCpu(String cpu);
    public abstract void buildMainBoard(String mainBoard);
    public abstract void buildRam(String ram);
    public abstract Computer build();
}
复制代码
3、Builder实现类:
public class ComputerBuilder extends Builder {
    private Computer mComputer = new Computer();
    
    @Override
    public void buildCpu(String cpu) {
        mComputer.setCpu(cpu);
    }

    @Override
    public void buildMainBoard(String mainBoard) {
        mComputer.setMainBoard(mainBoard);
    }

    @Override
    public void buildRam(String ram) {
        mComputer.setRam(ram);
    }

    @Override
    public Computer build() {
        return mComputer;
    }
}
复制代码
4、导演类:

起到封装的作用,避免深入到Builder内部的具体实现。可以传入不同的Builder实现对象。

public class ComputerDirector {
    private Builder mBuilder;

    private ComputerDirector(Builder builder) {
        this.mBuilder = builder;
    }

    public Computer createComputer(String cpu, String mainBoard, String ram) {
        mBuilder.buildCpu(cpu);
        mBuilder.buildMainBoard(mainBoard);
        mBuilder.buildRam(ram);
        return mBuilder.build();
    }
}
复制代码
5、客户端调用:
public class ComputerTest {
    public static void main(String[] args){
        Builder builder = new ComputerBuilder();
        ComputerDirector director = new ComputerDirector(builder);
        director.createComputer("i3","my board", "4g");
    }
}
复制代码

在实际使用过程中,有时会将Director进行省略,由调用者选择部分参数进行设置

三、AlertDialog

1、Builder

public static class Builder {

    private final AlertController.AlertParams P;

    public Builder(Context context) {
        this(context, resolveDialogTheme(context, 0));
    }

    public Builder(Context context, int themeResId) {
        P = new AlertController.AlertParams(new ContextThemeWrapper(
                context, resolveDialogTheme(context, themeResId)));
    }
   
    public Builder setTitle(@StringRes int titleId) {
        P.mTitle = P.mContext.getText(titleId);
        return this;
    }

    public Builder setCustomTitle(View customTitleView) {
        P.mCustomTitleView = customTitleView;
        return this;
    }

    public Builder setMessage(@StringRes int messageId) {
        P.mMessage = P.mContext.getText(messageId);
        return this;
    }
    ......

    public AlertDialog create() {
        // Context has already been wrapped with the appropriate theme.
        final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
        //调用了AlertParams的apply方法
        P.apply(dialog.mAlert);
        dialog.setCancelable(P.mCancelable);
        if (P.mCancelable) {
            dialog.setCanceledOnTouchOutside(true);
        }
        dialog.setOnCancelListener(P.mOnCancelListener);
        dialog.setOnDismissListener(P.mOnDismissListener);
        if (P.mOnKeyListener != null) {
            dialog.setOnKeyListener(P.mOnKeyListener);
        }
        return dialog;
    }

    public AlertDialog show() {
        final AlertDialog dialog = create();
        dialog.show();
        return dialog;
    }

}
复制代码

Builder中定义了一些set方法用来设置Dialog的参数,Builder方法内部是给AlertController.AlertParams进行参数赋值

2、AlertDialog.AlertParams
public static class AlertParams {
    public final Context mContext;
    public final LayoutInflater mInflater;

    public int mIconId = 0;
    public Drawable mIcon;
    public int mIconAttrId = 0;
    public CharSequence mTitle;
    public View mCustomTitleView;
    public CharSequence mMessage;
    public CharSequence mPositiveButtonText;
    ......

    public AlertParams(Context context) {
        mContext = context;
        mCancelable = true;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    //将参数赋值给了Dialog
    public void apply(AlertController dialog) {
        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);
        }
        ......
    }
} 
复制代码
3、基本使用
AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // 设置参数
builder.setTitle("")
    .setIcon(R.drawable.ic_launcher)
    .setMessage("");
builder.create().show();
复制代码
  • 先创建一个Builder对象,通过Builder进行参数设置
  • 内部会将这些参数传递给AlertDialog.AlertParams
  • 在调用create方法时,AlertDialog.AlertParams再将参数设置给AlertDialog
  • 最终通过show方法显示dialog

Builder模式通常作为配置类的构造器将配置的构造和表示分离,并且通过调用链实现,使代码调用更简洁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值