到國美面試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 [email protected]
*
*/
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 [email protected]
*
*/
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 [email protected]
*
*/
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();
}