編輯:關於android開發
模板方法模式是結構最簡單的行為型設計模式,也是所有模式中最為常見的幾個模式之一,是基於繼承的代碼復用的基本技術。在其結構中只存在父類與子類之間的繼承關系。
定義一個操作中的算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
一個模板方法是定義在抽象類中的,把基本操作方法組合在一起形成一個總算法或一個總行為的方法。這個模板方法定義在抽象類中,並由子類不加以修改地完全繼承下來。所以模板方法大多會定義為final類型,指明主要的邏輯功能在子類中不能被重寫。模板方法是一個具體方法,它給出了一個頂層邏輯框架,而邏輯的組成步驟在抽象類中可以是具體方法,也可以是抽象方法。由於模板方法是具體方法,因此模板方法模式中的抽象層只能是抽象類,而不是接口。
(1)抽象方法:一個抽象方法由抽象類聲明,由具體子類實現。在Java語言裡抽象方法以abstract關鍵字標示。
(2)鉤子方法:一個鉤子方法由抽象類聲明並實現,而子類會加以擴展。子類可以通過擴展鉤子方法來影響模板方法的邏輯。
(1)多個子類有公有的方法,並且邏輯基本相同。
(2)重要、復雜的算法,可以把核心算法設計為模板方法,周邊的相關細節功能由各個子類實現。
(3)重構時,模板方法是一個經常使用的模式,把相同的代碼抽取到父類中,然後通過鉤子方法約束其行為。
以電腦開機為例,假設現在有兩台電腦,一台Windows系統電腦,一台Mac系統電腦。但是開機流程基本一致:步驟為開啟電源、系統檢查、加載系統、檢查是否需要登錄。
抽象的 Computer
/**
* 抽象的 Computer
*/
public abstract class AbstractComputer {
//下面是抽象方法,子類可以覆蓋,不允許外部直接調用這些方法,所以用protected
/**
* 開啟電源
*/
protected abstract void powerOn();
/**
* 檢查硬件
*/
protected abstract void checkHardware();
/**
* 載入操作系統
*/
protected abstract void loadOS();
/**
* 登錄
*/
protected abstract void login();
//下面是鉤子方法,聲明並實現
/**
* 是否需要登錄
*
* @return true為需要登錄
*/
protected boolean isLogin(){
return true;
}
//下面是模板方法,定義為final,子類不能覆蓋此方法
/**
* 啟動計算機方法,步驟為開啟電源、系統檢查、加載系統、檢查是否登錄。
*/
public final void startUp(){
System.out.println("--------開機 START--------");
powerOn();
checkHardware();
loadOS();
if(isLogin()){
login();
}
System.out.println("-------- 開機 END --------");
}
}
Windows系統電腦(不需登錄):
/**
* Windows系統電腦
*/
public class WindowsComputer extends AbstractComputer{
@Override
protected void powerOn() {
System.out.println("Windows電腦開啟電源");
}
@Override
protected void checkHardware() {
System.out.println("Windows電腦檢查硬件");
}
@Override
protected void loadOS() {
System.out.println("Windows電腦載入操作系統");
}
@Override
protected void login() {
}
@Override
protected boolean isLogin() {
return false;//返回false,不需登錄
}
}
Mac系統電腦(需登錄):
/**
* Mac系統電腦
*/
public class MacComputer extends AbstractComputer{
@Override
protected void powerOn() {
System.out.println("Mac電腦開啟電源");
}
@Override
protected void checkHardware() {
System.out.println("Mac電腦檢查硬件");
}
@Override
protected void loadOS() {
System.out.println("Mac電腦載入操作系統");
}
@Override
protected void login() {
System.out.println("Mac電腦登錄");
}
}
調用:
public class Client {
public static void main(String[] args) {
AbstractComputer comp = new WindowsComputer();
comp.startUp();
comp = new MacComputer();
comp.startUp();
}
}
結果:
--------開機 START--------
Windows電腦開啟電源
Windows電腦檢查硬件
Windows電腦載入操作系統
-------- 開機 END --------
--------開機 START--------
Mac電腦開啟電源
Mac電腦檢查硬件
Mac電腦載入操作系統
Mac電腦登錄
-------- 開機 END --------
在使用AsyncTask時,我們都知道把耗時操作放到doInBackground(Params… params)中,在doInBackground之前,如果想做一些初始化操作,可以把實現寫在onPreExecute中,當doInBackground執行完後會執行onPostExecute方法,而我們只需要構建AsyncTask對象,然後執行execute方法。
ActivityThread的main函數被調用後,依次執行Activity的onCreate、onStart、onResume函數,用戶通常在Activity的子類中覆寫onCreate方法,並且在該方法中調用setContentView來設置布局。
(1)工廠方法是模板方法的一種特殊版本。
(2)策略模式和模板方法模式都是封裝算法,一個用組合,一個用繼承。
(3)策略模式和模板模式通常可以互相替換。它們都像試卷,策略模式是選擇題,模板模式是填空題。
模板方法模式用4個字概括就是:流程封裝。也就是把某個固定的流程封裝到一個final方法中,並且讓子類能夠定制這個流程中的某些或者所有步驟,這就要求父類提取公用的代碼,提升代碼的復用率,同時帶來了更好的可擴展性。
(1)封裝不變部分,擴展可變部分。
(2)提取公共部分代碼,便於維護。
需要為每一個基本方法的不同實現提供一個子類,如果父類中可變的基本方法太多,將會導致類的個數增加,系統更加龐大,設計也更加抽象,此時,可結合橋接模式來進行設計。
Android TextView兩端對齊 Android中的TextView控件默認是做不到兩端對齊的,都是左對齊。可能的原因是安卓默認數字、字母不能為第一行以後每行
使用Android studio分析內存洩露 使用Android studio分析內存洩露 This post is a permitted tra
伴隨ListView、RecyclerView、ScrollView滾動滑入滑出小圖標--第三方開源--FloatingActionButton,recyclerview
perf profiling 分析程序性能perf profiling 分析程序性能程序性能分析perf 有一個功能就是按一定頻率采集某一個程序的調用棧,然後對調用棧進行