Android 最常用的设计模式四 安卓源码分析——模板方法(Mould)
对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字标示。
模板方法 一 个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
public abstract class IBaseActivity extends Activity{/** * 模板方法,用于返回布局ID */ public abstract int initLayout(); /** * 模板方法,初始化View * final方法必须有执行体 * 和抽象方法是有区别 */ public final void initView(){setColor(); }; public void setColor(){}/** * 模板方法,获取数据,执行耗时操作 */ protected abstract void requestData(); /** * 提供给子类动态设置状态栏颜色 */ protected void setSystemBarColor(int colorId) {}//...省略一体化状态栏处理 /** * 该方法在onCreate中执行,用于获取Fragment的参数传递 * 子类可按情况自行选择复写 */ protected void getArgs() {}
public class MainActivity extends IBaseActivity {@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }@Override public int initLayout() {return 0; }@Override protected void requestData() {} }
- 父类中控制流程的方法定义为Final
- 父类中提供一系列子类可复写的方法,从而将具体步骤中的实现延迟到子类中
从上面可以看出,BaseActivity
中的Oncrea()
方法被定义为Final
,所以子类是无法重写的,这样可以很好的避免子类复写导致执行流程被打乱.由于父类中流程已经定义好,子类只需要负责具体实现的步骤即可,这样代码结构非常清晰,且不容易出错.
安卓代码中用到的地方:
1.View的绘制
2.AsyncTask
public abstract class AsyncTask<Params, Progress, Result> {private static final String LOG_TAG = "AsyncTask"; private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); // We want at least 2 threads and at most 4 threads in the core pool, // preferring to have 1 less than the CPU count to avoid saturating // the CPU with background work private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE_SECONDS = 30; private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) {return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); }}; private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(128); /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR; static {ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); threadPoolExecutor.allowCoreThreadTimeOut(true); THREAD_POOL_EXECUTOR = threadPoolExecutor; }
@MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) {if (mStatus != Status.PENDING) {switch (mStatus) {case RUNNING:throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED:throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); }}mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) {return executeOnExecutor(sDefaultExecutor, params); }
模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
认识到模板方法的这种思想,父类可以让未知的子类去做它本身可能完成的不好或者根本完成不了的事情,对框架学习大有帮助。
对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字标示。
模板方法 一 个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
public abstract class IBaseActivity extends Activity{ /** * 模板方法,用于返回布局ID */ public abstract int initLayout(); /** * 模板方法,初始化View * final方法必须有执行体 * 和抽象方法是有区别 */ public final void initView(){ setColor(); }; public void setColor(){ } /** * 模板方法,获取数据,执行耗时操作 */ protected abstract void requestData(); /** * 提供给子类动态设置状态栏颜色 */ protected void setSystemBarColor(int colorId) { } //...省略一体化状态栏处理 /** * 该方法在onCreate中执行,用于获取Fragment的参数传递 * 子类可按情况自行选择复写 */ protected void getArgs() { }
public class MainActivity extends IBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public int initLayout() { return 0; } @Override protected void requestData() { } }
- 父类中控制流程的方法定义为Final
- 父类中提供一系列子类可复写的方法,从而将具体步骤中的实现延迟到子类中
从上面可以看出,BaseActivity
中的Oncrea()
方法被定义为Final
,所以子类是无法重写的,这样可以很好的避免子类复写导致执行流程被打乱.由于父类中流程已经定义好,子类只需要负责具体实现的步骤即可,这样代码结构非常清晰,且不容易出错.
安卓代码中用到的地方:
1.View的绘制
2.AsyncTask
public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); // We want at least 2 threads and at most 4 threads in the core pool, // preferring to have 1 less than the CPU count to avoid saturating // the CPU with background work private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE_SECONDS = 30; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR; static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); threadPoolExecutor.allowCoreThreadTimeOut(true); THREAD_POOL_EXECUTOR = threadPoolExecutor; }
@MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
认识到模板方法的这种思想,父类可以让未知的子类去做它本身可能完成的不好或者根本完成不了的事情,对框架学习大有帮助。
Android 最常用的设计模式四 安卓源码分析——模板方法(Mould)相关推荐
- Android 9(P)之init进程启动源码分析指南之一
Android 9 之init进程启动源码分析指南之一 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...
- Android 9 (P)之init进程启动源码分析指南之三
Android 9 (P)之init进程启动源码分析指南之三 Android 9 (P)系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 An ...
- Android 8.1/9.0 MTK Camera源码分析之录像快门声音控制流程
前面已经针对拍照快门声音控制流程进行了分析,接下来分析一下录像快门声音的控制流程. Android 8.1/9.0 MTK Camera源码分析之快门声音控制流程 这两篇文章其实都是相对于手机系统RO ...
- Android 8.1/9.0 MTK Camera源码分析之快门声音控制流程
Android 8.1/9.0 MTK Camera源码分析之快门声音控制 在Android 8.1上mtk camera有控制快门声音的接口,但是并没有了控制录像快门声音的接口.之所以会有这个现象, ...
- 【C++】Android (Light)RefBase-sp-wp引用计数-智能指针源码分析
文章目录 1.RefBase简介 2.RefBase源码分析 3.RefBase使用注意事项 4.总结 1.RefBase简介 什么是RefBase?RefBase是Android中的一个C++类,用 ...
- 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 源码分析 | 创建 Protobuf 对象 )
文章目录 一.Protobuf 源码分析 二.创建 Protobuf 对象 三.完整代码示例 四.参考资料 一.Protobuf 源码分析 Protobuf 源文件如下 : addressbook.p ...
- 解密android日志xlog,XLog 详解及源码分析
一.前言 这里的 XLog 不是微信 Mars 里面的 xLog,而是elvishew的xLog.感兴趣的同学可以看看作者 elvishwe 的官文史上最强的 Android 日志库 XLog.这里先 ...
- Android SQLite多线程读写和线程同步源码分析
没啥诀窍,只需保证几个线程都是用的一个SQLiteDataBase对象就行了. 如果我们非要在不同线程中用两个或更多的SQLiteDataBase对象呢,当然这些SQLiteDataBase对象所操作 ...
- 【Android CameraX】CameraXBasic —— 官方CameraX实例源码分析
一.简介 二.源码分析 2.1 build.gradle 2.2 代码结构 2.3 变量 2.3.1 lensFacing 2.3.2 preview 2.3.3 Image capture 2.3. ...
- axios核心内容(四)源码分析
axios之源码分析 1.源码目录结构 2.源码分析 (1)axios与Axios的关系 (2)instance与axios的区别 (3)axios运行的整体流程 (4)axios的请求/响应拦截器 ...
最新文章
- C++ 自由存储区是否等价于堆?
- RocketMQ:NameServer路由管理源码分析
- 计算机应用基础实训任务书,《计算机应用基础》任务书
- NYOJ 170 网络的可靠性
- Mybatis使用IN语句查询
- Makefile文件试错
- java 蓝桥杯算法训练 数组查找及替换
- [配置]VUE中通过process.env判断开发,测试和生产环境,并分环境配置不同的URL HOST
- php监控nginx,zabbix php nginx 监控搭建
- struts 1.x 原理
- 盐城计算机考试时间安排,2019盐城中考具体时间安排 什么时候考试
- 当想给下一个请求发送同享的数据时候 可以使用域对象设置属性
- 深入解密比Guava Cache更优秀的缓存-Caffeine
- 电商物流快递意外延误创意海报设计PSD格式,用心良苦
- 仿照elementUI编写自己的表单组件
- mysql 用户名唯一,mysql用户名和密码(mysql忘记用户名密码)
- SpringBoot 下载打包图片
- 亚马逊电商数据自动化管理接口平台JAVA SP-API接口开发(下)
- Unity 使用 Behaviac (二)让unity的行为能执行behaviac搭建的树的逻辑
- 人工智能 | 自动驾驶与人工智能前沿研究报告(人才篇)