zoukankan      html  css  js  c++  java
  • 一个App架构例子分析--UI层使用MVP模式;各层之间使用Otto实现通信

    一、这个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
     
  • 相关阅读:
    Spring MVC系列-(5) AOP
    Spring MVC系列-(4) Bean的生命周期
    Spring MVC系列-(3) Bean的装配
    Spring MVC系列-(2) Bean的装配
    Spring MVC系列-(1) Spring概述
    JVM性能优化系列-(7) 深入了解性能优化
    JVM性能优化系列-(6) 晚期编译优化
    pycharm下载较快地址
    编程学习记录14:Oracle数据库序列,触发器
    编程学习记录13:Oracle数据库,表的查询
  • 原文地址:https://www.cnblogs.com/ttylinux/p/4509262.html
Copyright © 2011-2022 走看看