Builder mode (builder mode)-creation type

Creation type

1. Singleton design pattern
2. Factory design pattern
3. Builder design pattern
4. Prototype design pattern

Structure type

5. Agency design pattern
6, bridging design pattern
7, decoration design pattern
8, adapter design pattern
9, appearance design pattern
10, flyweight design pattern
11, combination design pattern

Behavioral

12. Template design mode

Introduction:

In the object-oriented development language, the builder mode is the same as the factory mode to create objects; the difference is that the factory mode is used to create different but related types of objects (inheriting the same parent class or a group of subclasses of the interface). The given parameters determine which type of object is created. The builder mode is used to create a type of complex object, by setting different optional parameters, "customized" to create different objects.

Application scenario

Those scenarios will be applied to the builder mode, mainly for the following requirements:

1. A class has many attributes, which must be initialized when the object is created. If you use the constructor to initialize these attributes, the constructor will return very long, too many parameters are not conducive to use, and it is easy to make mistakes, but it cannot be put in the set method. The guaranteed properties must be initialized;

2. If there are certain dependencies or constraints between the attributes of the class, we continue to use the constructor with the design idea of ​​the set() method, then the verification logic of these dependencies or constraints will no longer be placed.

3. If we want to create an immutable object, that is, after the object is created, we can no longer modify the internal attribute value. To achieve this function, we cannot expose the set() method in the class. The way the constructor cooperates with the set() method to set the attribute value is not applicable.

Builder mode implementation

Take a look at the AlertDialog in the Android source code; you can see from the AlertDialog that it is implemented using the creator mode;

Part of the source code:

public class AlertDialog extends Dialog implements DialogInterface {
    private AlertController mAlert;

  
    
    protected AlertDialog(Context context) {
        this(context, 0);
    }

    protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        this(context, 0);

        setCancelable(cancelable);
        setOnCancelListener(cancelListener);
    }

    
    protected AlertDialog(Context context, @StyleRes int themeResId) {
        this(context, themeResId, true);
    }

    AlertDialog(Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        super(context, createContextThemeWrapper ? resolveDialogTheme(context, themeResId) : 0, createContextThemeWrapper);

        mWindow.alwaysReadCloseOnTouchAttr();
        mAlert = AlertController.create(getContext(), this, getWindow());
    }

    @Override
    public void setTitle(CharSequence title) {
        super.setTitle(title);
        mAlert.setTitle(title);
    }

    public void setCustomTitle(View customTitleView) {
        mAlert.setCustomTitle(customTitleView);
    }

    public void setMessage(CharSequence message) {
        mAlert.setMessage(message);
    }

   
    public void setMessageMovementMethod(MovementMethod movementMethod) {
        mAlert.setMessageMovementMethod(movementMethod);
    }

    /** @hide */
    public void setMessageHyphenationFrequency(
            @Layout.HyphenationFrequency int hyphenationFrequency) {
        mAlert.setMessageHyphenationFrequency(hyphenationFrequency);
    }

    /**
     * Set the view to display in that dialog.
     */
    public void setView(View view) {
        mAlert.setView(view);
    }

    
    public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight, int viewSpacingBottom) {
        mAlert.setView(view, viewSpacingLeft, viewSpacingTop, viewSpacingRight, viewSpacingBottom);
    }
    
    public void setIcon(@DrawableRes int resId) {
        mAlert.setIcon(resId);
    }

    public void setIcon(Drawable icon) {
        mAlert.setIcon(icon);
    }

    
    public void setIconAttribute(@AttrRes int attrId) {
        TypedValue out = new TypedValue();
        mContext.getTheme().resolveAttribute(attrId, out, true);
        mAlert.setIcon(out.resourceId);
    }

    public void setInverseBackgroundForced(boolean forceInverseBackground) {
        mAlert.setInverseBackgroundForced(forceInverseBackground);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAlert.installContent();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mAlert.onKeyDown(keyCode, event)) return true;
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (mAlert.onKeyUp(keyCode, event)) return true;
        return super.onKeyUp(keyCode, event);
    }

    public static class Builder {
        private final AlertController.AlertParams P;

        public Builder(Context context) {
            this(context, resolveDialogTheme(context, ResourceId.ID_NULL));
        }

        
        public Builder(Context context, int themeResId) {
            P = new AlertController.AlertParams(new ContextThemeWrapper(
                    context, resolveDialogTheme(context, themeResId)));
        }

        
        public Context getContext() {
            return P.mContext;
        }

        public Builder setTitle(@StringRes int titleId) {
            P.mTitle = P.mContext.getText(titleId);
            return this;
        }

        
        public Builder setTitle(CharSequence title) {
            P.mTitle = title;
            return this;
        }

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

        
        public Builder setMessage(CharSequence message) {
            P.mMessage = message;
            return this;
        }

       
        public Builder setIcon(@DrawableRes int iconId) {
            P.mIconId = iconId;
            return this;
        }

       
        public Builder setIcon(Drawable icon) {
            P.mIcon = icon;
            return this;
        } 

        
        public Builder setOnKeyListener(OnKeyListener onKeyListener) {
            P.mOnKeyListener = onKeyListener;
            return this;
        }

       
        public Builder setItems(@ArrayRes int itemsId, final OnClickListener listener) {
            P.mItems = P.mContext.getResources().getTextArray(itemsId);
            P.mOnClickListener = listener;
            return this;
        }

        
        public Builder setItems(CharSequence[] items, final OnClickListener listener) {
            P.mItems = items;
            P.mOnClickListener = listener;
            return this;
        }

        
        public Builder setAdapter(final ListAdapter adapter, final OnClickListener listener) {
            P.mAdapter = adapter;
            P.mOnClickListener = listener;
            return this;
        }

        
        public Builder setCursor(final Cursor cursor, final OnClickListener listener,
                String labelColumn) {
            P.mCursor = cursor;
            P.mLabelColumn = labelColumn;
            P.mOnClickListener = listener;
            return this;
        }

       
        public Builder setMultiChoiceItems(@ArrayRes int itemsId, boolean[] checkedItems,
                final OnMultiChoiceClickListener listener) {
            P.mItems = P.mContext.getResources().getTextArray(itemsId);
            P.mOnCheckboxClickListener = listener;
            P.mCheckedItems = checkedItems;
            P.mIsMultiChoice = true;
            return this;
        }
       
        public Builder setSingleChoiceItems(@ArrayRes int itemsId, int checkedItem,
                final OnClickListener listener) {
            P.mItems = P.mContext.getResources().getTextArray(itemsId);
            P.mOnClickListener = listener;
            P.mCheckedItem = checkedItem;
            P.mIsSingleChoice = true;
            return this;
        }

        
        public Builder setSingleChoiceItems(Cursor cursor, int checkedItem, String labelColumn,
                final OnClickListener listener) {
            P.mCursor = cursor;
            P.mOnClickListener = listener;
            P.mCheckedItem = checkedItem;
            P.mLabelColumn = labelColumn;
            P.mIsSingleChoice = true;
            return this;
        }
        
        public Builder setView(int layoutResId) {
            P.mView = null;
            P.mViewLayoutResId = layoutResId;
            P.mViewSpacingSpecified = false;
            return this;
        }

        
        public Builder setView(View view) {
            P.mView = view;
            P.mViewLayoutResId = 0;
            P.mViewSpacingSpecified = false;
            return this;
        }

       
        @Deprecated
        public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
                int viewSpacingRight, int viewSpacingBottom) {
            P.mView = view;
            P.mViewLayoutResId = 0;
            P.mViewSpacingSpecified = true;
            P.mViewSpacingLeft = viewSpacingLeft;
            P.mViewSpacingTop = viewSpacingTop;
            P.mViewSpacingRight = viewSpacingRight;
            P.mViewSpacingBottom = viewSpacingBottom;
            return this;
        }

       
        @Deprecated
        public Builder setInverseBackgroundForced(boolean useInverseBackground) {
            P.mForceInverseBackground = useInverseBackground;
            return this;
        }


        public AlertDialog create() {
            // Context has already been wrapped with the appropriate theme.
            final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
            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 is the key class for creating objects in the builder mode. The member variables of the built object are generally repeatedly defined inside. That is: the builder mode is used to build the object. The code is actually a bit repetitive. The member variables in the AlertDialog class (AlertController mAlert), to be defined again in the Builder class (AlertController.AlertParams P contains the mAlert member variable). The mAlert member variable contained in P can be seen from the following code

//在Builer类的create方法中有如下代码
final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);            

P.apply(dialog.mAlert);

The builder mode can use chain calls to set parameters and use builder objects such as:

 AlertDialog builder = new AlertDialog.Builder(this).setTitle("这是Title").setIcon(R.drawable.ic_launcher_background).setMessage("提示信息").create();
 builder.show();


//或者,builder的show()方法会先调用create()方法
AlertDialog builder = new AlertDialog.Builder(this).setTitle("这是Title").setIcon(R.drawable.ic_launcher_background).setMessage("提示信息").show();

Summary: The above three development needs or problems can be solved through the builder model;

Guess you like

Origin blog.csdn.net/ezconn/article/details/106737936