前置知识
- 已入门 Android
- 了解过一些设计原则
前言
关于 Android 的架构问题,想必大家都听说过 MVC、MVP 和 MVVM ,且当下又出现了更新的 MVI。诸如此类的这些架构,都是我们日常所在使用的。这是我们代码设计中,对于业务开发会经常要用到的。但是除却业务开发呢?我们需要将系统分为更多层的时候需要怎么办呢?要了解哪些东西呢?
我们不妨将视野放宽,看看 Android 本身的架构,或者是其他客户端手段的架构,亦或是前端后端的架构,学习他们的架构手段,我们也能收获很多设计的思想。所以本文将会简单的讲一下一些值得我们学习的架构手段。
架构的作用
我们经常说一个架构帮助我们解耦,让我们开发得更顺畅。那么架构的作用,其出现的根本原因只是帮助我们解耦吗?
当然,架构能帮助我们进行解耦这是其出现的一个重要原因;但事实上更重要的是,它能够帮助我们解决特定领域在不同阶段发送的业务问题。它是伴随着一整个软件的生命周期而存在的,继而也要对应的解决每个生命周期中出现的问题。
我们软件周期包括:新生期、稳定期和老年期。
在新生期,架构要适应业务的不断膨胀问题;而在稳定期,架构则要让业务不断地重构和优化;最后到了老年期,架构要做的是如何让项目老得更慢,不要让过分臃肿的代码影响业务的正常运作。
我们可以有理想的架构,一开始就设定好来解决这些个问题,但实际上,理想总归是理想,我们要接受现实的骨感。事实上,我们很难存在一个理想的架构,因为业务是不断在变化的,变化才是软件唯一的不变点,所以架构也只能随着变化而变化,不断去解决出现的问题。
Android 的架构设计
我们可以看一下 Android 的架构设计,看看它的设计是如何解决出现的问题的。
下面的图大家都很熟悉了,这里不做详细介绍,只做简单的罗列。
- APP 层:业务代码层,在这一层实现自己的业务
- FrameWork 层:应用框架层,开发者对系统的 UI 编写,对数据的使用和调用接口,使用的都是这一层的 API
- Binder IPC:由于 Android 是有进程隔离的,所以使用 Binder 来跨进程高效通信
- 系统服务层:提供窗口、音视频、相机等能力。往下是对硬件能力的封装,往上是可以通过 Binder 暴露给其他人
- HAL 硬件抽象层:其屏蔽底层驱动的差异,使得系统服务层可以快速匹配到不同的硬件设备
- LINUX 内核层:CPU 、内存等重要的驱动服务在这一层实现。
由此,我们可以看出,Android 内部架构的设计是很有逻辑性的,底层为高层服务,越高层使用的越是定制化的内容。
不同领域的架构设计
由下图,我们可以看出在不同的端侧,其使用的语言、框架和平台都是不同的。但是在他们身上是可以找出共同点的,这些共同点是经过长期积累,抽象出来的方法论,是很值得我们学习的点。
公共的点包括:
- 编程思想:OOP、IOP、IOC 等
- 问题分解:按业务和技术分解
- 领域建模:接口设计、DSL 等
- 服务治理:模块化、组件化、容器化等
- 流程机制:敏捷开发模型、软件测试手段等
- 架构标准:公约文档,数据监测等
所以说,对于架构的设计,我们应当知晓它是不断随着需求和出现的问题不断变更优化的,且不同的架构虽有差异,但是差异之外的共同点很值得我们去学习。
值得学习的架构手段
了解了架构的作用之后,我们需要学习一些架构手段,以便解决软件生命周期中出现的各种问题。
设计模式
要做好架构设计,首先逃不掉需要学习的点及时设计模式,而设计模式又是基于设计原则来进行拓展的。学习设计模式,其最重要的就是学习其设计思想了。设计模式 - Yj家的孺子牛的专栏
而就如前文中讲过的 volatile
和 synchronize
,synchronize
中瘦锁容易被打断变成胖锁;而使用了 volatile
关键字之后就不会被打断。所以,我们认为使用了 volatile
关键字的单例模式更优。
这些对设计模式的深入使用的理解,是很容易影响到我们对架构设计的好坏的。
下文中,DoubleCheck 设计的单例模式就会相对更优些。
//LazySafe public class SingleTonTest { private static SingleTonTest instance; private SingleTonTest() { } public static synchronized SingleTonTest getInstance() { if (instance == null) { instance = new SingleTonTest(); } return instance; } } //DoubleCheck public class SingleTonTest { private static volatile SingleTonTest singleton; private SingleTonTest() { } public static SingleTonTest getInstance() { if (singleton == null) { synchronized (SingleTonTest.class) { if (singleton == null) { singleton = new SingleTonTest(); } } } return singleton; } } 复制代码