diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 508b3d9..7ac24c7 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -11,12 +11,7 @@ - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b2769db..a94d95a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,15 +1,15 @@ - - + diff --git a/app/src/main/java/upday/mvpvsmvvm/datamodel/IDataModel.java b/app/src/main/java/upday/mvpvsmvvm/datamodel/IDataModel.java deleted file mode 100644 index f0319c6..0000000 --- a/app/src/main/java/upday/mvpvsmvvm/datamodel/IDataModel.java +++ /dev/null @@ -1,12 +0,0 @@ -package upday.mvpvsmvvm.datamodel; - -import android.support.annotation.NonNull; - -import rx.Observable; - -public interface IDataModel { - - @NonNull - Observable getGreeting(); - -} diff --git a/app/src/main/java/upday/mvpvsmvvm/DroidconApplication.java b/app/src/main/java/upday/patterns/DroidconApplication.java similarity index 75% rename from app/src/main/java/upday/mvpvsmvvm/DroidconApplication.java rename to app/src/main/java/upday/patterns/DroidconApplication.java index 40fc100..dccf6d8 100644 --- a/app/src/main/java/upday/mvpvsmvvm/DroidconApplication.java +++ b/app/src/main/java/upday/patterns/DroidconApplication.java @@ -1,10 +1,10 @@ -package upday.mvpvsmvvm; +package upday.patterns; import android.app.Application; import android.support.annotation.NonNull; -import upday.mvpvsmvvm.datamodel.DataModel; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.datamodel.DataModel; +import upday.patterns.datamodel.IDataModel; public class DroidconApplication extends Application { diff --git a/app/src/main/java/upday/mvpvsmvvm/datamodel/DataModel.java b/app/src/main/java/upday/patterns/datamodel/DataModel.java similarity index 51% rename from app/src/main/java/upday/mvpvsmvvm/datamodel/DataModel.java rename to app/src/main/java/upday/patterns/datamodel/DataModel.java index 687c613..4687f86 100644 --- a/app/src/main/java/upday/mvpvsmvvm/datamodel/DataModel.java +++ b/app/src/main/java/upday/patterns/datamodel/DataModel.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.datamodel; +package upday.patterns.datamodel; import android.support.annotation.NonNull; @@ -8,7 +8,13 @@ public class DataModel implements IDataModel { @NonNull @Override - public Observable getGreeting() { + public Observable getGreetingAsync() { return Observable.just("Hello, World!"); } + + @NonNull + @Override + public String getGreetingSync() { + return "Hello World"; + } } diff --git a/app/src/main/java/upday/patterns/datamodel/IDataModel.java b/app/src/main/java/upday/patterns/datamodel/IDataModel.java new file mode 100644 index 0000000..4e0c23b --- /dev/null +++ b/app/src/main/java/upday/patterns/datamodel/IDataModel.java @@ -0,0 +1,24 @@ +package upday.patterns.datamodel; + +import android.support.annotation.NonNull; + +import rx.Observable; + +/** + * The Data Model used by all patterns + */ +public interface IDataModel { + + /** + * @return a stream of the greeting. The stream will emit once and then complete. + * Allows asynchronous retrieval of the greeting. + */ + @NonNull + Observable getGreetingAsync(); + + /** + * @return a greeting synchronously. + */ + @NonNull + String getGreetingSync(); +} diff --git a/app/src/main/java/upday/patterns/mvc/Controller.java b/app/src/main/java/upday/patterns/mvc/Controller.java new file mode 100644 index 0000000..91616da --- /dev/null +++ b/app/src/main/java/upday/patterns/mvc/Controller.java @@ -0,0 +1,17 @@ +package upday.patterns.mvc; + +import android.support.annotation.NonNull; + +/** + * Implementation class for the Controller in the MVC pattern, with a passive model. + */ +public class Controller { + + @NonNull + private final IView mView; + + public Controller(@NonNull final IView view) { + mView = view; + mView.update(); + } +} diff --git a/app/src/main/java/upday/patterns/mvc/IView.java b/app/src/main/java/upday/patterns/mvc/IView.java new file mode 100644 index 0000000..41fb805 --- /dev/null +++ b/app/src/main/java/upday/patterns/mvc/IView.java @@ -0,0 +1,9 @@ +package upday.patterns.mvc; + +/** + * A view that can update. + */ +public interface IView { + + void update(); +} diff --git a/app/src/main/java/upday/patterns/mvc/MVCActivity.java b/app/src/main/java/upday/patterns/mvc/MVCActivity.java new file mode 100644 index 0000000..e791c13 --- /dev/null +++ b/app/src/main/java/upday/patterns/mvc/MVCActivity.java @@ -0,0 +1,53 @@ +package upday.patterns.mvc; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.widget.TextView; + +import upday.patterns.DroidconApplication; +import upday.patterns.R; +import upday.patterns.datamodel.IDataModel; + +/** + * Implements the view class of the MVC pattern with passive model. + */ +public class MVCActivity extends AppCompatActivity implements IView { + + @NonNull + private Controller mController; + + @NonNull + private IDataModel mDataModel; + + @Nullable + private TextView mGreetingView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mDataModel = getDataModel(); + mController = new Controller(this); + + setupViews(); + } + + private void setupViews() { + mGreetingView = (TextView) findViewById(R.id.greeting); + } + + @Override + public void update() { + assert mGreetingView != null; + mGreetingView.setText(mDataModel.getGreetingSync()); + } + + @NonNull + private IDataModel getDataModel() { + return ((DroidconApplication) getApplication()).getDataModel(); + } + +} diff --git a/app/src/main/java/upday/mvpvsmvvm/mvp/IPresenter.java b/app/src/main/java/upday/patterns/mvp/IPresenter.java similarity index 82% rename from app/src/main/java/upday/mvpvsmvvm/mvp/IPresenter.java rename to app/src/main/java/upday/patterns/mvp/IPresenter.java index bde1493..f143584 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvp/IPresenter.java +++ b/app/src/main/java/upday/patterns/mvp/IPresenter.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.mvp; +package upday.patterns.mvp; /** * Interface for the Presenter class in the MVP pattern. diff --git a/app/src/main/java/upday/mvpvsmvvm/mvp/IView.java b/app/src/main/java/upday/patterns/mvp/IView.java similarity index 75% rename from app/src/main/java/upday/mvpvsmvvm/mvp/IView.java rename to app/src/main/java/upday/patterns/mvp/IView.java index feab086..f4e917e 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvp/IView.java +++ b/app/src/main/java/upday/patterns/mvp/IView.java @@ -1,11 +1,11 @@ -package upday.mvpvsmvvm.mvp; +package upday.patterns.mvp; import android.support.annotation.NonNull; /** * Interface for the view classes in the MVP pattern. */ -public interface IView { +interface IView { void setGreeting(@NonNull final String greeting); } diff --git a/app/src/main/java/upday/mvpvsmvvm/mvp/MVPActivity.java b/app/src/main/java/upday/patterns/mvp/MVPActivity.java similarity index 89% rename from app/src/main/java/upday/mvpvsmvvm/mvp/MVPActivity.java rename to app/src/main/java/upday/patterns/mvp/MVPActivity.java index 002330c..114a256 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvp/MVPActivity.java +++ b/app/src/main/java/upday/patterns/mvp/MVPActivity.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.mvp; +package upday.patterns.mvp; import android.os.Bundle; import android.support.annotation.NonNull; @@ -6,9 +6,9 @@ import android.support.v7.app.AppCompatActivity; import android.widget.TextView; -import upday.mvpvsmvvm.DroidconApplication; -import upday.mvpvsmvvm.R; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.DroidconApplication; +import upday.patterns.R; +import upday.patterns.datamodel.IDataModel; /** * Implements the view class of the MVP pattern. diff --git a/app/src/main/java/upday/mvpvsmvvm/mvp/Presenter.java b/app/src/main/java/upday/patterns/mvp/Presenter.java similarity index 87% rename from app/src/main/java/upday/mvpvsmvvm/mvp/Presenter.java rename to app/src/main/java/upday/patterns/mvp/Presenter.java index 21a0a9f..148e8b7 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvp/Presenter.java +++ b/app/src/main/java/upday/patterns/mvp/Presenter.java @@ -1,9 +1,9 @@ -package upday.mvpvsmvvm.mvp; +package upday.patterns.mvp; import android.support.annotation.NonNull; import rx.subscriptions.CompositeSubscription; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.datamodel.IDataModel; /** * Implementation class for the Presenter in the MVP model. @@ -28,7 +28,7 @@ public Presenter(@NonNull final IDataModel dataModel, public void bind() { mSubscription = new CompositeSubscription(); - mSubscription.add(mDataModel.getGreeting() + mSubscription.add(mDataModel.getGreetingAsync() .subscribe(this::setGreeting)); } diff --git a/app/src/main/java/upday/mvpvsmvvm/mvvm/MVVMActivity.java b/app/src/main/java/upday/patterns/mvvm/MVVMActivity.java similarity index 91% rename from app/src/main/java/upday/mvpvsmvvm/mvvm/MVVMActivity.java rename to app/src/main/java/upday/patterns/mvvm/MVVMActivity.java index 2d51247..a6bf541 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvvm/MVVMActivity.java +++ b/app/src/main/java/upday/patterns/mvvm/MVVMActivity.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.mvvm; +package upday.patterns.mvvm; import android.os.Bundle; import android.support.annotation.NonNull; @@ -7,9 +7,9 @@ import android.widget.TextView; import rx.subscriptions.CompositeSubscription; -import upday.mvpvsmvvm.DroidconApplication; -import upday.mvpvsmvvm.R; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.DroidconApplication; +import upday.patterns.R; +import upday.patterns.datamodel.IDataModel; public class MVVMActivity extends AppCompatActivity { diff --git a/app/src/main/java/upday/mvpvsmvvm/mvvm/ViewModel.java b/app/src/main/java/upday/patterns/mvvm/ViewModel.java similarity index 75% rename from app/src/main/java/upday/mvpvsmvvm/mvvm/ViewModel.java rename to app/src/main/java/upday/patterns/mvvm/ViewModel.java index 34b5ea9..34f1698 100644 --- a/app/src/main/java/upday/mvpvsmvvm/mvvm/ViewModel.java +++ b/app/src/main/java/upday/patterns/mvvm/ViewModel.java @@ -1,9 +1,9 @@ -package upday.mvpvsmvvm.mvvm; +package upday.patterns.mvvm; import android.support.annotation.NonNull; import rx.Observable; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.datamodel.IDataModel; /** * View model for the main activity. @@ -19,6 +19,6 @@ public ViewModel(@NonNull final IDataModel dataModel) { @NonNull public Observable getGreeting() { - return mDataModel.getGreeting(); + return mDataModel.getGreetingAsync(); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ea303c1..8f68b4a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - MVP vs MVVM + UI Architecture Patterns diff --git a/app/src/test/java/upday/patterns/mvc/ControllerTest.java b/app/src/test/java/upday/patterns/mvc/ControllerTest.java new file mode 100644 index 0000000..f7d313e --- /dev/null +++ b/app/src/test/java/upday/patterns/mvc/ControllerTest.java @@ -0,0 +1,30 @@ +package upday.patterns.mvc; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** + * Class that tests the implementation of {@link Controller} + */ +public class ControllerTest { + + @Mock + private IView mView; + + private Controller mController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void updateCalled_whenControllerCreated() { + mController = new Controller(mView); + + Mockito.verify(mView).update(); + } +} diff --git a/app/src/test/java/upday/mvpvsmvvm/mvp/PresenterTest.java b/app/src/test/java/upday/patterns/mvp/PresenterTest.java similarity index 80% rename from app/src/test/java/upday/mvpvsmvvm/mvp/PresenterTest.java rename to app/src/test/java/upday/patterns/mvp/PresenterTest.java index 1da10fe..a0a4673 100644 --- a/app/src/test/java/upday/mvpvsmvvm/mvp/PresenterTest.java +++ b/app/src/test/java/upday/patterns/mvp/PresenterTest.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.mvp; +package upday.patterns.mvp; import org.junit.Before; import org.junit.Test; @@ -7,7 +7,7 @@ import org.mockito.MockitoAnnotations; import rx.Observable; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.datamodel.IDataModel; public class PresenterTest { @@ -29,7 +29,7 @@ public void setUp() throws Exception { @Test public void testGetGreeting_set_whenViewBinded() { String greeting = "Hello!"; - Mockito.when(mDataModel.getGreeting()).thenReturn(Observable.just(greeting)); + Mockito.when(mDataModel.getGreetingAsync()).thenReturn(Observable.just(greeting)); mPresenter.bind(); diff --git a/app/src/test/java/upday/mvpvsmvvm/mvvm/ViewModelTest.java b/app/src/test/java/upday/patterns/mvvm/ViewModelTest.java similarity index 82% rename from app/src/test/java/upday/mvpvsmvvm/mvvm/ViewModelTest.java rename to app/src/test/java/upday/patterns/mvvm/ViewModelTest.java index 6f2a82c..4a9a141 100644 --- a/app/src/test/java/upday/mvpvsmvvm/mvvm/ViewModelTest.java +++ b/app/src/test/java/upday/patterns/mvvm/ViewModelTest.java @@ -1,4 +1,4 @@ -package upday.mvpvsmvvm.mvvm; +package upday.patterns.mvvm; import org.junit.Before; import org.junit.Test; @@ -8,7 +8,7 @@ import rx.Observable; import rx.observers.TestSubscriber; -import upday.mvpvsmvvm.datamodel.IDataModel; +import upday.patterns.datamodel.IDataModel; public class ViewModelTest { @@ -27,7 +27,7 @@ public void setUp() throws Exception { @Test public void testGetGreeting_emitsCorrectGreeting() { String greeting = "Hello!"; - Mockito.when(mDataModel.getGreeting()).thenReturn(Observable.just(greeting)); + Mockito.when(mDataModel.getGreetingAsync()).thenReturn(Observable.just(greeting)); TestSubscriber testSubscriber = new TestSubscriber<>(); mViewModel.getGreeting().subscribe(testSubscriber); diff --git a/build.gradle b/build.gradle index dea6d37..70b7b5b 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0-rc1' + classpath 'com.android.tools.build:gradle:2.2.0-beta1' classpath 'me.tatarka:gradle-retrolambda:3.2.3' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 122a0dc..04e285f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip