1. 模式介紹
模式的定義
定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
模式的使用場景
1.多個子類有公有的方法,并且邏輯基本相同時。
2.重要、復雜的算法,可以把核心算法設(shè)計為模板方法,周邊的相關(guān)細節(jié)功能則由各個子類實現(xiàn)。
3.重構(gòu)時,模板方法模式是一個經(jīng)常使用的模式,把相同的代碼抽取到父類中,然后通過鉤子函數(shù)約束其行為。
2. UML類圖
角色介紹
- AbstractClass : 抽象類,定義了一套算法框架。
- ConcreteClass1 : 具體實現(xiàn)類1;
- ConcreteClass2: 具體實現(xiàn)類2;
3. 模式的簡單實現(xiàn)
簡單實現(xiàn)的介紹
模板方法實際上是封裝一個算法框架,就像是一套模板一樣。而子類可以有不同的算法實現(xiàn),在框架不被修改的情況下實現(xiàn)算法的替換。下面我們以開電腦這個動作來簡單演示一下模板方法。開電腦的整個過程都是相對穩(wěn)定的,首先打開電腦電源,電腦檢測自身狀態(tài)沒有問題時將進入操作系統(tǒng),對用戶進行驗證之后即可登錄電腦,下面我們使用模板方法來模擬一下這個過程。
實現(xiàn)源碼
package com.dp.example.templatemethod;
/**
* 抽象的Computer
* @author mrsimple
*
*/
public abstract class AbstractComputer {
protected void powerOn() {
System.out.println("開啟電源");
}
protected void checkHardware() {
System.out.println("硬件檢查");
}
protected void loadOS() {
System.out.println("載入操作系統(tǒng)");
}
protected void login() {
System.out.println("小白的電腦無驗證,直接進入系統(tǒng)");
}
/**
* 啟動電腦方法, 步驟固定為開啟電源、系統(tǒng)檢查、加載操作系統(tǒng)、用戶登錄。該方法為final, 防止算法框架被覆寫.
*/
public final void startUp() {
System.out.println("------ 開機 START ------");
powerOn();
checkHardware();
loadOS();
login();
System.out.println("------ 開機 END ------");
}
}
package com.dp.example.templatemethod;
/**
* 碼農(nóng)的計算機
*
* @author mrsimple
*/
public class CoderComputer extends AbstractComputer {
@Override
protected void login() {
System.out.println("碼農(nóng)只需要進行用戶和密碼驗證就可以了");
}
}
package com.dp.example.templatemethod;
/**
* 軍用計算機
*
* @author mrsimple
*/
public class MilitaryComputer extends AbstractComputer {
@Override
protected void checkHardware() {
super.checkHardware();
System.out.println("檢查硬件防火墻");
}
@Override
protected void login() {
System.out.println("進行指紋之別等復雜的用戶驗證");
}
}
package com.dp.example.templatemethod;
public class Test {
public static void main(String[] args) {
AbstractComputer comp = new CoderComputer();
comp.startUp();
comp = new MilitaryComputer();
comp.startUp();
}
}
輸出結(jié)果如下 :
------ 開機 START ------
開啟電源
硬件檢查
載入操作系統(tǒng)
碼農(nóng)只需要進行用戶和密碼驗證就可以了
------ 開機 END ------
------ 開機 START ------
開啟電源
硬件檢查
檢查硬件防火墻
載入操作系統(tǒng)
進行指紋之別等復雜的用戶驗證
------ 開機 END ------
過上面的例子可以看到,在startUp方法中有一些固定的步驟,依次為開啟電源、檢查硬件、加載系統(tǒng)、用戶登錄四個步驟,這四個步驟是電腦開機過程中不會變動的四個過程。但是不同用戶的這幾個步驟的實現(xiàn)可能各不相同,因此他們可以用不同的實現(xiàn)。而startUp為final方法,即保證了算法框架不能修改,具體算法實現(xiàn)卻可以靈活改變。startUp中的這幾個算法步驟我們可以稱為是一個套路,即可稱為模板方法。因此,模板方法是定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。如圖 :
4. 構(gòu)建整個應用的BaseActivity
每個項目肯定離不開Activity,在Activity的onCreate()方法里面基本都是:設(shè)置布局 ->初始化頭部 -> 初始化界面 -> 初始化數(shù)據(jù)。如果按照這么個流程是不是剛好符合我們模板設(shè)計模式。
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView();
initTitle();
initView();
initData();
}
// 初始化數(shù)據(jù)
protected abstract void initData();
// 初始化界面
protected abstract void initView();
// 設(shè)置界面視圖
protected abstract void setContentView();
// 初始化頭部
protected abstract void initTitle();
}
以后我們每次新建Activity就不會直接繼承自 AppCompatActivity 而是我們自己的BaseActivity就會自動要我們復寫B(tài)aseActivity里面的幾個抽象方法,我們在方法里面寫對應的代碼。
public class MainActivity extends BaseActivity {
@Override
protected void initData() {
}
@Override
protected void initView() {
}
@Override
protected void setContentView() {
setContentView(R.layout.activity_main);
}
@Override
protected void initTitle() {
}
}
這也沒見到什么好處啊~好處我待會再來說,我們先對BaseActivity來擴展一下,一些通用的流程和功能其實可以放在BaseActivity里面,比如前幾次所分享的自己動手打造一套IOC注解框架、啟動Activity…文章來源:http://www.zghlxwxcb.cn/news/detail-645911.html
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView();
// IOC注解注入
ViewUtils.inject(this);
initTitle();
initView();
initData();
}
// 初始化數(shù)據(jù)
protected abstract void initData();
// 初始化界面
protected abstract void initView();
// 設(shè)置界面視圖
protected abstract void setContentView();
// 初始化頭部
protected abstract void initTitle();
/**
* 啟動一個Activity
* @param activity 需要啟動的Activity的Class
*/
public void startActivity(Class<? extends Activity> activity) {
Intent intent = new Intent(this,activity);
startActivity(intent);
}
/**
* findViewById 不需要再去強轉(zhuǎn)
*/
public <T extends View> T viewById(@IdRes int resId) {
return (T) super.findViewById(resId);
}
}
接下來我們來說一下好處,模板設(shè)計模式的好處就不說了網(wǎng)上太多了,我們就只說在真正的開發(fā)中這么做的好處文章來源地址http://www.zghlxwxcb.cn/news/detail-645911.html
- 在實際的開發(fā)過程中我們往往不是一個人在開發(fā),如果把直接在onCreate()里面寫很多東西顯然不行,但是如果寫一些方法,那么每個成員所寫的方法都會不同,何況有些哥們英語估計沒過四級,單詞都寫錯;
- 直接繼承自BaseActivity會自動提示覆蓋方法,更加有利于開發(fā)或者代碼的閱讀,每個方法各盡其職只干自己該干的事,沒事干就歇著;
- 我們可以把通用的流程或者是某些方法放到BaseActivity,這樣又節(jié)省代碼又方便但是不是亂七八糟的放一大堆,細節(jié)會有很多具體可以看視頻講解;
- 我們中間肯定還需要邏輯層的BaseActivity,這樣做其實有利于后期的版本迭代、層次抽離和代碼重構(gòu)…
到了這里,關(guān)于Android模板設(shè)計模式之 - 構(gòu)建整個應用的BaseActivity的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!