热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android编程设计模式之模板方法模式详解

这篇文章主要介绍了Android编程设计模式之模板方法模式,结合实例形式详细分析了Android模板方法模式的概念、功能、使用场景、用法及相关操作注意事项,需要的朋友可以参考下

本文实例讲述了Android编程设计模式之模板方法模式。分享给大家供大家参考,具体如下:

一、介绍

在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是,某些步骤的具体实现是未知的,或者说某些步骤的实现是会随着环境的变化而改变的,例如,执行程序的流程大致如下:

1.检查代码的正确性;
2.链接相关的类库;
3.编译相关代码;
4.执行程序。

对于不同的程序设计语言,上述4个步骤都是不一样的,但是,它们的执行流程是固定的,这类问题的解决方案就是我们本章要讲的模板方法模式。

二、定义

定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

三、使用场景

多个子类有公有的方法,并且逻辑基本相同时。

重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。

重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

四、模板方法模式的UML类图

UML类图:

角色介绍:

AbstractClass:抽象类,定义了一套算法框架。

ConcreteClass1:具体实现类1。

ConcreteClass2:具体实现类2。

五、简单示例

模板方法实际上是封装一个固定流程,就像是一套执行模板一样,第一步该做什么,第二步该做什么都已经在抽象类中定义好。而子类可以有不同的算法实现,在框架不被修改的情况下实现某些步骤的算法替换,下面以打开计算机这个动作来简单演示一下模板方法。打开计算机的整个过程都是相对固定的,首先启动计算机电源,计算机检测自身状态没有问题时将进入操作系统,对用户进行验证之后即可登录计算机,下面我们使用模板方法来模拟一下这个过程:

抽象的 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 --------

六、Android源码中的模板方法模式

1、AsyncTask

在使用AsyncTask时,我们都知道把耗时操作放到doInBackground(Params… params)中,在doInBackground之前,如果想做一些初始化操作,可以把实现写在onPreExecute中,当doInBackground执行完后会执行onPostExecute方法,而我们只需要构建AsyncTask对象,然后执行execute方法。

2、Activity的生命周期

ActivityThread的main函数被调用后,依次执行Activity的onCreate、onStart、onResume函数,用户通常在Activity的子类中覆写onCreate方法,并且在该方法中调用setContentView来设置布局。

七、区别

工厂方法是模板方法的一种特殊版本。

策略模式和模板方法模式都是封装算法,一个用组合,一个用继承。

策略模式和模板模式通常可以互相替换。它们都像试卷,策略模式是选择题,模板模式是填空题。

八、总结

模板方法模式用4个字概括就是:流程封装。也就是把某个固定的流程封装到一个final方法中,并且让子类能够定制这个流程中的某些或者所有步骤,这就要求父类提取公用的代码,提升代码的复用率,同时带来了更好的可扩展性。

优点:

封装不变部分,扩展可变部分。

提取公共部分代码,便于维护。

缺点:

需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象,此时,可结合桥接模式来进行设计。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
author-avatar
mobiledu2502931473
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有