Android设计模式(十)--建造者模式

回头看自己写的东西,在关于Android自定义控件时,写的代码适用性比较高,但是看上去没有什么技术含量,所以在学习设计模式的时候,想想有些东西是否能够改进,比如说:

自定义Dialog是Android应用必须的,系统的控件实在是太难看了;

在构建中,完全是,new完对象之后,需要什么构建什么,这样写没有问题,可读性也还行,就是看上去不咋的。


以下是小部分代码片段:

package com.example.demo.Builder;

/**
 * 
 * @author qubian
 * @data 2015年6月10日
 * @email naibbian@163.com
 *
 */
public class BuilderDialog extends Dialog implements View.OnClickListener {
	private Context mContext;
	private View view;
	private View lineView;
	private TextView titleTv;
	private TextView contentTv;
	private Button sureBtn;
	private Button cancelBtn;
	private String sureTitle;
	private String cancelTitle;
	private String title;
	private String content;
	private boolean sureVisible = true;
	private boolean cancelVisible = true;
	private View.OnClickListener sureListener;
	private View.OnClickListener cancelListener;

	public BuilderDialog(Context context, String title, String content) {
		super(context, R.style.base_dialog_style);
		this.mContext = context;
		this.title = title;
		this.content = content;
		view = LayoutInflater.from(mContext).inflate(R.layout.dialog_normal,
				null);
		addContentView(view, Utils.getDialogLayoutParams(mContext));
	}

	public void setSureTitle(String title) {
		sureTitle = title;
	}

	public void setCancelTitle(String title) {
		cancelTitle = title;
	}

	public void setCancelVisible(boolean visible) {
		cancelVisible = visible;
	}

	public void setSureListener(View.OnClickListener listener) {
		if (listener != null) {
			sureListener = listener;
		}
	}

	public void setCancelListener(View.OnClickListener listener) {
		
	}

	/**
	 * 是否可以返回
	 * 
	 * @param canBack
	 */
	public void setCanBack(boolean canBack) {

	}
       //初始化
	private void initView() {
		lineView = view.findViewById(R.id.line_view);
		titleTv = (TextView) view.findViewById(R.id.title_tv);
		contentTv = (TextView) view.findViewById(R.id.content_tv);
		contentTv.setText((content.replace("\\r","\r").replace("\\n", "\n")));
		sureBtn = (Button) view.findViewById(R.id.sure_btn);
		cancelBtn = (Button) view.findViewById(R.id.cancel_btn);
	}

	@Override
	public void show() {
		initView();
		titleTv.setText(title);
		if (sureVisible) {
			if (sureListener == null) {
				sureBtn.setOnClickListener(this);
			} else {
				sureBtn.setOnClickListener(sureListener);
			}
			if (sureTitle != null) {
				sureBtn.setText(sureTitle);
			}
		} else {
			sureBtn.setVisibility(View.GONE);
		}
		if (cancelVisible) {
			
		} else {
			
		}
		super.show();
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == sureBtn.getId()) {
			this.cancel();
		} else if (v.getId() == cancelBtn.getId()) {
			this.cancel();
		}
	}

}

使用,和适用都没问题,并且逻辑也比较简单,那么如何优化呢?


言归正传:

建造者模式


1、定义:

将一个复杂的构建与其表示分离,使得相同的构建有了不同的表示。

2、目的:

建造者模式是讲复杂的内部构建封装在内部,对于其他外部成员来说,只需要传递构建者和构建工具,便可以得到所需,不需要关心如何构建,以及内部构建过程。

3、使用:

   3.1、在构建的过程中,允许不同的构建过程,产生不同表示的构建对象;

   3.2、在复杂的对象时,其复杂的构建算法应当独立于对象的组成部分,或者是独立于装配方式时;

4、一个简单的demo:

核心:抽象建造者,具体建造者,实体类

package com.example.demo.Builder;

import android.util.Log;
/**
 * 建造者模式
 * @author qubian
 * @data 2015年6月10日
 * @email naibbian@163.com
 *
 */
public class Product {
	
	Builder mBuilder ;
	public Builder getBuilder()
	{
		if (mBuilder==null) {
			mBuilder = new ProductBuilder();
		}
		return mBuilder;
	}
	
	/**
	 * 抽象建造者
	 * @author qubian
	 * @data 2015年6月10日
	 * @email naibbian@163.com
	 *
	 */
	public interface Builder
	{
		public Builder buildPart1();
		
		public Builder buildPart2();
		
		public Product getProduct();
	}
	/**
	 * 具体的建造者
	 * @author qubian
	 * @data 2015年6月10日
	 * @email naibbian@163.com
	 *
	 */
	public class ProductBuilder implements Builder
	{
		private static final String TAG= "ProductBuilder";
		Product mProduct = new Product();
		@Override
		public Builder buildPart1() {
			Log.i(TAG, "buildPart1");
			return this;
			
		}

		@Override
		public Builder buildPart2() {
			Log.i(TAG, "buildPart2");
			return this;
			
		}

		@Override
		public Product getProduct() {

			return mProduct;
		}
		
	}

}

使用:

package com.example.demo.Builder;

/**
 *  使用
 * @author qubian
 * @data 2015年6月10日
 * @email naibbian@163.com
 *
 */
public class UseProduct {

	public void use()
	{
		Product p = new Product().getBuilder().buildPart1().buildPart2().getProduct();
	}
	
}

5、在Android的源码中,建造者模式,肯定是必不可少的;

其中最为代表的就是AlertDialog,在其构建过程中,便是构建与表示分离。其内部的Builder便是他的构建者。


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

    
    @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;
        private int mTheme;
        
        /**
         * Constructor using a context for this builder and the {@link AlertDialog} it creates.
         */
        public Builder(Context context) {
            this(context, resolveDialogTheme(context, 0));
        }

        /**
         * 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 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 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 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;
        }

        /**
         * 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, mTheme, 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;
        }

        /**
         * 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;
        }
    }
    
}

或许是为了其开放性,AlterView也有自己的构建过程,这样使用AlterView的构建者Builder可以构建视图,他自己的对象也可以对其本身进行操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值