RoboBinding / RoboBinding

A data-binding Presentation Model(MVVM) framework for the Android platform.
http://robobinding.org
Other
1.28k stars 216 forks source link

Looking at RoboBinding for the first time - Observation #228

Closed jbeckton closed 8 years ago

jbeckton commented 9 years ago

Just watched the video by Robert (2012) London Android User Group.

Early in the video Robert is showing the benefits of RoboBinding's MVVM by removing the "Crap" boilerplate code from the activity. Seems to me that RoboBinding has just moved the boilerplate code into the ViewModel. Looks like you are just trading the getViewByID in the activity to get a handle on each view for setters and getters in the ViewModel. I see other benefits to this library but for me it seems like there is still a good bit of boilerplate code to be written in order to get two way binding.

If I have a business layer that returns an object that has 10 properties then I have to write 20 functions (setters and getters) in my ViewModel so my ui can bind to it.

Is it possible to bind directly to the object instance?

in my ViewModel I have a property like:

UserInfo userInfoObj;

this property gets set by some service call that returns a single object.

then in my view xml:

bind:text="userInfoObj.Firstname"

bind:text="userInfoObj.Lastname"

weicheng113 commented 9 years ago

Hi Jesse,

Thanks for your view. One of major benefits to adopt a mvvm framework is make more of your source code unit testable. it can be up till ViewModel layer when apply mvvm pattern correctly. As the software is getting more complicated, we want this capability.

Another benefit is assisting concerns and layer separation. You can have a read on 'project structure and best practices' if you have not - http://robobinding.github.io/RoboBinding/getting_started.html#_project_structure_and_best_practices, as well as Album Sample project and https://github.com/RoboBinding/Android-CleanArchitecture.

About the idea you described with UserInfo example, there is a problem. Your UserInfo has to be observable so that it can notify the changes to UI. You have either to dirty your UserInfo bean or you have to use some invasive way, for example XXObservable objects like AndroidBinding did in your ViewModels - https://github.com/gueei/AndroidBinding/blob/master/Demo/MarkupDemoICS/src/com/gueei/demos/markupDemo/viewModels/TextView.java.

In my opinion, views are better not to access entities directly, as views normally only access subset of entities' information and there could be some transformation. With a layer viewModel to isolate both sides, it is a good separation. with the text you gave 'bind:text="userInfoObj.Lastname"', it is actaully a method chaining anti-pattern, if you write it in java 'viewModel.userInfoObj.Lastname'. It means view knows about both viewModel and userInfo objects -https://en.wikipedia.org/wiki/Method_chaining.

The feature #164, which has not implemented, is a bit related. , https://github.com/RoboBinding/RoboBinding/issues/164

weicheng113 commented 9 years ago

No further communications. Close it for now.

Dellkan commented 8 years ago

Just for the sake of posterity, https://github.com/Dellkan/robobinding-helpers set out to solve several of these issues. It does so by breaking a few patterns, and intentionally implementing a few anti-patterns.

It sits as a layer on top of Robobinding, and has (among others) the following features:

  1. @Get, @GetSet annotation that can be put on any attribute to automagically generate getters and setters
  2. Support for validation on fields with error messages and custom validation, also using annotations (such as @ValidateLengthMin)
  3. Support for easy export of data, simply apply @AddToData on one or more fields in your model. PresentationModelWrapper gives you access to a method getData() which then takes all annotated fields and puts them in a hashmap which you can easily put into a JsonObject for instance.
  4. Support for nesting child viewmodels through the use of @IncludeModel

@IncludeModel(prefix = "", excludefields = [""]) works in the following way:

@PresentationModel
public class MySubModel extends PresentationModelWrapper implements Serializable {
    @Get
    protected String title;
    @Get
    protected String image;
    @GetSet
    protected String customizableText;
    @GetSet
    protected String privateString;
}

@PresentationModel
public class MainModel extends PresentationModelWrapper implements Serializable {
    @IncludeModel(prefix = "subModel", excludeFields = ("privateString"))
    MySubModel myCustomSubModel;

    @Get
    protected String title;
}

The above enables the following types of layouts (Assume MainModel, and only MainModel is given to Robobinding)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://robobinding.org/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        src="{subModelImage}" />

    <!-- This gives you title from MainModel -->
    <TextView
        bind:text="{title}" />
    <!-- This gives you title from MySubModel -->
    <TextView
        bind:text="{subModelTitle}" />

    <EditText
        bind:text="${subModelCustomizableText}"
</LinearLayout>
weicheng113 commented 8 years ago

@Dellkan Thanks. The intention on subModel is the same as #164 . We want a fine support for component-based development.

I will have a look your other parts when i get time next.

Thanks, Cheng