android View.OnClickListener条件调度程序重构为Command模式

今天试着将公司的一大堆的android View.OnClickListener条件调度程序重构为Command模式,经测试,程序没有出错,代码的可读性高了,而且消除了不少重复代码,先将原始代码和重构后的代码贴至如下:

1.原先代码:

private void pull_to_refresh() {
	NavigationTextView textView;
	for (int i = 0; i < inforTitles.size(); i++) {
	    textView = inforTitles.get(i);
	    if (textView.isSelected()) {
		setViewBg(textView);
		/*
		 * if(footerViewIsVisible){ footLayout.setVisibility(View.GONE);
		 * footerViewIsVisible=false; }
		 */
		inforAdapter.updateInforList(textView.getTitleUrl(), i, true);
		listView.setSelection(0);
		break;
	    }
	}
    }

    private View.OnClickListener listener = new View.OnClickListener() {
	public void onClick(View v) {
	    int viewId = v.getId();
	    if (viewId == R.id.information_menu_child_refresh) {
		NavigationTextView textView;
		for (int i = 0; i < inforTitles.size(); i++) {
		    textView = inforTitles.get(i);
		    if (textView.isSelected()) {
			setViewBg(textView);
			if (footerViewIsVisible) {
			    footLayout.setVisibility(View.GONE);
			    footerViewIsVisible = false;
			}
			listView.showProgressBar();
			inforAdapter.updateInforList(textView.getTitleUrl(), i,
				true);
			listView.setSelection(0);
			break;
		    }
		}
	    } else if (viewId == R.id.information_menu_child_offine_download) {
		down();
	    } else if (viewId == R.id.information_menu_child_custom_channel) {
		Intent cusIntent = new Intent();
		cusIntent.setClass(InformationBrowserActivity.this,
			CustomChannelActivity.class);
		Bundle b = new Bundle();
		int backFlag;
		if (moreNaviListLayout.getVisibility() == View.VISIBLE) {
		    backFlag = Config.NAVI_MORE;
		} else {
		    backFlag = Config.NAVI_FIRST;
		}
		b.putInt("backFlag", backFlag);
		cusIntent.putExtras(b);
		startActivity(cusIntent);
		layout.removeAllViews();
	    } else if (viewId == R.id.information_menu_child_favorite) {
		Intent favoriteIntent = new Intent(
			InformationBrowserActivity.this,
			MoreFavoriteActivity.class);
		startActivity(favoriteIntent);
	    } else if (viewId == R.id.information_menu_child_setting) {
		Intent settingIntent = new Intent(
			InformationBrowserActivity.this, PconlineSetting.class);
		startActivity(settingIntent);
	    }/*
	      * else if (viewId == R.id.information_menu_child_select_city) {
	      * changeCity(); }
	      */else if (viewId == R.id.information_menu_child_search) {
		Intent searchIntent = new Intent(
			InformationBrowserActivity.this,
			InformationCategorySearchResultActivity.class);
		startActivity(searchIntent);
	    } /*
	       * else if (viewId == R.id.information_menu_child_exit) {
	       * onBackPressed(); }
	       */else if (viewId == R.id.information_menu_top_layout) {
		mPopupWindow.dismiss();
	    }
	    mPopupWindow.dismiss();
	}
    };
重构后的代码:

    private void pull_to_refresh() {
	boolean isHanlderForFooterViewInVisible = false;
	refresh(isHanlderForFooterViewInVisible);
    }

    private void setInInVisibleForFooterViews(boolean isVisible) {
	if (isVisible) {
	    if (footerViewIsVisible) {
		footLayout.setVisibility(View.GONE);
		footerViewIsVisible = false;
	    }
	    listView.showProgressBar();
	}
    }

    private void refresh(boolean isHanlderForFooterViewInVisible) {
	NavigationTextView textView;
	for (int i = 0; i < inforTitles.size(); i++) {
	    textView = inforTitles.get(i);
	    if (textView.isSelected()) {
		setViewBg(textView);
		setInInVisibleForFooterViews(isHanlderForFooterViewInVisible);
		inforAdapter.updateInforList(textView.getTitleUrl(), i, true);
		listView.setSelection(0);
		break;
	    }
	}
    }

    private Map<Integer, MenuChildListenerResponse> maps = new HashMap<Integer, MenuChildListenerResponse>();

    private void compositeCommandForMenuChildListener() {
	maps.put(R.id.information_menu_child_refresh, new MenuChildRefresh());
	maps.put(R.id.information_menu_child_offine_download,
		new MenuChildOfflineDownload());
	maps.put(R.id.information_menu_child_custom_channel,
		new MenuChildCustomChannel());
	maps.put(R.id.information_menu_child_favorite, new MenuChildFavorite());
	maps.put(R.id.information_menu_child_setting, new MenuChildSetting());
	maps.put(R.id.information_menu_child_search, new MenuChildSearch());
	maps.put(R.id.information_menu_top_layout, new MenuTopLayout());

    }

    private abstract class MenuChildListenerResponse {
	abstract void execute();

	void composeIntent(Class<?> c, Bundle b) {
	    Intent newIntent = new Intent(InformationBrowserActivity.this, c);
	    if (b != null)
		newIntent.putExtras(b);
	    startActivity(newIntent);
	}

    }

    private class MenuChildRefresh extends MenuChildListenerResponse {
	public void execute() {
	    boolean isHanlderForFooterViewInVisible = true;
	    refresh(isHanlderForFooterViewInVisible);
	}
    }

    private class MenuChildOfflineDownload extends MenuChildListenerResponse {

	@Override
	void execute() {
	    down();
	}
    }

    private class MenuChildCustomChannel extends MenuChildListenerResponse {
	void execute() {
	    Bundle b = new Bundle();
	    int backFlag;
	    if (moreNaviListLayout.getVisibility() == View.VISIBLE) {
		backFlag = Config.NAVI_MORE;
	    } else {
		backFlag = Config.NAVI_FIRST;
	    }
	    b.putInt("backFlag", backFlag);
	    composeIntent(CustomChannelActivity.class, b);
	    layout.removeAllViews();
	}

    }

    private class MenuChildFavorite extends MenuChildListenerResponse {
	void execute() {
	    composeIntent(MoreFavoriteActivity.class, null);
	}
    }

    private class MenuChildSetting extends MenuChildListenerResponse {
	void execute() {
	    composeIntent(PconlineSetting.class, null);
	}
    }

    private class MenuChildSearch extends MenuChildListenerResponse {
	void execute() {
	    composeIntent(InformationCategorySearchResultActivity.class, null);
	}
    }

    private class MenuTopLayout extends MenuChildListenerResponse {
	void execute() {
	    mPopupWindow.dismiss();
	}
    }

    private View.OnClickListener listener = new View.OnClickListener() {
	public void onClick(View v) {
	    int viewId = v.getId();
	    maps.get(viewId).execute();
	    new MenuTopLayout().execute();
	}
    };


 
 
最大的子程序行数也没超过10行,可读性是不是好了很多呢?而且当再次添加菜单的View和View的OnClickListener事件时,只要继承与MenuChildListenerResponse并覆盖execute方法,然后在Map对象注册该View的id和具体的命令对象即可,不会影响到其他View的处理逻辑,符合了二进制兼容性原则。若发现有重复代码,可用Pull Up重构,将重复代码移到超类。   当然将条件调度程序或者Switch-case程序重构为Command模式的前提是这些程序条件判断比较复杂,比如一屏不能显示完所有的if-else,switch-case,否则,这样重构后只会增加了代码的复杂性。

继续加油,将设计模式用在重构上!

你可能感兴趣的:(android,command,null,Class,download,menu)