Java的结构之美【1】——构造对象
当我们遇到多个构造器參数的时候可能会想到用构件器,代码例如以下:
/**
* 构建器
* @author 阳光小强
*
*/
public class Lunch {
private String cake;
private String meat;
private String milk;
private String drink; public Lunch(){
this(null);
} public Lunch(String meat){
this(null, meat, null);
} public Lunch(String cake, String meat, String milk){
this(cake, meat, milk, null);
} public Lunch(String cake, String meat, String milk, String drink) {
super();
this.cake = cake;
this.meat = meat;
this.milk = milk;
this.drink = drink;
}
}
重叠的构建器看似能解决我们遇到的各种问题,可是当參数非常多的时候,这样做就会显的太傻了,以下我们使用Builder模式,实现相同的效果:
/**
* 构建器
* @author 阳光小强
*
*/
public class Lunch {
private String cake;
private String meat;
private String milk;
private String drink; public static class Builder{
private String meat; //必需要初始化的參数 private String cake;
private String milk;
private String drink; public Builder(String meat){
this.meat = meat;
} public Builder addCake(String cake){
this.cake = cake;
return this;
} public Builder addMilk(String milk){
this.milk = milk;
return this;
} public Builder addDrink(String drink){
this.drink = drink;
return this;
} public Lunch create(){
return new Lunch(this);
}
} private Lunch(Builder builder){
this.meat = builder.meat;
this.cake = builder.cake;
this.milk = builder.milk;
this.drink = builder.drink;
} @Override
public String toString() {
return "==" + meat + "==" + cake + "==" + "milk" + "==" + "drink";
}
}
写一个Main測试类測试一下:
public class Main {
public static void main(String[] args) {
Lunch.Builder builder = new Lunch.Builder("meat");
Lunch lunch = builder.addCake("cake")
.addDrink("drink")
.addMilk("milk")
.create();
System.out.println(lunch.toString());
}
}
输出结果:
==meat==cake==milk==drink
上面的Builder模式不得不使人想到Android中的AlertDialog,查看它的实现,事实上就是使用了Builder模式,原代码例如以下:
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package android.app; import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView; import com.android.internal.app.AlertController; /**
* A subclass of Dialog that can display one, two or three buttons. If you only want to
* display a String in this dialog box, use the setMessage() method. If you
* want to display a more complex view, look up the FrameLayout called "custom"
* and add your view to it:
*
* <pre>
* FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);
* fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
* </pre>
*
* <p>The AlertDialog class takes care of automatically setting
* {@link WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
* WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM} for you based on whether
* any views in the dialog return true from {@link View#onCheckIsTextEditor()
* View.onCheckIsTextEditor()}. Generally you want this set for a Dialog
* without text editors, so that it will be placed on top of the current
* input method UI. You can modify this behavior by forcing the flag to your
* desired mode after calling {@link #onCreate}.
*/
public class AlertDialog extends Dialog implements DialogInterface {
private AlertController mAlert; protected AlertDialog(Context context) {
this(context, com.android.internal.R.style.Theme_Dialog_Alert);
} protected AlertDialog(Context context, int theme) {
super(context, theme);
mAlert = new AlertController(context, this, getWindow());
} protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, com.android.internal.R.style.Theme_Dialog_Alert);
setCancelable(cancelable);
setOnCancelListener(cancelListener);
mAlert = new AlertController(context, this, getWindow());
} /**
* Gets one of the buttons used in the dialog.
* <p>
* If a button does not exist in the dialog, null will be returned.
*
* @param whichButton The identifier of the button that should be returned.
* For example, this can be
* {@link DialogInterface#BUTTON_POSITIVE}.
* @return The button from the dialog, or null if a button does not exist.
*/
public Button getButton(int whichButton) {
return mAlert.getButton(whichButton);
} /**
* Gets the list view used in the dialog.
*
* @return The {@link ListView} from the dialog.
*/
public ListView getListView() {
return mAlert.getListView();
} @Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
} /**
* @see Builder#setCustomTitle(View)
*/
public void setCustomTitle(View customTitleView) {
mAlert.setCustomTitle(customTitleView);
} public void setMessage(CharSequence message) {
mAlert.setMessage(message);
} /**
* Set the view to display in that dialog.
*/
public void setView(View view) {
mAlert.setView(view);
} /**
* Set the view to display in that dialog, specifying the spacing to appear around that
* view.
*
* @param view The view to show in the content area of the dialog
* @param viewSpacingLeft Extra space to appear to the left of {@code view}
* @param viewSpacingTop Extra space to appear above {@code view}
* @param viewSpacingRight Extra space to appear to the right of {@code view}
* @param viewSpacingBottom Extra space to appear below {@code view}
*/
public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight,
int viewSpacingBottom) {
mAlert.setView(view, viewSpacingLeft, viewSpacingTop, viewSpacingRight, viewSpacingBottom);
} /**
* Set a message to be sent when a button is pressed.
*
* @param whichButton Which button to set the message for, can be one of
* {@link DialogInterface#BUTTON_POSITIVE},
* {@link DialogInterface#BUTTON_NEGATIVE}, or
* {@link DialogInterface#BUTTON_NEUTRAL}
* @param text The text to display in positive button.
* @param msg The {@link Message} to be sent when clicked.
*/
public void setButton(int whichButton, CharSequence text, Message msg) {
mAlert.setButton(whichButton, text, null, msg);
} /**
* Set a listener to be invoked when the positive button of the dialog is pressed.
*
* @param whichButton Which button to set the listener on, can be one of
* {@link DialogInterface#BUTTON_POSITIVE},
* {@link DialogInterface#BUTTON_NEGATIVE}, or
* {@link DialogInterface#BUTTON_NEUTRAL}
* @param text The text to display in positive button.
* @param listener The {@link DialogInterface.OnClickListener} to use.
*/
public void setButton(int whichButton, CharSequence text, OnClickListener listener) {
mAlert.setButton(whichButton, text, listener, null);
} /**
* @deprecated Use {@link #setButton(int, CharSequence, Message)} with
* {@link DialogInterface#BUTTON_POSITIVE}.
*/
@Deprecated
public void setButton(CharSequence text, Message msg) {
setButton(BUTTON_POSITIVE, text, msg);
} /**
* @deprecated Use {@link #setButton(int, CharSequence, Message)} with
* {@link DialogInterface#BUTTON_NEGATIVE}.
*/
@Deprecated
public void setButton2(CharSequence text, Message msg) {
setButton(BUTTON_NEGATIVE, text, msg);
} /**
* @deprecated Use {@link #setButton(int, CharSequence, Message)} with
* {@link DialogInterface#BUTTON_NEUTRAL}.
*/
@Deprecated
public void setButton3(CharSequence text, Message msg) {
setButton(BUTTON_NEUTRAL, text, msg);
} /**
* Set a listener to be invoked when button 1 of the dialog is pressed.
*
* @param text The text to display in button 1.
* @param listener The {@link DialogInterface.OnClickListener} to use.
* @deprecated Use
* {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)}
* with {@link DialogInterface#BUTTON_POSITIVE}
*/
@Deprecated
public void setButton(CharSequence text, final OnClickListener listener) {
setButton(BUTTON_POSITIVE, text, listener);
} /**
* Set a listener to be invoked when button 2 of the dialog is pressed.
* @param text The text to display in button 2.
* @param listener The {@link DialogInterface.OnClickListener} to use.
* @deprecated Use
* {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)}
* with {@link DialogInterface#BUTTON_NEGATIVE}
*/
@Deprecated
public void setButton2(CharSequence text, final OnClickListener listener) {
setButton(BUTTON_NEGATIVE, text, listener);
} /**
* Set a listener to be invoked when button 3 of the dialog is pressed.
* @param text The text to display in button 3.
* @param listener The {@link DialogInterface.OnClickListener} to use.
* @deprecated Use
* {@link #setButton(int, CharSequence, android.content.DialogInterface.OnClickListener)}
* with {@link DialogInterface#BUTTON_POSITIVE}
*/
@Deprecated
public void setButton3(CharSequence text, final OnClickListener listener) {
setButton(BUTTON_NEUTRAL, text, listener);
} /**
* Set resId to 0 if you don't want an icon.
* @param resId the resourceId of the drawable to use as the icon or 0
* if you don't want an icon.
*/
public void setIcon(int resId) {
mAlert.setIcon(resId);
} public void setIcon(Drawable icon) {
mAlert.setIcon(icon);
} 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; /**
* Constructor using a context for this builder and the {@link AlertDialog} it creates.
*/
public Builder(Context context) {
P = new AlertController.AlertParams(context);
} /**
* Set the title using the given resource id.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setTitle(int titleId) {
P.mTitle = P.mContext.getText(titleId);
return this;
} /**
* Set the title displayed in the {@link Dialog}.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
} /**
* Set the title using the custom view {@code customTitleView}. The
* methods {@link #setTitle(int)} and {@link #setIcon(int)} should be
* sufficient for most titles, but this is provided if the title needs
* more customization. Using this will replace the title and icon set
* via the other methods.
*
* @param customTitleView The custom view to use as the title.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setCustomTitle(View customTitleView) {
P.mCustomTitleView = customTitleView;
return this;
} /**
* Set the message to display using the given resource id.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setMessage(int messageId) {
P.mMessage = P.mContext.getText(messageId);
return this;
} /**
* Set the message to display.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
} /**
* Set the resource id of the {@link Drawable} to be used in the title.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setIcon(int iconId) {
P.mIconId = iconId;
return this;
} /**
* Set the {@link Drawable} to be used in the title.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setIcon(Drawable icon) {
P.mIcon = icon;
return this;
} /**
* Set a listener to be invoked when the positive button of the dialog is pressed.
* @param textId The resource id of the text to display in the positive button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setPositiveButton(int textId, final OnClickListener listener) {
P.mPositiveButtonText = P.mContext.getText(textId);
P.mPositiveButtonListener = listener;
return this;
} /**
* Set a listener to be invoked when the positive button of the dialog is pressed.
* @param text The text to display in the positive button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
P.mPositiveButtonText = text;
P.mPositiveButtonListener = listener;
return this;
} /**
* Set a listener to be invoked when the negative button of the dialog is pressed.
* @param textId The resource id of the text to display in the negative button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setNegativeButton(int textId, final OnClickListener listener) {
P.mNegativeButtonText = P.mContext.getText(textId);
P.mNegativeButtonListener = listener;
return this;
} /**
* Set a listener to be invoked when the negative button of the dialog is pressed.
* @param text The text to display in the negative button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setNegativeButton(CharSequence text, final OnClickListener listener) {
P.mNegativeButtonText = text;
P.mNegativeButtonListener = listener;
return this;
} /**
* Set a listener to be invoked when the neutral button of the dialog is pressed.
* @param textId The resource id of the text to display in the neutral button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setNeutralButton(int textId, final OnClickListener listener) {
P.mNeutralButtonText = P.mContext.getText(textId);
P.mNeutralButtonListener = listener;
return this;
} /**
* Set a listener to be invoked when the neutral button of the dialog is pressed.
* @param text The text to display in the neutral button
* @param listener The {@link DialogInterface.OnClickListener} to use.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setNeutralButton(CharSequence text, final OnClickListener listener) {
P.mNeutralButtonText = text;
P.mNeutralButtonListener = listener;
return this;
} /**
* Sets whether the dialog is cancelable or not. Default is true.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setCancelable(boolean cancelable) {
P.mCancelable = cancelable;
return this;
} /**
* Sets the callback that will be called if the dialog is canceled.
* @see #setCancelable(boolean)
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setOnCancelListener(OnCancelListener onCancelListener) {
P.mOnCancelListener = onCancelListener;
return this;
} /**
* Sets the callback that will be called if a key is dispatched to the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setOnKeyListener(OnKeyListener onKeyListener) {
P.mOnKeyListener = onKeyListener;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of the
* selected item via the supplied listener. This should be an array type i.e. R.array.foo
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setItems(int itemsId, final OnClickListener listener) {
P.mItems = P.mContext.getResources().getTextArray(itemsId);
P.mOnClickListener = listener;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of the
* selected item via the supplied listener.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setItems(CharSequence[] items, final OnClickListener listener) {
P.mItems = items;
P.mOnClickListener = listener;
return this;
} /**
* Set a list of items, which are supplied by the given {@link ListAdapter}, to be
* displayed in the dialog as the content, you will be notified of the
* selected item via the supplied listener.
*
* @param adapter The {@link ListAdapter} to supply the list of items
* @param listener The listener that will be called when an item is clicked.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setAdapter(final ListAdapter adapter, final OnClickListener listener) {
P.mAdapter = adapter;
P.mOnClickListener = listener;
return this;
} /**
* Set a list of items, which are supplied by the given {@link Cursor}, to be
* displayed in the dialog as the content, you will be notified of the
* selected item via the supplied listener.
*
* @param cursor The {@link Cursor} to supply the list of items
* @param listener The listener that will be called when an item is clicked.
* @param labelColumn The column name on the cursor containing the string to display
* in the label.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setCursor(final Cursor cursor, final OnClickListener listener,
String labelColumn) {
P.mCursor = cursor;
P.mLabelColumn = labelColumn;
P.mOnClickListener = listener;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content,
* you will be notified of the selected item via the supplied listener.
* This should be an array type, e.g. R.array.foo. The list will have
* a check mark displayed to the right of the text for each checked
* item. Clicking on an item in the list will not dismiss the dialog.
* Clicking on a button will dismiss the dialog.
*
* @param itemsId the resource id of an array i.e. R.array.foo
* @param checkedItems specifies which items are checked. It should be null in which case no
* items are checked. If non null it must be exactly the same length as the array of
* items.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setMultiChoiceItems(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;
} /**
* Set a list of items to be displayed in the dialog as the content,
* you will be notified of the selected item via the supplied listener.
* The list will have a check mark displayed to the right of the text
* for each checked item. Clicking on an item in the list will not
* dismiss the dialog. Clicking on a button will dismiss the dialog.
*
* @param items the text of the items to be displayed in the list.
* @param checkedItems specifies which items are checked. It should be null in which case no
* items are checked. If non null it must be exactly the same length as the array of
* items.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
final OnMultiChoiceClickListener listener) {
P.mItems = items;
P.mOnCheckboxClickListener = listener;
P.mCheckedItems = checkedItems;
P.mIsMultiChoice = true;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content,
* you will be notified of the selected item via the supplied listener.
* The list will have a check mark displayed to the right of the text
* for each checked item. Clicking on an item in the list will not
* dismiss the dialog. Clicking on a button will dismiss the dialog.
*
* @param cursor the cursor used to provide the items.
* @param isCheckedColumn specifies the column name on the cursor to use to determine
* whether a checkbox is checked or not. It must return an integer value where 1
* means checked and 0 means unchecked.
* @param labelColumn The column name on the cursor containing the string to display in the
* label.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setMultiChoiceItems(Cursor cursor, String isCheckedColumn, String labelColumn,
final OnMultiChoiceClickListener listener) {
P.mCursor = cursor;
P.mOnCheckboxClickListener = listener;
P.mIsCheckedColumn = isCheckedColumn;
P.mLabelColumn = labelColumn;
P.mIsMultiChoice = true;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of
* the selected item via the supplied listener. This should be an array type i.e.
* R.array.foo The list will have a check mark displayed to the right of the text for the
* checked item. Clicking on an item in the list will not dismiss the dialog. Clicking on a
* button will dismiss the dialog.
*
* @param itemsId the resource id of an array i.e. R.array.foo
* @param checkedItem specifies which item is checked. If -1 no items are checked.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setSingleChoiceItems(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;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of
* the selected item via the supplied listener. The list will have a check mark displayed to
* the right of the text for the checked item. Clicking on an item in the list will not
* dismiss the dialog. Clicking on a button will dismiss the dialog.
*
* @param cursor the cursor to retrieve the items from.
* @param checkedItem specifies which item is checked. If -1 no items are checked.
* @param labelColumn The column name on the cursor containing the string to display in the
* label.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
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;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of
* the selected item via the supplied listener. The list will have a check mark displayed to
* the right of the text for the checked item. Clicking on an item in the list will not
* dismiss the dialog. Clicking on a button will dismiss the dialog.
*
* @param items the items to be displayed.
* @param checkedItem specifies which item is checked. If -1 no items are checked.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setSingleChoiceItems(CharSequence[] items, int checkedItem, final OnClickListener listener) {
P.mItems = items;
P.mOnClickListener = listener;
P.mCheckedItem = checkedItem;
P.mIsSingleChoice = true;
return this;
} /**
* Set a list of items to be displayed in the dialog as the content, you will be notified of
* the selected item via the supplied listener. The list will have a check mark displayed to
* the right of the text for the checked item. Clicking on an item in the list will not
* dismiss the dialog. Clicking on a button will dismiss the dialog.
*
* @param adapter The {@link ListAdapter} to supply the list of items
* @param checkedItem specifies which item is checked. If -1 no items are checked.
* @param listener notified when an item on the list is clicked. The dialog will not be
* dismissed when an item is clicked. It will only be dismissed if clicked on a
* button, if no buttons are supplied it's up to the user to dismiss the dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setSingleChoiceItems(ListAdapter adapter, int checkedItem, final OnClickListener listener) {
P.mAdapter = adapter;
P.mOnClickListener = listener;
P.mCheckedItem = checkedItem;
P.mIsSingleChoice = true;
return this;
} /**
* Sets a listener to be invoked when an item in the list is selected.
*
* @param listener The listener to be invoked.
* @see AdapterView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setOnItemSelectedListener(final AdapterView.OnItemSelectedListener listener) {
P.mOnItemSelectedListener = listener;
return this;
} /**
* Set a custom view to be the contents of the Dialog. If the supplied view is an instance
* of a {@link ListView} the light background will be used.
*
* @param view The view to use as the contents of the Dialog.
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setView(View view) {
P.mView = view;
P.mViewSpacingSpecified = false;
return this;
} /**
* Set a custom view to be the contents of the Dialog, specifying the
* spacing to appear around that view. If the supplied view is an
* instance of a {@link ListView} the light background will be used.
*
* @param view The view to use as the contents of the Dialog.
* @param viewSpacingLeft Spacing between the left edge of the view and
* the dialog frame
* @param viewSpacingTop Spacing between the top edge of the view and
* the dialog frame
* @param viewSpacingRight Spacing between the right edge of the view
* and the dialog frame
* @param viewSpacingBottom Spacing between the bottom edge of the view
* and the dialog frame
* @return This Builder object to allow for chaining of calls to set
* methods
*
*
* This is currently hidden because it seems like people should just
* be able to put padding around the view.
* @hide
*/
public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
int viewSpacingRight, int viewSpacingBottom) {
P.mView = view;
P.mViewSpacingSpecified = true;
P.mViewSpacingLeft = viewSpacingLeft;
P.mViewSpacingTop = viewSpacingTop;
P.mViewSpacingRight = viewSpacingRight;
P.mViewSpacingBottom = viewSpacingBottom;
return this;
} /**
* Sets the Dialog to use the inverse background, regardless of what the
* contents is.
*
* @param useInverseBackground Whether to use the inverse background
*
* @return This Builder object to allow for chaining of calls to set methods
*/
public Builder setInverseBackgroundForced(boolean useInverseBackground) {
P.mForceInverseBackground = useInverseBackground;
return this;
} /**
* @hide
*/
public Builder setRecycleOnMeasureEnabled(boolean enabled) {
P.mRecycleOnMeasure = enabled;
return this;
} /**
* Creates a {@link AlertDialog} with the arguments supplied to this builder. It does not
* {@link Dialog#show()} the dialog. This allows the user to do any extra processing
* before displaying the dialog. Use {@link #show()} if you don't have any other processing
* to do and want this to be created and displayed.
*/
public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
dialog.setOnCancelListener(P.mOnCancelListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
} /**
* Creates a {@link AlertDialog} with the arguments supplied to this builder and
* {@link Dialog#show()}'s the dialog.
*/
public AlertDialog show() {
AlertDialog dialog = create();
dialog.show();
return dialog;
}
} }
由此可见Builder模式的强大,假设一个类的构造器或者静态工场中有多个參数,使用Builder模式是非常合适的。Builder模式不仅easy理解并且是代码更加简洁和易于编写。
值得注意的是上面的Builder模式中用到了内部类,并且是一个静态内部类,为什么使用内部类(这个非常显然,是为了操作成员变量),那么为什么要是静态的呢?假设不设为静态内部类则必须现有外部类的实例才干创建内部类的实例(这样就矛盾了),假设内部类使用静态,则直接能够创建该内部类的实例。
有时候我们可能不过需要一个实例,而不需反复的去构造对象,则能够使用单利模式,经常使用的单例模式有饿汉式和懒汉式(对于学过Java的朋友已经非常熟悉了,这里就不举例了),以下介绍一种JDK1.5以后能够用的方法,并且是比較推荐的实现方式:
public enum Elvis {
INSTANCE; private Elvis(){
//枚举构造是私有的
System.out.println("构造方法");
}
public void todoSomeThing(){
System.out.println("todoSomeThing");
}
}
我们先来看看枚举的API文档
能够看到枚举直接实现了序列化接口,假设我们使用上面的单例模式,在声明中加上“implements Serializable"是不够的,为了保证唯独一个实例,必须声明全部实例域都是瞬时的(transient),并提供一个readResolve方法。否则每次反序列化一个序列化实例,都会创建一个新的实例,假设我们用枚举实现则不必考虑这些。
public class Main {
public static void main(String[] args) {
Elvis.INSTANCE.todoSomeThing();
}
}
感谢你对“阳光小强"的关注,我的还有一篇博文非常荣幸參加了CSDN举办的博文大赛,假设你觉的小强的博文对你有帮助,请为小强投上你宝贵的一票,投票地址:http://vote.blog.csdn.net/Article/Details?articleid=30101091
Java的结构之美【1】——构造对象的更多相关文章
- Java的结构之美【2】——销毁对象
先来看一段代码: import java.util.Arrays; import java.util.EmptyStackException; /** * 2014年6月28日09:31:59 * @ ...
- Java内存结构、类的初始化、及对象构造过程
概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的 ...
- 【Java 基础项目 - - Bank项目4】 对象构造/跨package调用
UML设计: 文件组织: (注: 在bank4中,直接调用bank3的内容, 不再重复编写代码即可!) 代码编写Bank.java: package Banking_4; import Banking ...
- jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解
一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机: 1 ...
- Java虚拟机 - 结构原理与运行时数据区域
http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关 ...
- Java 语言结构【转】
Java 语言结构 基础:包(Package).类(Class)和对象(Object) 了解 Java 的包(Package).类(Class)和对象(Object)这些基础术语是非常重要的,这部分内 ...
- Java 内存结构备忘录
本文详细描述了 Java 堆内存模型,垃圾回收算法以及处理内存泄露的最佳方案,并辅之以图表,希望能对理解 Java 内存结构有所帮助.原文作者 Sumith Puri,本文系 OneAPM 工程师编译 ...
- 读书笔记-----Java并发编程实战(二)对象的共享
public class NoVisibility{ private static boolean ready; private static int number; private static c ...
- 使用递归算法结合数据库解析成java树形结构
使用递归算法结合数据库解析成java树形结构 1.准备表结构及对应的表数据a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCHA ...
随机推荐
- BZOJ 1150 CTSC2007 数据备份Backup 堆+馋
标题效果:给定一个长度n−1n-1的序列,要求选出kk个不相邻的数使得和最小 费用流显然能跑.并且显然过不去- - 考虑用堆模拟费用流 一个错误的贪心是每次取最小.这样显然过不去例子 我们把[每次取最 ...
- PHP读取Excel里的文件
下载phpExcelReader http://sourceforge.net/projects/phpexcelreader 解压后得到以下这些文件 jxlrwtest.xls这个excel文件有 ...
- Xamarin.Android 入门实例(2)之实现WCF 寄宿于IIS 的Web服务提供
1.WCF 契约 ICalculator.cs using System.ServiceModel; namespace Contracts { [ServiceContract] public in ...
- basename, dirname 在C语言中的使用
basename作用是得到特定的路径中的最后一个'/',后面的内容 如/usr/bin,得到的内容就是bin 如果/sdcard/miui_recovery/backup 得到的内容就是backup ...
- Android 学习历程摘要(二)
1.资源文件命名仅仅能小写,否则会报错生成不了R.java文件 2.R文件导包时应该导入自己project的包,而不是android.R 3.数据库操作使用SqliteOpenHelper 4.val ...
- Linux curl使用简单介绍 (转)
Curl是Linux下一个很强大的http命令行工具,其功能十分强大. 1) 二话不说,先从这里开始吧! $ curl http://www.linuxidc.com 回车之后,www.linuxid ...
- 国内外MD5在线解密网站
-http://www.cmd5.com/english.aspx (457,354,352,282) - http://www.md5crack.com - http://www.hashcheck ...
- cocos2dx 3.0 学习笔记 引用cocostudio库 的环境配置
cocostudio创建UI并应用时须要引用cocostudio库,须要额外的环境配置: 之前已经搭配好了基础的开发环境,包含 1) JDK 2) Python 2.7 3) ant 4) visua ...
- HDU 5052 LCT
Yaoge's maximum profit Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性
原文:ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性 深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开 ...