模版设计模式

2019-05-31  本文已影响0人  gczxbb

一、概念介绍

在父类中定义一个操作流程,该流程的每一步骤是固定的,步骤中具体的事情实现方法(算法)交给子类完成。
模版方法,父类定义一套固定的方法,自己没实现,让子类实现,每个子类只需要实现父类的方法,父类已经安排好执行的步骤。
比如,父亲有一些梦想没有实现,没上过大学,很遗憾,该梦想由一系列具体的小梦想步骤组成,让孩子去完成这个梦想。

public abstract class FatherClass {
    //父亲的梦想模版
    public final void lifeDream(){
        //出生
        doUniversity();
        doGraduate();
        doDoctor(); 
    }
    public void doUniversity() {
        //父亲未读大学,空方法
    }
    //读研
    public abstract void doGraduate();
    //读博
    public abstract void doDoctor();
}

lifeDream步骤确定,do大学,do研究生,do博士,一步步来。doXxx抽象方法,子类去实现。

public class ChildClass extends FatherClass{
    //按照父亲设定的梦想上大学
    @Override
    public void doUniversity() {
        //学习
    }

    //按照父亲设定的梦想做研究
    @Override
    public void doGraduate() {
        //研究
    }
    
    //按照父亲设定的梦想读博士
    @Override
    public void doDoctor() {
        //继续研究
    }
}

子类,doXxx方法,具体的实现,在大学研究生博士做具体的事情,最终达成目的。

二、在Android中的应用

在Android系统,测量、布局、绘制过程,使用模版设计模式,View基类提供一套测量、布局和绘制的模板步骤,每个子类View负责测量、布局、绘制的具体实现。
视图测量
measure方法,基类View提供的测量方法,final关键字修饰,子类无法重写。树结构中每个视图的测量,都先调用此方法,测量流程中调用onMeasure方法。
View类提供一个默认onMeasure方法,子类重写该方法,实现具体的测量。

模版方法,measure方法。
onMeasure方法,子类实现。

视图布局
layout方法,基类View提供的布局方法,final关键字修饰,子类不能重写。
ViewGroup的layout方法,调用父类View的layout方法,该方法实现了一套布局流程。

@Override
public final void layout(int l, int t, int r, int b) {
    if (!mSuppressLayout && (mTransition == null || !mTransition.isChangingLayout())) {
        if (mTransition != null) {
            mTransition.layoutChange(this);
        }
        super.layout(l, t, r, b);
    } else {
        mLayoutCalledWhileSuppressed = true;
    }
}

View的layout方法,保存该视图本身在父视图中的Rect区域,上下左右四个入参,调用onLayout方法,实现内部子视图布局,View类不需要给子视图布局,该方法在View类中是空。
onLayout方法,View类是空方法,ViewGroup类是抽象方法,ViewGroup子类实现具体布局,只有ViewGroup类型需要为子视图布局。

举例视图布局

举例,一个LinearLayout类视图,两个ImageView类型子视图。
在布局时,LinearLayout类是ViewGroup的子类,调用父类ViewGroup的layout方法,super类layout方法,即View类layout方法,将它自己在父视图坐标区域入参保存,然后,调用onLayout方法,LinearLayout类重写,布局两个子视图。

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (mOrientation == VERTICAL) {
        layoutVertical(l, t, r, b);
    } else {
        layoutHorizontal(l, t, r, b);
    }
}

遍历调用child视图ImageView的layout方法,基类View的layout方法,入参是每个ImageView在LinearLayout中的Rect区域,保存到子视图ImageView内部,然后,调用ImageView的onLayout方法,ImageView是View类型,未重写onLayout方法。

模版,layout方法,View类定义模板。
onLayout方法,ViewGroup的子类实现,View类未实现。

视图绘制
draw方法,基类View提供的绘制方法。
onDraw方法,View类空方法,子类重写,具体绘制。
dispatchDraw方法,View类空方法,ViewGroup实现,绘制分发。
每一个View类的draw方法,绘制步骤是onDraw方法,dispatchDraw方法。View子类实现onDraw方法,dispatchDraw方法是派发,遍历每个子视图draw方法,在ViewGroup类实现一次,它的子类不需要重写。

模版方法,draw方法。
onDraw方法,子类实现,dispatchDraw方法,ViewGroup类实现。

模版设计模式,通过继承,改变父类工序中其中一道流程的实现方法。


任重而道远

上一篇 下一篇

猜你喜欢

热点阅读