带你领略Clean架构的魅力,腾讯T3大佬亲自讲解

好像相对于上面那张图更好理解,知道为什么吗?因为字少了好多。哈哈。接下来的内容以及我的开源项目中都是以此为基础来写的。分别来解释下。

表现层 (Presentation Layer)

我们这里的表现层以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组成。底下会介绍。

领域层 (Domain Layer)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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模块,暂时没想到很好的办法,有知道的大佬可以指教一下。

数据层 (Data Layer)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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架构理解的一点代码体现。

How

下面的例子是从我开源库[CrazyDaily](

)中选取的,以知乎日报为例。

数据层 (Data Layer)

数据层就是从我们的仓库(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)]

领域层 (Domain Layer)

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)。真的感觉架构越来越有意思了。我可以在这里处理我们大部分的业务逻辑。

表现层 (Presentation Layer)

@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)]

你可能感兴趣的:(Android,android,java,移动开发)