用组合取代继承能为 Activity 带来什么


其实我们在非常多 Java 进阶书籍上看到过“开发时应该更倾向于选择组合而不是继承”的建议,为什么建议我们更倾向于而不是全然取代呢,由于当类 A 能全然取代还有一个类 B(我们想让 B 成为 A 的父类)时。我们就应该使用继承,假设 A 不过和 B 有着某些共同的行为。是不应该使用继承的(很多其它的讨论戳我)。

然而,在我阅读别人的源代码时。滥用继承的情况实在是太多了,多少人创建了一个 BaseActivity 后,就让全部 Activity 继承它。在子 Activity 中实现业务逻辑。

并且这样做问题大大的有,最鲜活的样例就是:Joe Newguy 加入到我们组,并实现了 ShinyFeatureActivity。那会组里没有不论什么规定强迫他必须让 ShinyFeatureActivity 继承于 BaseActivity,但他还是这么干了……万幸我们在 Code Review 时发现了这个问题。

此外。假设每个 Activity 都继承于 BaseActivity,在某些情况下。你可能要继承的是其它 Activity(比如:PreferenceActivity、ListActivity)。

虽然大部分 Activity 的子类都有对应的 Fragment 取代,但还是有一部分是没有对应 Fragment 的。某些库仍然须要对应的 Activity 子类。

有些更潜在的问题是:有时候某些 Activity 须要这些行为,其它的 Activity 须要其它行为,而 Java 并不支持多继承,这就意味着我们得将行为有交集的 Activity 的全部行为放到一个独立的类里面。

但这样做会减少可维护性,甚至带来性能影响。

其实,我们会这么干的动机非常easy:代码复用。确实。代码复用非常重要。而我们大部分公共逻辑须要在 Activity 生命周期的某一环实现。但 Application.ActivityLifecycleCallbacks 是一个让人非常蛋疼的玩意。并且可能须要在 Application.onCreate() 方法里注冊它,最讽刺的是:我们想尽办法避免在 Application.onCreate() 方法里注冊它……

这也是无绑定 View 的 Fragment 的由来了,当无数 Android 开发人员把 Fragment 看作 UI 组件时。其实 Fragment 更像生命周期的组件。

为什么要说这些 Fragment 是无绑定 View 的呢?由于在这些开发人员的手里。Fragment 的 onCreateView() 方法既没有被重写,也没有返回 null。

本质上。Fragment 就是一个能够处理或操控事件的组件,而它自身没有对应的 View。

为了区分无绑定 View 的 Fragment 和面向 View 的 Fragemnt,我在命名时会将无绑定 View 的 Fragemnt 命名为 * XXHelper*,其它的就命名为XXFragment。比如。AnalyticsHelper 代表的就是关联分析逻辑的 Fragment。而 HeaderFragment 则显示了一个标题栏。

当然了,大家能够尝试这么干。也能够无视我的建议,我自己是感觉满实用的哈~

由于这些无绑定 View 的 Fragment 里面没有 UI 组件,也就意味着在这些 Fragment 里我们不须要考虑初始化布局所需的 Layout-ID,或者是 View 须要的动画。那么我们全然能够用工厂模式开发这些 Fragment,提高工厂方法的易用性和可操控性。

就这一点来说,他们还能完毕加入 Fragment 自身的操作,我创建了一个 Gist 来为大家介绍要怎么做到,有兴趣的话能够点进去看看哈。

假设使用 Android-Studio 进行开发的话。你能够将它加入到设置的 File and Code Templates 选项中,然后当你创建一个新的类时。在 Kind 下拉选项中选择它。

将 FooHelper 加入到它的父类中非常easy,只要调用 FooHelper.attach(this) 就能够了。但假设对应的父类没有实现 FooHelper 的回调接口的话会出现编译错误,此外。假设 attach() 方法已经被调用了,该方法的返回值会是之前的 Fragment。这个 Gist 包括对 Fragment 和 Activity 的重载,并且将它们转换为使用支持的 Fragement 和 FragmentActivity,当中的意义非常中大。并且它还包括了 FragmentUtils.getParent() 的简化版 —— getParent() 方法(详情戳我)。

显然,无绑定 View 的 Fragment 比 BaseActivity 好用得多,它们非常好地封装了须要生命周期回调(或者是 onActivityResult(),FragmentManager)的处理方法。最优秀的是,我们能够将 Activity 共用的某些逻辑分解到职责单一的模块组件中。Activity 须要什么逻辑,就选择什么模块使用。假设你的 Activity 大部分都须要很多同样的模块。那么你没有理由不实现 CommonComponentsHelper 用于处理这些共用逻辑。并且你也不须要把 Activity 的全部共用依赖放在一个基类中。

1
0

用组合取代继承能为 Activity 带来什么的更多相关文章

  1. Java(Android)编程思想笔记02:组合与继承、final、策略设计模式与适配器模式、内部类、序列化控制(注意事项)

    1.组合和继承之间的选择 组合和继承都允许在新的类中放置子对象,组合是显式的这样做,而继承则是隐式的做. 组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形.即在新类中嵌入某个对象,让其实 ...

  2. 28-React state提升、组件组合或继承

    Lifting State Up state提升 对于在React应用程序中更改的任何数据,应该有一个单一的数据源.通常,都是将state添加到需要渲染的组件.如果其他组件也需要它,您可以将其提升到最 ...

  3. oc随笔二:组合、继承

    在oc中如果没有使用ARC的话,手动管理内存一定要注意处理好“野指针”,通常我们在释放指针的指向的地址时,都要将指针赋值为nil,这样能有效的防止野指针.常用的关键字:retain.assign .s ...

  4. (笔记):组合and继承之访问限制(一)

    下面在介绍组合与继承之前,先介绍一下访问限制,访问限制:public.protected.private三者是按照授权的大小排序的.这里有个博客,对这三者有了经典的诠释.http://blog.csd ...

  5. Effective Java 第三版——18. 组合优于继承

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. 面向对象之组合VS继承:继承过时了?

        在阅读Effective Java中的第16条时发现了一个有趣的机制或者说是模式,那就是组合(文中翻译为复用,但是作者认为组合更能体现这种模式的精神),并且文中建议使用组合.  那什么是组合, ...

  7. day 24 二十四、组合、继承、方法重写和重用、super()

    一.组合 1.定义:自定义类的对象作为类的属性 A类的对象具备某一个属性,该属性的值是B类的对象 基于这种方式就把A类与B类组合到一起 对象既能使用A类中的数据与功能,也能使用B类中的数据与功能 2. ...

  8. 重新精读《Java 编程思想》系列之组合与继承

    Java 复用代码的两种方式组合与继承. 组合 组合只需将对象引用置于新类中即可. 比如我们有一个B类,它具有一个say方法,我们在A类中使用B类的方法,就是组合. public class B { ...

  9. day25-静态、组合、继承

    #!/usr/bin/env python # -*- coding:utf-8 -*- # ----------------------------------------------------- ...

随机推荐

  1. 多目录,多可执行文件的Makfile的编写

    1.前言 在目前的工作中,我遇到这样的一个工作情景,可以认为我要开发一个库,这个库的有多个模块,每个模块的.c放到src中,.h放到include中,这应该是个标准做法. drwxr-xr-x. ro ...

  2. Windows下VS2013创建与使用动态链接库(.dll)

    一.创建动态链接库文件 ** 1.打开VS2013,选择文件,新建工程  2.选择新建W32控制台应用程序,这里将工程名改为makeDLL  3.在应用程序类型中选择DLL,点击完成  4.完成以上步 ...

  3. bisect维护已排序的序列

    #!/usr/bin/env python # -*- coding:utf-8 -*- # author:love_cat import bisect # 用来处理已经排序好的序列,升序 # 二分查 ...

  4. centos6.5 以 zero-dependency Erlang from RabbitMQ 搭建环境

    rabbitmq 官方安装文档可参考:http://www.rabbitmq.com/install-rpm.html  ,由于rabbitmq 使用Erlang 开发的,运行环境需要用到Erlang ...

  5. POJ 1769 Minimizing maximizer(DP+zkw线段树)

    [题目链接] http://poj.org/problem?id=1769 [题目大意] 给出一些排序器,能够将区间li到ri进行排序,排序器按一定顺序摆放 问在排序器顺序不变的情况下,一定能够将最大 ...

  6. 1.13(java学习笔记)异常机制

    异常不同于错误,它是程序运行时产生的未知问题. 如果把程序比喻成一辆汽车,那么汽车开着开着突然前面出现了一个大石头挡住了路,这就叫异常. 那么出现了这个异常我们需要去处理,比如打电话给公路管理局,让它 ...

  7. MySQL 中的 base64 函数

    1. 5.6版本及之后的版本的base64 主要就是两个mysql内部函数to_base64和from_base64,使用也很简单,如下: 5.6之前不支持 mysql> select vers ...

  8. HTML <form> 标签的 accept-charset 属性

    定义和用法 accept-charset 属性规定服务器处理表单数据所接受的字符集. accept-charset 属性允许您指定一系列字符集,服务器必须支持这些字符集,从而得以正确解释表单中的数据. ...

  9. 详细解析ASP.NET中Request接收参数乱码原理

    起因:今天早上被同事问了一个问题:说接收到的参数是乱码,让我帮着解决一下. 实际情景: 同事负责的平台是Ext.js框架搭建的,web.config配置文件里配置了全局为“GB2312”编码: < ...

  10. Sql Server中百万级数据的查询优化

    原文:Sql Server中百万级数据的查询优化 万级别的数据真的算不上什么大数据,但是这个档的数据确实考核了普通的查询语句的性能,不同的书写方法有着千差万别的性能,都在这个级别中显现出来了,它不仅考 ...