Android 面向协议编程 体会优雅编程之旅
Android中面向协议编程的深入浅出
http://blog.csdn.net/sk719887916/article/details skay编写
说起协议,现实生活中大家第一感觉会想到规则或者约定,确实协议的本意就是一种约束,每个人事物都遵守的准则或法则,如果拿生活中的列子来说 法律本身就是一种协议 每个人自然人去遵守,只有遵守了这个法则,执行法律的法院才会对遵守的人管辖有效,当然前提是你必须是在某个国家的法律之内,如果不是某个法律的协议范围之内,当然法院的执法者是无法对其他国家的自然人进行管理的,也就需要一个中间的桥接者进行沟通,比如目前的大使馆就是做这种协议转换的作用。而大使馆又是一个更高层次的协议。
面向协议
那对于编程语言来说协议的范围可以有多方面的解释,不同的语言对协议也有着不同的定义,但是他们的最终目的还是和上面说到的现实问题相一致的,就拿java语言来说 协议是什么,在从事java开发多年的人也未必听说过协议,但说起规则,大家都会想到java接口,确实interface是约束某种规则的,我们定义了某个功能的一些方法,让其他功能遵守了这个协议(java是实现这个接口),才能正常的实用起功能。java对于协议编程有我们熟知的面向接口编程一说,这只是对协议编程的一种细化,java中的接口更是对一种具体api的运用的编程,那么这样的接口编程其实未必是一种行为的协议编程,为什么这么讲呢 我们可以看看OC的中的协议编程。
OC的运用是由于iOS移动开发的兴起而的到广泛运用,然后oc也是一种面向对象语言,也拥有java一样的oop思想,而只不过和我的java的接口有所不同,oc中用了协议一词,它让某个类去遵守某个协议,这样也许更确切显示生活中的协议,OC协议中没有抽象类一说,只有一个单纯的@protocol来进行声明,但是他的实现类并不是我们java中的接口实现类,这里要明确一点OC语言每个类都有一个声明类和实现类,而OC的对于协议的实现类我们要和OC本身的语法要进行区分对待,协议用关直接在继承类(NSObject)后面 <协议名>即可,他的协议也有必须实现和选择实现两种
- @required:表示必须强制实现的方法
- @optional:表示可以有选择性的实现方法
JAVA中用abstract 来定义我们的可选规则和不可选规则,而java中真正的接口类不如说是协议,还不如说他是oc中的代理,于是协议和代理其实密切关联的。
面向切面
说完了协议的概念和在编程语言中的定义,大家会想到面向切面编程,也就是从上面提到的面向接口编程一样,会问到面向协议,面向接口,面向切面,面向对象有啥区别。今天你就以本人的见解给大家梳理一遍
面向对象
面向对象是把任何东西看成一个基本单元,大的基本单元包含小的基本单元,就是把一个整体的东西做到细化,从而是实现整体的组装。
面向接口
面向接口狭义的定义就是对java的接口API的完美运用,编程者建议我们都用接口实现功能重组,其实也是基于面向对象语言的一种特性的多态的扩展,其实这种采用注入方式,或者我们Java1.5新增的注解其实也是对于接口的延生,那么面向接口一般用在小规模的编程中,如果放到整个编程架构,那么面向接口还是去无法完美说服力
面向切面
提到面向切面其实也是对于面向接口的总结,他是将代码现实化,如果我们说道面向接口,大家第一感官就会想到java类的接口类,并不关心一个现实生活中的具体代表什么,那么面向切面来了,他是将我的事物分成一个个事物单元和事物组件,那么这个组件就可以担负起桥接单元的功能,而这个组件有一定的约束力哦,只有符合该组件的要求才能由他来连接,那么通俗的将我们并不关系某个组件由什么组成,我们也只要知道这个单元是符合这个组件的越束就行,就类似我们所说的热插拔,插座和插头的功能,而这种广泛运用在服务端比较多,著名的spring就利用面向切面思想,依赖我们需要的配置注入,其实也就延生客户端的面向协议编程诞生。
面向协议
那么面向协议该怎么做解释呢,在我们的移动端的开发中,我觉得用面向协议总结上面123点的结合一起比较合适,面向协议并不是只是对具体API的运用,也不是对某种局部功能的拆分细化,更不是对某种方法的抽象,也不是说某个功能我们要去完成必须去写一个dao,用daoIPML(javaweb端的常用做法),而是将我的某种规则(某种功能)去和具体调用和分离,也和具体实施者做分离,不管我具体的由谁去做这个规则的实施,但是这个规则是存在,而具体调用规则的人也灵活的,那么移动端的面向协议方可这么认为。
安卓面向协议编程
通看安卓源码我们可以看到谷歌工程师喜欢用xxxManger, xxxMangerImpl,XXXRoot, BaseXXX, 自我分析很久,也许这只是他们的编程习惯而已,更有可能安卓只是一个移动端操作系统,而某些组件更是唯一一组功能集合的管理者,因此以管理者命名的原因居多。在这里暂且不管原因,我们看他实现的整个过程中,所有的组件都是在我们的ActivityThred(以下简称AT)去做动态注入的,也就是说不管是viewRootImpL, ActivtiyManferImpl,都是在AT做实现类的注入,如果某些Manager需要上层调用,那么他会将此Manager绑定到我们的Context静态类中,因此我们在很对地方拿到上下文,就可以得到某些Manager的原因,然后这些manager并不是具体的实现类,都是由他们的IMPL去完成,如果我去做重写或者覆盖东西,其实context内部也利用外部重载进来的代码进行实现,我们就拿普通的onClick()事件来说,比如我在某个界面中给某个view注入单击事件
mView.setOnClickListener("我们自己定义的OnClickListener实现类");
我么看过这个listener后他也就是个接口源码如下
/**
* Interface definition for a callback to be invoked when a view is clicked.
* */
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}
看到他会把我们的listener加入到ListenerInfo中用来一个TAG将事件和view做绑定,
public void setOnClickListener(OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
这些其中的事件传递就不在做些说,那么他由我们的最底层的viewrootImpl(activity的消费事件最终也有viewrootIMpl来进行原始的调用)来进行处理最后回调到我的下面方法
public boolean callOnClick() {
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnClickListener != null) {
li.mOnClickListener.onClick(this);
return true;
}
return false;
}
代码里的只是调用了OnClickListener的onClick()然后就会将我们代码实现的处理逻辑执行,这充分给我们的开发者有自我扩展的能力,不但不会影响源码的其他代码,而且还给了开发者有自己去实现的方式,这也只是一种面向协议的简单运用。
Mvp面向协议编程架构运用
mvp是一种架构模式,我们通常可以将安卓当中的视图和数据分离,采用presenter来进行管理,数据和模型是无法直接通信的,这和mvc的根本区别就是视图和模型无任何交集。
这里写图片描述
但是在庞大的安卓源码中可能并不是只是一个视图和数据模型的分离,也有可能是众多presenter的分离,这将会产生功能之间的mvp架构模式,rootPresener来管理众多的childPresenter, 那么这种面像协议的编程就来了 我们可以看看安卓某些某块的源码(ViewManger)
public interface ViewManager {
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view)
}
其实也是一一个接口类我们的具体实现类如下ViewGroup去实现,看看其中的addView()的实现
public void addView(View child, int index, LayoutParams params) {
if (DBG) {
System.out.println(this + " addView");
}
// addViewInner() will call child.requestLayout() when setting the new LayoutParams
// therefore, we call requestLayout() on ourselves before, so that the child's request
// will be blocked at our level
requestLayout();
invalidate();
addViewInner(child, index, params, false);
}
但是具体的添加视图(addview)只是一个动作性方法,源码又提供了一个进行逻辑性的接口类(ViewParent) 源码部分:
public interface ViewParent {
public void requestLayout();
public boolean isLayoutRequested();
public void requestTransparentRegion(View child);
public void invalidateChild(View child, Rect r);
public ViewParent invalidateChildInParent(int[] location, Rect r);
:::::::略
public void bringChildToFront(View child);
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);
public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
boolean immediate)
}
两个抽象的接口都是由viewgroup去实现,而viewgroup是在viewroot在启动activtiy时候帮到我们的acitivty的,一次一连串的功能协议就走通了,接下来我们可以想想这种思想的好处,为何不直接调用呢,
面向协议编程好处
- 增加扩展功能,也更容易保障具体实现类代码的安全
- 增加新的传参方式(代码块)
- 更容易实现低耦合的思想
- 将具体的实现者进行和执行者分离
这里说个题外话,谷歌喜欢视图层运用Root, Child, 逻辑用Base Normal, 核心开放类用Manager,一般便于维护。这些类是无法修改的。其实只是一种编程的习惯,这和java jdk的命名习惯有很大区别的。
Android 面向协议编程 体会优雅编程之旅的更多相关文章
- python优雅编程之旅
偶然的机会坐上了python的贼船,无奈只能一步步踏上王者之巅..... 参考博客地址:https://mp.weixin.qq.com/s/OZVT3iFrpFReqdYqVhUf6g 1.交换赋值 ...
- fir.im Weekly - 揭秘 iOS 面向协议编程
本期 fir.im Weekly 重点推荐关于 iOS 面向协议编程相关文章,还有 iOS 多线程安全.Swift 进阶.Android MVVM 应用框架.Android 蓝牙实践等技术文章分享和工 ...
- Swift -POP( 面向协议编程)与OOP(面向对象编程)
面向协议编程(Protocol Oriented Programming,简称POP),是Swift的一种编程范式,Apple于2015年WWDC提出的,如果大家看Swift的标准库,就会看到大量PO ...
- 为什么说swift是面向协议编程--草稿
为什么说swift是面向协议编程 public protocol ReactiveCompatible { /// Extended type associatedtype CompatibleTyp ...
- 编程范式 --- 面向协议编程(Protocol Oriented Programming,简称POP)
面向协议编程(Protocol Oriented Programming,简称POP) 是Swift的一种编程范式,Apple于2015年WWDC踢出 在Swift的标准库中,能见到大量POP的影子 ...
- Swift 学习笔记(面向协议编程)
在Swift中协议不仅可以定义方法和属性,而且协议是可以扩展的,最关键的是,在协议的扩展中可以添加一些方法的默认实现,就是在协议的方法中可以实现一些逻辑,由于这个特性,Swift是可以面向协议进行编程 ...
- Android面向切面编程(AOP)(转)
转自:https://www.jianshu.com/p/aa1112dbebc7 一.简述 1.AOP的概念 如果你用java做过后台开发,那么你一定知道AOP这个概念.如果不知道也无妨,套用百度百 ...
- (54)LINUX应用编程和网络编程之九Linux网络通信实践
3.9.1.linux网络编程框架 3.9.1.1.网络是分层的 (1)OSI 7层模型(理论指导) (2)网络为什么要分层 (3)网络分层的具体表现 3.9.1.2.TCP/IP协议引入(网络分层实 ...
- Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
随机推荐
- angularjs中关于跨域设置白名单
在config中注入$sceDelegateProvider服务使用resourceUrlWhitelist([])方法添加白名单 跨域时将method的属性设置为"jsonp"就 ...
- Python小代码_13_生成两个参数的最小公倍数和最大公因数
def demo(m, n): if m > n: m, n = n, m p = m * n while m != 0: r = n % m n = m m = r return (int(p ...
- CSS缩写的样式
熟悉和了解CSS的朋友都知道,CSS样式表有很多缩写方式.比如,定义字体.定义背景等,都可以把CSS代码缩写到一行.为了能更好的搞清楚CSS缩写方法,我收集整理了一些有关CSS简写的参考资料,也是对自 ...
- Jmeter_ForEach控制器实现网页爬虫
一直以来,爬虫似乎都是写代码去实现的,今天像大家介绍一下Jmeter如何实现一个网页爬虫! Jmeter的爬虫原理其实很简单,就是对网页提交一个请求,然后把返回的所有href提取出来,利用ForEac ...
- 排序分析函数中对null的处理
--排序分析函数中对null的处理 --分析:对于null在分析函数中是升序默认是nulls last,降序默认是nulls first.如果不指定排序,那么是升序 )); ,'测试1'); ,'测试 ...
- Java关键字---this的由来和其三大作用
[声明]欢迎转载,但请保留文章原始出处→_→ 秦学苦练:http://www.cnblogs.com/Qinstudy/ 文章来源:http://www.cnblogs.com/Qinstudy/p/ ...
- 【python标准库模块二】random模块学习
random模块是用来生成随机数的模块 导入random模块 import random 生成一个0~1的随机数,浮点数 #随机生成一个0~1的随机数 print(random.random()) 生 ...
- Mac下配置远程Linux 服务器SSH密钥认证自动登录
1. 在本地机器创建公钥 打开万能的终端,执行如下命令,无视一切输出,一路欢快地回车即可. ssh-keygen -t rsa -C 'your email@domain.com' -t 指定密钥类型 ...
- android 获取栈顶activty的方法总结(兼容API 5.0)
声明:本文为Dujinyang CSDN原创投稿文章,未经许可,禁止任何形式的转载. 最近5.0\6.0\7.0 安卓系统都陆续上岗了,兼容性和代码更新是个很头疼的问题,这次我们来说下TASK的基础和 ...
- OpenResty和Resis一些基本的性能配置
Basics: 1. Ensure that you have not disabled Lua code cache: https://github.com/openresty/lua-nginx- ...