原本对于设计模式的写作还不在当前的计划中,然而因为在写TWU作业的时候,觉得代码写得不好,于是慢慢试着一点点重构,重新看着设计模式。也开始记录这一点点的方法,至少这些步骤是必要的。
对于一个基本的C/C++/Java/Python的Application来说,他只需要有一个Main函数就够了。对于一个好一点的APP来说,他可能是下面的步骤,
main(){
init();
while(!condition()){
do();
}
}
上面的代码是我在学51/AVR等各式嵌入式设备时,经常是按上面的写法写的,对于一个更符合人性的App来说他应该会有一个退出函数。
main(){
init();
while(!condition()){
do();
}
exit();
}
于是很幸运地我找到了这样的一个例子。
过去看过Arduino的代码,了解过他是如何工作的,对于一个Arduino的代码来说,必要的两个函数就是。
void setup() {
}
void loop() {
}
setup()函数相当于上面的init(),而loop()函数刚相当于上面的do()。似乎这就是我们想要的东西,看看Arduino目录中的Arduino.h就会发现,如下的代码(删减部分代码)
#include <Arduino.h>
int main(void)
{
init();
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
代码中的for(;;)看上去似乎比while(True)容易理解得多,这也就是为什么嵌入式中经常用到的是for(;;),从某种意义上来说两者是等价的。再有不同的地方,就是gcc规定了,main()函数不能是void。so,两者是差不多的。只是没有,并没有在上面看到模板方法,等等。我们在上面所做的事情,便是创建一个框架。
模板方法: 在一方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
对于我来说,我就是在基本的App中遇到的情况是一样的,在我的例子中,一开始我的代码是这样写的。
public static void main(String[] args) throws IOException {
initLibrary();
while(!isQuit){
loop();
}
exit;
}
protected void initLibrary(); {
System.out.println(welcomeMessage);
}
protected void loop() {
String key = "";
Scanner sc = new Scanner(System.in);
key = sc.nextLine();
System.out.println(results);
if(key.equals("Quit")){
setQuit();
}
}
protected void exit() {
System.out.println("Quit Library");
}
只是这样写感觉很是别扭,看上去一点高大上的感觉,也木有。于是,打开书,找找灵感,就在《敏捷软件开发》一书中找到了类似的案例。Template Method模式可以分离能用的算法和具体的上下文,而我们通用的算法便是。
main(){
init();
while(!condition()){
do();
}
exit();
}
看上去正好似乎我们当前的案例,于是便照猫画虎地来了一遍。
创建了一个名为App的抽象基类,
public abstract class App {
private boolean isQuit = false;
protected abstract void loop();
protected abstract void exit();
private boolean quit() {
return isQuit;
}
protected boolean setQuit() {
return isQuit = true;
}
protected abstract void init();
public void run(){
init();
while(!quit()){
loop();
}
exit();
}
}
而这个也和书中的一样,是一个通用的主循环应用程序。从应用的run函数中,可以看到主循环。而所有的工作也都交付给抽象方法,于是我们的LibraryApp就变成了
public class LibraryApp extends App {
private static String welcomeMessage = "Welcome to Biblioteca library";
public static void main(String[] args) throws IOException {
(new LibraryApp()).run();
}
protected void init() {
System.out.println(welcomeMessage);
}
protected void loop() {
String key = "";
Scanner sc = new Scanner(System.in);
key = sc.nextLine();
if(key.equals("Quit")){
setQuit();
}
}
protected void exit() {
System.out.println("Quit Library");
}
}
然而,如书中所说这是一个很好的用于示范TEMPLATE METHOD模式的例子,却不是一个合适的例子。
参考书目
围观我的Github Idea墙, 也许,你会遇到心仪的项目