好像相对于上面那张图更好理解,知道为什么吗?因为字少了好多。哈哈。接下来的内容以及我的开源项目中都是以此为基础来写的。分别来解释下。
我们这里的表现层以MVP为基础,个人觉得Clean本身也是MVP的基础上更加抽象,更加独立。熟悉的MVP的同学非常清楚这一层是干嘛用的。老规矩,先上张图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e4exjVTX-1631769638694)(https://user-gold-cdn.xitu.io/2017/9/27/ccccf90377a0baa49d63141cdd1a487f?imageView2/0/w/1280/h/960/ignore-error/1)]
是不是很眼熟?P层使得V层(Fragment和Activity)内部除UI逻辑再无其它逻辑。而我的开源项目中的Presenter由多个Interactor组成。底下会介绍。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tfzj2mCT-1631769638696)(https://user-gold-cdn.xitu.io/2017/9/27/1950f115073f471ca4b9beb4bc4f88cc?imageView2/0/w/1280/h/960/ignore-error/1)]
图上很明显了,这里主要是interactor的实现类和业务对象。讲道理这里应该只属于java模块,但是有时候我们的业务对象,可能要实现第三方库中的实体类接口,不得不改为Android模块,暂时没想到很好的办法,有知道的大佬可以指教一下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qGrNcV00-1631769638697)(https://user-gold-cdn.xitu.io/2017/9/27/797ee7d22b857162e258f0432d996c08?imageView2/0/w/1280/h/960/ignore-error/1)]
这是一种Repository模式,具体的可以看[这里](
)。以我现在的见解,只能说只要项目复杂而需要分层,那么就应该用这个模式,它让clean架构的clean更加亮眼。
这个本来就是概念,我相信大家也不愿意看,所以就简单介绍。如果想详细了解,可以戳[这里](
)。
现在谈谈自己的看法,后者是相对前者较为具体的一种符合Android的结构。在这插一个clean架构的依赖性规则:内层不能依赖外层。三者也都分别解释了是干什么用的,那么为什么有分为这三者,它们又有什么联系?我是个俗人,那就应该用俗话来讲,从数据层利用Repository模式让领域层感觉不到数据访问层的存在,即原始数据是独立的,业务规则不绑定具体哪一种数据,通俗点讲就是你要什么数据?我给你取,但你不需要知道我从哪里取的;因此领域层对数据层怎么实现的是一无所知,而领域层主要工作就是你给了我数据,那我就要用,怎么用?都是我来决定;用完之后再回调给表现层渲染UI。因此大多数的业务逻辑都在领域层,可以说是一个APP的核心。我认为这里透露着一个很重要的设计理念就是数据驱动UI,我都想给自己点个赞,哈哈。其实,到这里,你心里已经有点13数的话,可以跳到Why,因为怎么用已经是具体的东西,而架构本身就是一种共识,是抽象的,从Java角度讲你可以多个类去实现这个接口。下面的使用只是我对Clean架构理解的一点代码体现。
下面的例子是从我开源库[CrazyDaily](
)中选取的,以知乎日报为例。
数据层就是从我们的仓库(Repository)中取数据,可以从云端、磁盘或者内存中取。
public interface ZhihuService {
String HOST = "http://news-at.zhihu.com/api/4/";
@GET("news/latest")
Flowable getZhihuNewsList();
@GET("news/{id}")
Flowable getZhihuNewsDetail(@Path("id") long id);
}
public class ZhihuDataRepository implements ZhihuRepository {
...
@Inject
public ZhihuDataRepository(HttpHelper httpHelper) {
mZhihuService = httpHelper.getZhihuService();
}
@Override
public Flowable getZhihuNewsList() {
return mZhihuService.getZhihuNewsList()
...
}
...
}
这里比较尴尬的是只提供了云端的数据,采用的是retrofit+okhttp的框架获取。比较正确的方式应该是给ZhihuDataRepository提供一个Factory而不是HttpHelper,Factory根据不同的条件获取相应的数据。比如像这样:
@Inject
UserDataRepository(UserDataStoreFactory dataStoreFactory,
UserEntityDataMapper userEntityDataMapper) {
this.userDataStoreFactory = dataStoreFactory;
this.userEntityDataMapper = userEntityDataMapper;
}
UserDataStoreFactory是从不同地方获取数据的一个工厂类,UserEntityDataMapper是我们的数据包装类,不知道还记得上面的Interface Adapters吗?细心的朋友可以关注到ZhihuDataRepository实现了ZhihuRepository,但是ZhihuRepository并非数据层的东西,而是领域层的东西,很显然,以接口进行关联,但内容独立,没错,这就是传说中的依赖倒置原则。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jJbjSqEL-1631769638699)(https://user-gold-cdn.xitu.io/2017/9/27/f6374b51c60eeaf235aea664d94309b3?imageView2/0/w/1280/h/960/ignore-error/1)]
public interface ZhihuRepository {
Flowable getZhihuNewsList();
Flowable getZhihuNewsDetail(long id);
}
public abstract class UseCase {
...
public UseCase() {
...
}
protected abstract Flowable buildUseCaseObservable(Params params);
public void execute(Params params, DisposableSubscriber subscriber) {
...
}
...
}
public class ZhihuNewsListUseCase extends UseCase {
private final ZhihuRepository mZhihuRepository;
@Inject
public ZhihuNewsListUseCase(ZhihuRepository zhihuRepository) {
mZhihuRepository = zhihuRepository;
}
@Override
protected Flowable buildUseCaseObservable(Void aVoid) {
return mZhihuRepository.getZhihuNewsList()
...
}
}
真的很完美,跟数据层一毛线关系都没有,利用接口(ZhihuRepository)来控制数据层(ZhihuDataRepository)。真的感觉架构越来越有意思了。我可以在这里处理我们大部分的业务逻辑。
@ActivityScope
public class HomePresenter extends BasePresenter implements HomeContract.Presenter {
private ZhihuNewsListUseCase mZhihuUseCase;
...
@Inject //多个UseCase
public HomePresenter(ZhihuNewsListUseCase zhihuUseCase ...) {
mZhihuUseCase = zhihuUseCase;
...
}
@Override
public void getZhihuNewsList() {
mZhihuUseCase.execute(new BaseSubscriber() {
@Override
public void onNext(ZhihuNewsEntity zhihuNewsEntity) {
mView.showZhihu(zhihuNewsEntity);
}
});
}
}
public interface HomeContract {
interface View extends IView {
void showZhihu(ZhihuNewsEntity zhihuNewsEntity);
...
}
interface Presenter extends IPresenter {
void getZhihuNewsList();
...
}
### 文末
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](
)**
**进阶学习视频**
![](https://img-blog.csdnimg.cn/img_convert/4f1488144bf0e4b377a004e20d7afd84.png)
**附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题** (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
![](https://img-blog.csdnimg.cn/img_convert/4751e4d1c7abe41f7e66927ee4fbee1c.png)
*附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题** (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中...(img-KJbjb1Ud-1631769638702)]