前言
由于CSDN在移动端的UI界面不太友好,现在把博客迁到简书。
原来CSDN博客地址:http://blog.csdn.net/iigeoxiaoyang
Clean Architecture 架构模式很早之前就提出了,Fernando Cejas在Github上实现了Android下的Clean Architecture项目。本文主要根据这个项目源码以及我们项目中的实践说说对这个架构的理解。
一 Clean Architecture
Uncle Bob 2012年在自己的博客里面提出了Clean Architecture模式,他对这个架构模式的主要思想描述如下:
- Independent of Frameworks.(框架独立)
- Testable.(容易测试)
- Independent of UI.(UI独立)
- Independent of Database.(数据库独立)
- Independent of any external agency.(外部机制独立)
下面是一张这个架构的模式图,类似于"剥洋葱"的方式
clean architecture 架构图.png
如上图所示,最外层以此依赖于内层,Entities实体数据层的数据传递给UseCases层(业务逻辑层),Presenters层将业务层逻辑封装给UI层调用。
二 Android Clean Architecture
Fernando Cejas 2014年根据Uncle Bob的思想设计实现了Android端的Clean Architecture模式,主要分为三层Data Layer,Domain Layer ,Presentation Layer。
另外,Fernando Cejas 在GithHub上创建了一个Android 10项目(https://github.com/android10/Android-CleanArchitecture),
这个项目结合Retrofit+RxJava+MVP实现了clean architecture的思想。先放一副实现思路图。
响应式clean architecture架构图.png 详细说明一下上图的实现思路:
- 1 Data layer
集合Retrofit框架从服务端获取Restful API,根据不同的接口分别创建RxJAVA的被观察者对象(这个对象提供给Domain层,进行流式操作)。service实现方式如下:
@GET("api/v1/users/all?")
Observable<UsersModel> getAllUsers(@Query("lastUpdateTime") final int lastUpdateTime);
然后通过Repository暴露service给dimain层,repository实现如下:
Observable<UsersModel> getAllUsers(final int lastUpdateTime);
- 2 Domain layer
利用RxJAVA实现data层返回的Observable订阅Presentation层传入的的Subscriber对象(该对象在persenter层创建)实现业务逻辑,实现如下:
public abstract class UseCase {
private final ThreadExecutor threadExecutor;
private final PostExecutionThread postExecutionThread;
private Subscription subscription = Subscriptions.empty();
protected UseCase(ThreadExecutor threadExecutor,
PostExecutionThread postExecutionThread) {
this.threadExecutor = threadExecutor;
this.postExecutionThread = postExecutionThread;
}
//获取data layer层Observable对象
protected abstract Observable buildUseCaseObservable();
//实现订阅,并创建事件发生线程,Observable对象创建在子线程,Subscriber对象创建在主线程
public void execute(Subscriber UseCaseSubscriber) {
this.subscription = this.buildUseCaseObservable()
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.getScheduler())
.subscribe(UseCaseSubscriber);
}
//解除订阅
public void unsubscribe() {
if (!subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
- 3 Presentation Layer
这里创建Subscriber对象传入到domain层观察Observable对象发送的事件。由于Model已经在Data层声明,所以这一层去掉MVP中的ModeL层,定义view接口(Activity实现该接口)
,定义presenter类创建subsciber对象,获取domain层传递的服务端数据对象。
private final class UserListPresenter extends DefaultSubscriber<UsersModel> {
@Override
public void onCompleted() {
UserListPresenter.this.hideViewLoading();
}
@Override
public void onError(Throwable e) {
//异常错误处理
UserListPresenter.this.hideViewLoading();
UserListPresenter.this.showErrorMessage(new DefaultErrorBundle((Exception) e));
UserListPresenter.this.showViewRetry();
}
@Override
public void onNext(UsersModel users) {
//返回数据供Activity中调用
UserListPresenter.this.showUsersCollectionInView(users);
}
}
//定义view接口
showUsersCollectionInView(users);
三 Dagger2注解框架集成
最后我们集成Dagger2框架,实现依赖注入,关于Dagger2依赖注入框架的基础概念和原理就不说了,我个人理解的也是不是很深刻,阅读本文后面的内容请先看牛晓伟同志的三篇文章:
Android:dagger2让你爱不释手-基础依赖注入框架篇
Android:dagger2让你爱不释手-重点概念讲解、融合篇
Android:dagger2让你爱不释手-终结篇
我们的Clean Architecture架构的Component(目标依赖类和目标类之间的桥梁)设计如下图:
遵循以下原则:
- 一个app必须要有一个Component(ApplicationComponent)用来管理app的整个全局类实例;
- 注射器依赖关系为:ActivityComponent 依赖 ApplicationComponent, UserComponent依赖ApplicationComponent
- 利用Name(Qualifier的默认实现)解决一个实例被多种方式构建依赖迷失问题;
- 利用Singleton(Scope的一个默认实现)匹配Module和Comopnent;
下面以注入UserPresenter到UserActivity为例,说明Android clean architecture 下的dagger2注入流程,流程图如下:
android clean Architecture dagger2图.png
总结
这一部分内容的理解还不是深刻,后续根据理解修改,只作为个人笔记。
参考文献
1.https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html (Uncle Bob 清洁架构)
2.https://fernandocejas.com/2015/07/18/architecting-android-the-evolution/ (Fernando Cejas架构英文)
3.http://xuyushi.github.io/2016/07/20/Architecting%20Android%E2%80%A6The%20evolution/ (Fernando Cejas架构中文翻译)
4.https://fernandocejas.com/2015/04/11/tasting-dagger-2-on-android/
网友评论