Slide 1

Slide 1 text

%BHHFS ͱ #VJME7BSJBOUT ๺ଜɹྋ

Slide 2

Slide 2 text

ࣗݾ঺հ w ๺ଜɹྋ w ͸ͯͳJEGVOOFMCJU w 5XJUUFSJEFYQFSPQFSP

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

͸ͯͳϒοΫϚʔΫ

Slide 5

Slide 5 text

%BHHFS #VJME7BSJBOUT

Slide 6

Slide 6 text

%BHHFS w IUUQHPPHMFHJUIVCJPEBHHFS w %*ίϯςφ w "15࢖ͬͯίϯύΠϧ࣌ʹґଘղܾ

Slide 7

Slide 7 text

#VJME7BSJBOUT w #VJME5ZQFT1SPEVDU'MBWPST

Slide 8

Slide 8 text

HSBEF productFlavors {
 typea {
 applicationId "com.funnelbit.testablediconceptapplication.typea"
 }
 typeb {
 applicationId "com.funnelbit.testablediconceptapplication.typeb"
 }
 }

Slide 9

Slide 9 text

TSDNBJOKBWB TSDUZQFBKBWB TSDUZQFCKBWB

Slide 10

Slide 10 text

TSDNBJOKBWB

Slide 11

Slide 11 text

"QQ$PNQPOFOU#BTF public interface AppComponentBase {
 // App
 void inject(App app);
 // Activity
 void inject(MainActivity mainActivity);
 }

Slide 12

Slide 12 text

"QJ$MJFOU public interface ApiClient {
 void request(String query, Callback callback);
 
 class Response {
 public final String body;
 public Response(String body) { this.body = body; }
 }
 
 interface Callback {
 void onSuccess(Response response);
 void onFail(Exception e);
 }
 }

Slide 13

Slide 13 text

&OUSZ.BOBHFS public class EntryManager {
 final ApiClient mApiClient;
 @Inject EntryManager(ApiClient apiClient) {
 mApiClient = apiClient;
 }
 
 public void create() {
 mApiClient.request("create query", new ApiClient.Callback() { …
 });
 }
 
 public void delete() {
 mApiClient.request("delete query", new ApiClient.Callback() {
 …
 });
 }
 }

Slide 14

Slide 14 text

.BJO"DUJWJUZ public class MainActivity extends AppCompatActivity {
 @Inject EntryManager mEntryManager;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 ((App) getApplication()).getAppComponent().inject(this);
 setContentView(R.layout.activity_main);
 
 mEntryManager.create();
 mEntryManager.delete();
 }
 }

Slide 15

Slide 15 text

TSDUZQFBKBWB

Slide 16

Slide 16 text

"QQ$PNQPOFOU @Component(modules = AppModule.class)
 public interface AppComponent extends AppComponentBase {
 }

Slide 17

Slide 17 text

"QQ.PEVMF @Module
 public class AppModule {
 @Provides
 public ApiClient provideApiClient() {
 return new AppClientImpl();
 }
 }

Slide 18

Slide 18 text

"QQ public class App extends Application {
 private AppComponent mAppComponent;
 @Override
 public void onCreate() {
 super.onCreate();
 mAppComponent = DaggerAppComponent.builder()
 .appModule(new AppModule())
 .build();
 }
 
 public AppComponent getAppComponent() {
 return mAppComponent;
 }
 }

Slide 19

Slide 19 text

"QQ$MJFOU*NQM public class AppClientImpl implements ApiClient {
 @Override
 public void request(String query, Callback callback) {
 callback.onSuccess(new Response("production response"));
 }
 }

Slide 20

Slide 20 text

TSDUZQFCKBWB

Slide 21

Slide 21 text

"QQ$PNQPOFOU @Component(modules = {StubAppModule.class, DebugModule.class})
 public interface AppComponent extends AppComponentBase {
 }

Slide 22

Slide 22 text

4UVC"QQ.PEVMF @Module
 public class StubAppModule {
 @Provides
 public ApiClient provideApiClient() {
 return new StubApiClient();
 }
 }

Slide 23

Slide 23 text

"QQ public class App extends Application {
 private AppComponent mAppComponent;
 @Inject LogUtil mLogUtil;
 @Override
 public void onCreate() {
 super.onCreate();
 mAppComponent = DaggerAppComponent.builder()
 .stubAppModule(new StubAppModule())
 .debugModule(new DebugModule())
 .build();
 
 mAppComponent.inject(this);
 mLogUtil.debugLog("͜Μʹͪ͸");
 }
 public AppComponent getAppComponent() {
 return mAppComponent;
 }
 }

Slide 24

Slide 24 text

ߏ੒·ͱΊ w ڞ௨ͯ͠࢖͏΋ͷ͸NBJOʹ͔͘ w ৼΔ෣͍Λม͍͑ͨ৔߹͸*OKFDU w "QQ͸NBJOʹஔ͔ͳ͍ w $PNQPOFOU͸NBJOͷ֎ w .PEVMF͸NBJOҎ֎ͷ֎

Slide 25

Slide 25 text

·ͱΊ w ࿩͕͍ͨ͠Ͱ͢ w ͲΜͳײ͡Ͱಋೖ͍ͯ͠Δ͔ w ςετͷ࣌Ͳ͏ͯ͠Δ͔

Slide 26

Slide 26 text

͋Γ͕ͱ͏͍͟͝·ͨ͠