Android设计模式(八)--模板方法模式

Android设计模式(八)--模板方法模式

到国美面试Android的时候。问我的设计模式相关的问题:

1、单例模式的意义时什么。

2、有哪几种工厂方法模式;

3、你用过的模板方法模式。举例说明;

自己感觉答的一塌糊涂。

模板方法模式都没说出来;

悲剧。

基础不牢。地动山摇。

大公司注重基础,所以对于java 基础,设计模式。算法。

这些是一定坚固的。


1、定义:

定义一个操作算法的骨架,将一些步骤延伸到子类中。
模版方法模式使得子类能够不改变算法结构就可以重定义该算法的某些步骤。

Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. 

Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

2、作用:

通过使用模板方法模式。能够将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的运行次序。而通过其子类来覆盖某些步骤。从而使得同样的算法框架能够有不同的运行结果。

3、模板类,模板方法:

   3.1、模板类能够是抽象类,也能够是详细类,依据须要来确定。

   3.2、模板类中的模板方法。一定是详细方法,其它方法能够使抽象方法也能够是详细方法;

   3.3、通过继承与多态的控制。能够实现子类对父子的反向控制;

   


4、demo

package com.example.demo.TemplateMethod;

import android.util.Log;

/**
 * 模版方法抽象类
 * @author qubian
 * @data 2015年6月9日
 * @email naibbian@163.com
 *
 */
public abstract class TemplateLotteryAbs {

	/**
	 * 获取随机数
	 */
	protected abstract String getRandomNum(int num);
	/**
	 * 处理随即数产生的数据
	 */
	protected abstract void doLotteryString(String lottery);
	/**
	 * 计算注数
	 */
	protected abstract void doLotteryNum();
	
	/**
	 * 是否标红
	 * @return
	 */
	public boolean shouldSetStringRed()
	{
		return false;
	}
	
	/**
	 * 标红
	 */
	protected void SetStringRed()
	{
		Log.i("TemplateAbs", "SetStringRed");
	}
	
	/**
	 * 模板方法:定义在抽象类中,并由子类不加以改动地全然继承下来。

* 模板方法是一个详细方法。它给出了一个顶层逻辑框架, * 而逻辑的组成步骤在抽象类中能够是详细方法,也能够是抽象方法。 * 因为模板方法是详细方法,因此模板方法模式中的抽象层仅仅能是抽象类,而不是接口。 * */ public void doInfo(int num) { // 内部控制 doLotteryString(getRandomNum(num)); doLotteryNum(); // 这能够通过 继承覆盖,反向控制父类的方法 if (shouldSetStringRed()) { SetStringRed(); } } }


详细方法:

package com.example.demo.TemplateMethod;

import android.util.Log;


/**
 * 模板方法子类
 * @author qubian
 * @data 2015年6月9日
 * @email naibbian@163.com
 *
 */
public class TemplateLottery extends TemplateLotteryAbs{

	private static final String TAG ="TemplateObj";

	@Override
	protected String getRandomNum(int num) {

		return "1,2,3,4,5,6";
	}

	@Override
	protected void doLotteryString(String lottery) {
		Log.i(TAG, "doLotteryString");
	}

	@Override
	protected void doLotteryNum() {
		
	}
	/**
	 * 反向控制
	 */
	@Override
	public boolean shouldSetStringRed() {

		return super.shouldSetStringRed();
	}
	@Override
	protected void SetStringRed() {

		super.SetStringRed();
	}

}

使用:

package com.example.demo.TemplateMethod;

/**
 * 使用 模板方法模式
 * @author qubian
 * @data 2015年6月9日
 * @email naibbian@163.com
 *
 */
public class UseTemplate {

	public void use()
	{
		
		TemplateLotteryAbs tempObj= new TemplateLottery();
		
		tempObj.doInfo(5);
	}
}

7、在Android中的运用:

在Android源代码中,View中的Draw()方法就是一个“模板方法”。
当继承View子类中,假设要重写或者扩展这种方法时,整个方法流程和基本内容不可以改动,

View 视图的构建。都是由View自身实现,当中的算法实现流程都是确定的;


子类仅仅能通过扩展onDraw(Canvas canvas)和dispatchDraw(Canvas canvas)两个函数。使子类自己的View显示效果和别的详细子类的不同。
当中有:TextView类中重写了OnDraw函数。ViewGroup类,SurfaceView重写了dispatchDraw()函数等等。


public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {

    /**
     * Implement this to do your drawing.
     *
     * @param canvas the canvas on which the background will be drawn
     */
    protected void onDraw(Canvas canvas) {
    }
    /**
     * Called by draw to draw the child views. This may be overridden
     * by derived classes to gain control just before its children are drawn
     * (but after its own view has been drawn).
     * @param canvas the canvas on which to draw the view
     */
    protected void dispatchDraw(Canvas canvas) {

    }
}


public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {

    @Override
    protected void onDraw(Canvas canvas) {
        restartMarqueeIfNeeded();

        // Draw the background for this view
        super.onDraw(canvas);

        final Drawables dr = mDrawables;
        if (dr != null) {
             //.....
        }

        int color = mCurTextColor;
        mTextPaint.setColor(color);
        mTextPaint.drawableState = getDrawableState();

        canvas.save();
    }