Builder模式概述
Builder模式(Builder Pattern)是一种创建型设计模式,它用于构建复杂对象的实例。该模式将对象的构建过程与对象的表示分离,使得相同的构建过程可以创建不同的表示。Builder模式通常用于以下情况:
- 需要生成的对象包含很多字段和复杂的构建步骤。
- 构建过程中需要一步步进行,而不是一步到位。
- 需要在不使用构造函数时提供更灵活的对象创建方式。
Builder模式的结构
Builder模式通常由以下几个部分组成:
- Product(产品): 最终要创建的复杂对象。
- Builder(构建者): 构建过程的抽象接口,定义创建产品各个部分的方法。
- ConcreteBuilder(具体构建者): 实现 Builder 接口,具体构建各个部分,并最终组装成产品对象。
- Director(导演): 负责调用构建者的方法一步步创建产品对象,控制构建过程。
- Client(客户端): 创建一个具体的构建者对象并通过导演构建产品。
Builder模式示例
以下是一个简单的 Builder 模式示例,用于构建一个 Person
对象。
Product(产品)
public class Person {
private final String firstName;
private final String lastName;
private final int age;
private final String address;
// 私有构造函数,只能通过 Builder 创建
private Person(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.address = builder.address;
}
// Getter方法...
}
Builder(构建者)
public static class Builder {
private String firstName;
private String lastName;
private int age;
private String address;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setLastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public Person build() {
return new Person(this);
}
}
Client(客户端)
public class Client {
public static void main(String[] args) {
Person person = new Person.Builder()
.setFirstName("John")
.setLastName("Doe")
.setAge(30)
.setAddress("123 Main St")
.build();
// 使用 person 对象
}
}
结合示例代码理解Builder模式
在 InputDialog
的代码中,Builder模式用于构建和显示输入对话框:
InputDialog
中的Builder模式
public final class InputDialog {
public static final class Builder extends CommonDialog.Builder<Builder> implements BaseDialog.OnShowListener, TextView.OnEditorActionListener {
@Nullable
private OnListener mListener;
private final RegexEditText mInputView;
public Builder(Context context) {
super(context);
setCustomView(R.layout.input_dialog);
mInputView = findViewById(R.id.tv_input_message);
mInputView.setOnEditorActionListener(this);
addOnShowListener(this);
}
public Builder setHint(@StringRes int id) {
return setHint(getString(id));
}
public Builder setHint(CharSequence text) {
mInputView.setHint(text);
return this;
}
public Builder setContent(@StringRes int id) {
return setContent(getString(id));
}
public Builder setContent(CharSequence text) {
mInputView.setText(text);
Editable editable = mInputView.getText();
if (editable == null) {
return this;
}
int index = editable.length();
if (index <= 0) {
return this;
}
mInputView.requestFocus();
mInputView.setSelection(index);
return this;
}
public Builder setInputRegex(String regex) {
mInputView.setInputRegex(regex);
return this;
}
public Builder setListener(OnListener listener) {
mListener = listener;
return this;
}
@Override
public void onShow(BaseDialog dialog) {
postDelayed(() -> showKeyboard(mInputView), 500);
}
@SingleClick
@Override
public void onClick(View view) {
int viewId = view.getId();
if (viewId == R.id.tv_ui_confirm) {
autoDismiss();
if (mListener == null) {
return;
}
Editable editable = mInputView.getText();
mListener.onConfirm(getDialog(), editable != null ? editable.toString() : "");
} else if (viewId == R.id.tv_ui_cancel) {
autoDismiss();
if (mListener == null) {
return;
}
mListener.onCancel(getDialog());
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
onClick(findViewById(R.id.tv_ui_confirm));
return true;
}
return false;
}
}
public interface OnListener {
void onConfirm(BaseDialog dialog, String content);
default void onCancel(BaseDialog dialog) {
}
}
}
使用Builder构建InputDialog
new InputDialog.Builder(this)
.setTitle(getString(R.string.personal_data_name_hint))
.setContent(mNameView.getRightText())
.setListener((dialog, content) -> {
if (!mNameView.getRightText().equals(content)) {
mNameView.setRightText(content);
}
})
.show();
通过Builder模式,创建和显示InputDialog
变得简单和直观,同时使代码更加清晰易读。