设计模式

设计模式实践-模板模式

2020-10-20  本文已影响0人  h2coder

什么是模板模式?什么时候用?

模板模式,其实在我们日常开发中,算是除了单例模式之外,经常会使用的一种设计模式。例如我们安卓开发中,界面类一般为Activity或Fragment。它们提供了一些系列回调函数,就像流程一样。
其实这就是模板模式的一种体现,Activity或Fragment怎么new出来的,怎么被栈管理的,怎么添加到手机界面上的,各种复杂的事情,这些我们一般统统都不用管,我们只要在特定的回调做事情就好了。

而一般我们都会在Activity或Fragment上做自己的一套封装,添加一些抽象方法,界面类继承复写方法即可,这些大家肯定非常熟悉了。其实它有个名字,就叫模板模式。

怎么实现模板模式?

  1. 基类,一般为抽象类,定义不变的基本流程,不能决定的事情,就提供抽象方法给子类,抽象方法可以在基类声明也可以在接口中声明(如果其他种类的流程也是一致时,一般会抽取到接口)。

  2. 子类,继承基类,实现抽象方法,实现特定逻辑。

模板模式实践,打造你的基类

就以我们最熟悉的Activity和Fragment为例。一般我们会在Activity的onCreate()回调中,一般有这几个步骤:

  1. 设置布局

  2. 查找控件

  3. 绑定控件

  4. 请求数据

而如果我们的界面非常复杂,这些操作都全写在onCreate()方法中,就会非常多,所以一般我们都会抽取函数,那么我们每次都需要写这些重复代码么?不!这时就需要用到模板模式。

实现步骤

  1. 声明接口,由于我们在Activity和Fragment中做事情的流程是一样的,也会经历上面4个流程,所以我们抽取一个接口,让基类去实现。
public interface LayoutCallback {
    /**
     * 设置布局之前回调,一般在该回调中获取前面跳转传递的数据
     */
    void onLayoutBefore();

    /**
     * 获取布局LayoutId,会设置到布局中
     */
    int onInflaterViewId();

    /**
     * 查找View和给View进行相关设置等
     */
    void onBindView(View view);

    /**
     * 设置数据,请求接口等
     */
    void setData();
}
  1. 声明和创建基类,我们一般继承Activity或它的子类
public abstract class BaseActivity extends AppCompatActivity implements LayoutCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在设置布局前调用
        onLayoutBefore();
        //获取子类布局,设置到布局中
        int id = onInflaterViewId();
        if (id != -1) {
            setContentView(id);
        }
        //设置完毕,回调子类进行查找控件
        onBindView(findViewById(android.R.id.content));
        //回调子类,让其请求数据
        setData();
    }
}

//...
public abstract class BaseFragment extends Fragment implements LayoutCallback {
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //回调子类获取前面传递的参数
        onLayoutBefore();
    }
    
    @Nullable
    @Override
    public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //回调子类,设置布局
        return inflater.inflate(onInflaterViewId(), container, false);
    }
    
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //View创建后,回调子类查找、绑定控件
        onBindView(getView());
        //设置数据
        setData();
    }
}
  1. 创建子类,例如关于界面,继承基类,复写抽象方法
public class AboutFragment extends BaseFragment {
     private TopBar vTopBar;

     public static AboutFragment newInstance() {
        return new AboutFragment();
    }

    @Override
    public int onInflaterViewId() {
        return R.layout.me_about;
    }
    
    @Override
    public void onBindView(View view) {
        findView(view);
        bindView();
    }
    
    private void findView(View view) {
       vTopBar = view.findViewById(R.id.top_bar);
    }
    
    private void bindView(View view) {
         //配置标题和返回键
         vTopBar.setTitle(R.string.me_setting_about);
         vTopBar.addLeftBackImageButton().setOnClickListener(v -> {
            if (getActivity() != null) {
                getActivity().finish();
            }
        });
        //...
    }
    
    @Override
    public void setData() {
         //显示当前版本
         String version = PackageUtil.getVersionName(getActivity());
         //...
         //如果需要请求接口,再请求...
    }
}

总结

优点:

缺点:

上一篇下一篇

猜你喜欢

热点阅读