课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
相信对于大多数的android开发程序员来说都有一套符合自己风格的软件开发方法,今天,我们就给大家介绍一下关于如何利用Clean架构来进行android软件开发的。
下面,就开始今天的主要内容吧,首先,我们先来了解一下关于Clean架构的基本定义是什么。
什么是Clean架构?
有许多文章已经对Clean架构的概念做过介绍。在此我讲一讲Clean架构的核心内容。
通常所说的Clean,是指代码被分为像洋葱状的多个层,其规则基础:内层不需要知道外层在干什么。即向内依赖。
这在Anroid中意味着什么
一般来说,你的应用可以有任意数量的层,除非你的Android应用包含企业级的业务逻辑,最常见的是3层:
外层:实现层
中间层:接口适配层
内层:业务逻辑层
实现层是框架要求所有事情发生的地方。构架代码包括不解决特定问题的代码,比如所有Android开发者都喜欢的创建Activity和Fragment,发送Intent,以及其它网络和数据库相关的框架代码。
接口适配层的目标是连接业务逻辑和框架代码。
最重要的问题是业务逻辑层。这里是你的应用中实际解决问题的地方。这里不会有框架代码,你应该能在没有模拟器支持下运行这部分代码。这样你的业务逻辑代码才容易测试、开发和维护。这是Clean架构的主要优势。
核心层之上的每一层都需要为下一层转换模型结构。内层不会引用外层的模型,但外层可以使用内层的模型。这也是前面提到的依赖规则。虽然这样做会导致更大的开销,但能确保各层代码之间的解耦。
怎样开始构建一个Clean应用?
我做了一个样板项目,它为你提供了所有的底层命令。这是一个Clean启动包,在设计之初就包含最常用的一些工具包。你可免费下载和修改,还能用它建立自己的应用程序。
开始编写新用例
本节将解释所有需要编写的代码,你可通过上一节提供的样板文件使用Clean方法创建一个示例。一个示例只代表应用程序中的部分独立功能。用户(例如,在点击时)可以选择启用或不启用。
首先我们来解释这种方法的结构和术语。这里要说的是我如何构建应用程序,其方法并不固定,你可根据你的需求组织不同的结构。
结构
一般的Android应用结构如下:
外层包:UI、Storage、Network等。
中层包:Presenters,Converters
内层包:Interactors、Models、Repositories、Executor
外层
上面已经提到过,这里是框架的细节。
UI —包括Activite、Fragment、Adapter和其它用户界面相关的代码。
Storage — 数据库相关代码,实现Interactor需要使用的接口,用于访问和存储数据。包含如ContentProviders或者像DBFlow这样的ORM。
Network — 类似Retrofit的网络操作。
中层
粘合代码层,将实现细节与业务逻辑连接起来。
Presenters — 处理来自UI的事件(比如用户单击)或者常用作内层(Interactor)的回调。
Converters — 转换器对象负责把内部模型转换为外部模型,反之亦然。
内层
核心层包含大部分高等级代码。这里的所有类都是POJO。这一层中的类和对象都不是特定运行在Android应用中,可以非常容易的移植到其它JVM运行。
Interactors-这些是实际包含业务逻辑代码的类。这些类在后台运行,并使用回调向上层传递事件。在一些项目中,它们也被称为用例(可能是一个合适的名称)。在您的项目中可能有很多小的用于解决特定问题Interactor类,这属正常现象。可以说,它符合单一责任原则,而且这样的理解更容易让人接受。
Models-这些是您在业务逻辑中处理的业务模型。
Repositories -此包仅包含数据库或其他外层实现的接口。Interactors使用这些接口来访问和存储数据。也称为仓库模式。
Executor-此包包含用于调用工作线程执行器在后台执行Interactors的代码。这个包一般不需要你修改任何部分。
编写新的Interactor(内部/核心层)
事实上你可以从架构的任意层开始编码,但是我还是推荐你首先从核心业务逻辑开始。因为逻辑代码写好之后可以测试,不需要activity也可以正常运行。
所以我们先从创建一个Interactor开始。Interactor是用例主逻辑实现的地方。所有的Interactors都运行在后台线程,因此应该不会对UI展示造成影响。我们在这里新建一个Interactor,叫做WelcomingInteractor。
Callback负责和主线程中的UI交互,我们之所以将其放在Interactor接口中是因为我们不需要将其重新命名为WelcomingInteractorCallback——用于将其与其他回调区分。下面让我们实现取回消息的逻辑。假设我们有一个Interactor的MessageRepository,可以给我们发送欢迎消息。
编写展现层
展现代码属于简洁框架的外层。它由向用户呈现界面的框架代码组成。我们使用MainActivity类在用户回到应用的时候向用户显示欢迎信息。
你可能注意到Interactor的行为与AsyncTask相类似,都是在提供所需东西后运行。那为什么不使用AsyncTask呢?因为这是Android代码,需要模拟器才能运行或测试。
我们为Interfactor提供下列属性:
ThreadExecutor实例负责在后台线程中执行Interactor。我通常会使用单例模式。这个类实际驻留在域包中,不需要在外层实现。
MainThreadImpl实例负责在主线程上从Interactor发送可运行对象。主线程可以使用框架代码访问,因此这个类需要在外层实现。
你可能注意到我们向Interactor提供了this,因为MainPresenter也是一个Callback对象,Interactor会用它在事件回调中更新UI。
WelcomeMessageRepository实现了Interactor用到的MessageRepository接口,所以我们提供了它的实例。WelcomeMessageRepository会在编写存储层一节中详述。
编写存储层
repository中的接口就在存储层实现。所有数据库相关的代码都在这里。仓库模式只是表达数据来源。但我们的主要业务逻辑不在乎首数据的来源——不管它是来自数据库、服务器还是文本文件。
对于复杂的数据,你可以使用ContentProviders或者像DBFlow这样的ORM工具处理。如果你需要从Web接收数据,那就会用到Retrofit。如果你需要简单的键值对存储,那你会用到SharedPreferences。不管怎样,你需要选择正确的工具。
结论
对于我来说,这是迄今为止开发应用程序的最佳方式。解耦的代码能让人把注意力放在具体的问题上,而不受其他事件干扰。这是一个不错的SOLID方法,但我们还需要一些时间适应。希望这篇文章的示例能让你对该内容有进一步了解。
译作:边城,Tocy,Viyi,紫系流月,无若
【免责声明】:本内容转载于网络,转载目的在于传递最新信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。