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
     
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
  • 原文地址:https://www.cnblogs.com/ttylinux/p/4509262.html
Copyright © 2011-2022 走看看