May 10, 2015
{concept}Inversion of Control (IoC)
{concept}Dependency Injection (DI)
Googe Guice
RoboGuice DaggerAndroid
Annotations
PicoContainer PlexusSpring core
Dependency Injection (DI)
Makes code ...● more concise ● more modular● easier to test
@ContentView(R.layout.main)public class GuicyActivity extends RoboActivity {
public class GuicelessActivity extends Activity {…@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
@InjectView(R.id.text_output) TextView outputText;
...TextView outputText;...outputText =(TextView)findViewById(R.id.text_output);
@InjectView(R.id.text_output) TextView outputText;
String appName;...appName = getString(R.string.app_name);
@Inject SensorManager sensorManager;
SensorManager sensorManager;...sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
SomeController someController;..someController = new SomeController(this);
public class SomeController { Activity hostActivity;
@Inject public SomeController(Activity hostActivity) { this.hostActivity = hostActivity; }}
@Inject SomeController someController;
@ContentView(R.layout.main)public class GuicyActivity extends RoboActivity { @InjectView(R.id.text_output) TextView outputText; @InjectResource(R.string.app_name) String appName; @Inject SensorManager sensorManager; @Inject SomeController someController;}
public class GuicelessActivity extends Activity { TextView outputText; String appName; SensorManager sensorManager; SomeController someController;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); outputText = (TextView)findViewById(R.id.text_output); appName = getString(R.string.app_name); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); someController = new SomeController(this); }}
15 LOC → 7 LOC
= more concisene
Dependency Injection (DI)
Makes code ...● more concise ● more modular● easier to test
Bindings
public class MyModule extends AbstractModule {
@Override protected void configure() { // custom binding go here }}
bind(ISomeService.class).to(SomeServiceDummy.class);
bind(ISomeService.class).toInstance(new SomeServiceReal("yes", 1));
@Inject@Providespublic AnotherService provideAnotherService(
ISomeService someService) { return new AnotherService(someService, "bla");}
Bindings allows for
● wiring up components● configuring components
Adding Google Analytics to an Activity● onCreate → startNewSession● onResume → trackPageView● onDestroy → stopSession● Attributes● Support code
Component Bloat-Up● anti pattern: God Class● low coherence● tight coupling● low separation of concernes
public void onCreate(@Observes OnCreateEvent onCreateEvent)
@Inject protected AnalyticsMixin analyticsMixin;
We get:● loose coupling● high coherence● centralized wiring● centralized configuration
Testability (see wikipedia)● controllability: The degree to which it is possible to control the state of the
component under test (CUT) as required for testing.
● observability: The degree to which it is possible to observe (intermediate and final) test results.
● isolateability: The degree to which the CUT can be tested in isolation.
● separation of concerns: The degree to which the CUT has a single, well defined responsibility.
● understandability: The degree to which the CUT is documented or self-explaining.
● automatability: The degree to which it is possible to automate testing of the CUT.
● heterogeneity: The degree to which the use of diverse technologies requires to use diverse test methods and tools in parallel.
@RunWith(RobolectricTestRunner.class)public class SomeServiceTest { @Mock private SomeDAO mockDao; @Mock private Logger mockLogger;
private SomeService cut;
@Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); cut.someDao = mockDao; cut.log = mockLogger; }
@Test public void testExecute_willPassWhenNotInBeta() { when(mockDao.countSomeStuff()).thenReturn(23); assertTrue(cut.hasEnoughStuff()); verify(mockLogger, times(1)).info("have 23"); }}
Testability (see wikipedia)● controllability ++● observability ++● isolateability ++● separation of concerns ++● understandability +● automatability +● heterogeneity o
Dependency Injection (DI)
Makes code ...● more concise ● more modular● easier to test
References:● DI: http://martinfowler.com/articles/injection.html● Guice: http://code.google.com/p/google-guice/● RoboGuice: https://github.com/roboguice/roboguice● Testability:
http://en.wikipedia.org/wiki/Software_testability● Mockito: http://code.google.com/p/mockito/● Rebolectric: http://pivotal.github.io/robolectric/
Contact:● [email protected]● @tom___b● http://play.google.com → GrooveGrid