
举个小栗子
AA类
public class AA {
private String x;
AA(String str){ x = str; }
public void print(){ System.out.println(x); }
}
BB类
public class BB {
private int x;
BB(int k){ x = k; }
public void print(){ System.out.println(x); }
}
可以看出 AA和BB有相同的代码 print() 函数,只是传入的参数不一样,该怎样优化?
可以使用模板设计模式
分析:使用模板只要考虑两点,哪些是不变的,不变的部分抽离出来,哪些是变化的,变化的部分抽象出来。
看下改造后的使用:
基类的抽取:SuperAB
public abstract class SuperAB {
public void template_print(){
System.out.println(hook_getData());
}
protected abstract String hook_getData();
}
实现类AA
public class AA extends SuperAB{
private String x;
AA(String str){ x = str; }
@Override protected String hook_getData() {
return x;
}}
这就够了吗? 不不不,还可以进一步的升级。
public abstract class SuperAB implements IAB{
@Override
public void template_print() {
System.out.println(hook_getData());
}
protected abstract String hook_getData();
}
把模板方法template_print放入接口中
public interface IAB {
public void template_print();
}
这样做,架构模型从最简单的编码,进化成越来越规范,并支持拓展。
实际项目开发哪些场景可以使用模板设计模式
比如开发个BaseActivity
public abstract class BaseMvpActivity<V, T extends BasePresenter<V>> extends AppCompatActivity{
public BaseMvpActivity mContext;
private Toolbar mToolBarView;
private LinearLayout mView;
private TextView mGoBack;
private TextView mTitle;
private FrameLayout mBaseView;
private FrameLayout mBaseViews;
protected T mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewTools.setActivityBackGroudCoulor(this, Color.parseColor("#ffffff"));
super.setContentView(R.layout.activity_base);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mContext = this;
mView = (LinearLayout) findViewById(R.id.root_view);
mToolBarView = (Toolbar) findViewById(R.id.tb_app_bar);
mGoBack = (TextView) findViewById(R.id.tv_toolbar_back);
mTitle = (TextView) findViewById(R.id.tv_toolbar_title);
mBaseView = (FrameLayout) findViewById(R.id.base_framelayout);
int viewLayoutId = getViewLayout();
mPresenter = createPresenter();
if (mPresenter != null) {
mPresenter.attachView((V) this);//因为之后所有的子类都要实现对应的View接口
}
if (viewLayoutId != 0) {
View.inflate(mContext, viewLayoutId, mBaseView);
}
setToolBarDetail();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter != null) {
mPresenter.detachView();
}
}
private void setToolBarDetail() {
if (isShowToolbar()) {
mToolBarView.setVisibility(View.VISIBLE);
mGoBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mTitle.setText(getToolBarTitle());
} else {
mToolBarView.setVisibility(View.GONE);
}
}
protected abstract CharSequence getToolBarTitle();
protected abstract boolean isShowToolbar();
//用于创建Presenter和判断是否使用MVP模式(由子类实现)
protected abstract T createPresenter();
//获取布局id
protected abstract int getViewLayout();
}
在OnCreate 函数中每个界面都动态创建个ToolBar,通过抽象isShowToolbar来动态控制是否显示。
getToolBarTitle()用来在ToolBar上展示文字,这样做的好处是。
ViewTools.setActivityBackGroudCoulor(this, Color.parseColor("#ffffff"));
super.setContentView(R.layout.activity_base);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mContext = this;
mView = (LinearLayout) findViewById(R.id.root_view);
mToolBarView = (Toolbar) findViewById(R.id.tb_app_bar);
mGoBack = (TextView) findViewById(R.id.tv_toolbar_back);
mTitle = (TextView) findViewById(R.id.tv_toolbar_title);
mBaseView = (FrameLayout) findViewById(R.id.base_framelayout);
这些代码不用重复写,子类实现也很简单。
public class LoginActivity extends BaseMvpActivity<ILoginActivity,LoginPresenter> implements ILoginActivity{
@Override
protected int getViewLayout() {
return R.layout.activity_login_activity;
}
@Override
protected LoginPresenter createPresenter() {
return new LoginPresenter(mContext);
}
@Override
protected CharSequence getToolBarTitle() {
return "登陆or注册";
}
@Override
protected boolean isShowToolbar() {
return true;
}
学习设计好处有哪些?
1、面试:大家基本都是说单例,很少说模板,通常是用了这种写法但不知道理论,所以学习下理论知识还是有必要。
2、封装: 有了理论才会如鱼得水的去实践。
网友评论