您的位置:首页 > 移动开发

一个App架构例子分析--UI层使用MVP模式;各层之间使用Otto实现通信

2015-05-17 10:42 771 查看
一、这个App整体的架构划分:



分为四大模块:

1.app模块
2.common模块
3.domain模块
4.model模块

app模块的依赖:
dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

compile project(':domain')
...
}
它依赖domain,领域层模块。在app模块中,应用了MVP模式,把一个activity中的View和Presenter划分掉。

domain模块的依赖:
dependencies {

compile project (':common')

compile project (':model')
...
}
它依赖model模块。领域逻辑代码放在这个模块;需要获取数据,获取数据的实现代码则放在module模块;它依赖common,通用的功能,整个应用共用的代码,放在common模块中。

model模块的依赖:
dependencies {

compile project(':common')
....
}
这个模块只依赖common模块。model模块提供数据获取,修改功能。

common模块的依赖:
dependencies {

compile 'com.squareup:otto:1.3.5'

compile 'com.google.dagger:dagger:2.0'

compile 'org.glassfish:javax.annotation:10.0-b28'

}
它不依赖domain,app,model模块。它使用第三方类库,来给其它模块提供功能。使用Dagger依赖注入框架,进行依赖注入;使用otto类库,来实现总线方式的通信。

二、整个执行流程简要分析



app模块:
MoviesActivity,MoviesPresenter。

domain模块:
ConfigurationUsecase, GetMoviesUsecaseController。

module模块:
RestMovieSource。

模块之间的通信,协作使用Bus总线来实现。比如,module模块,接受了数据查询的请求,查询完毕之后,它就通过总线post出去;然后,app模块或者domain模块,使用总线订阅了某个事件,那么订阅该事件的方法就会被回调。

三、依赖注入框架,注入流程

1.依赖注入流程
在MoviesActivity中,声明了一个带有注解@Inject的成员,@Inject MoviesPresenter mMoviesPresenter。这就表明当前类需要注入一个依赖mMoviesPresenter。

2.在MoviesActivity中,执行方法initializeDependencyInjector():
private void initializeDependencyInjector() {

MoviesApp app = (MoviesApp) getApplication();

DaggerBasicMoviesUsecasesComponent.builder()
.appComponent(app.getAppComponent())
.basicMoviesUsecasesModule(new BasicMoviesUsecasesModule())
.build().inject(this);
}

package com.hackvg.android.di.components;

import com.hackvg.android.di.modules.BasicMoviesUsecasesModule;
import com.hackvg.android.di.scopes.PerActivity;
import com.hackvg.android.views.activities.MoviesActivity;

import dagger.Component;

@PerActivity
@Component(dependencies = AppComponent.class, modules = BasicMoviesUsecasesModule.class)
public interface BasicMoviesUsecasesComponent {

void inject (MoviesActivity moviesActivity);
}

}

initializeDependencyInjector()方法,会生成所有相关的依赖,根据一个对象图生成依赖。编译该项目,Dagger会为BasicMoviesUsecasesComponent生成一个类DaggerBasicMoviesUsecasesComponent。在创建了Component实例后,传入需要的外部参数,AppComponent.class,BasicMoviesUsecasesModule.class,然后,再调用其中的inject方法就可以了。

@PerActivity注解表明该Component的存在的范围与当前Activity一致。

Dagger生成Component中的依赖的流程:
1.BasicMoviesUsecasesModule,描述了依赖 ConfigurationUsecase, ConfigurationUsecase的生成

package com.hackvg.android.di.modules;

import com.hackvg.domain.ConfigurationUsecase;
import com.hackvg.domain.ConfigurationUsecaseController;
import com.hackvg.domain.GetMoviesUsecase;
import com.hackvg.domain.GetMoviesUsecaseController;
import com.hackvg.model.rest.RestMovieSource;
import com.squareup.otto.Bus;

import dagger.Module;
import dagger.Provides;

@Module
public class BasicMoviesUsecasesModule {

@Provides ConfigurationUsecase provideConfigurationUsecase (Bus bus, RestMovieSource moviesSource) {
return new ConfigurationUsecaseController(moviesSource, bus);
}

@Provides GetMoviesUsecase provideMoviesUsecase (Bus bus, RestMovieSource movieSource) {
return new GetMoviesUsecaseController(movieSource, bus);
}
}

2.生成上述两个依赖,需要提供参数Bus, RestMovieSource,那么,根据Dagger规定,这两个参数也要执行依赖注入。这两个依赖由AppComponent.Class来提供:
该AppComponent实例是单例的,它提供了两个依赖的生成Bus, RestMovieSource。

AppComponent:

package com.hackvg.android.di.components;

import com.hackvg.android.di.modules.ApplicationModule;
import com.hackvg.android.di.modules.DomainModule;
import com.hackvg.model.rest.RestMovieSource;
import com.squareup.otto.Bus;

import javax.inject.Singleton;

import dagger.Component;

@Singleton
@Component(modules = {
ApplicationModule.class,
DomainModule.class,
})

public interface AppComponent {

Bus bus();
RestMovieSource restMovieSource();
}

DomainModule:描述了依赖Bus,RestMoviesSource的生成。

package com.hackvg.android.di.modules;

import com.hackvg.model.rest.RestMovieSource;
import com.squareup.otto.Bus;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;

@Module
public class DomainModule {

@Provides @Singleton Bus provideBus () {
return new Bus();
}

@Provides @Singleton RestMovieSource provideDataSource (Bus bus) { return new RestMovieSource(bus); }

}

参考资料: https://github.com/saulmm/Material-Movies
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐