After I have read the Android documentation and various other articles about LiveData, I came to know that the main benefit of it is its state-awareness.
The concept may be very nice for simple Objects like a String, but I am wondering why it is suggested to use it for complex types or collections.
As a list can easily be modified without triggering any notification (as the list is just a reference inside the LiveData-Object), I think it is very error-prone and required one to do additional steps.
For example:
...
List<String> list = new ArrayList<>();
MutableLiveData<String> mld = new MutableLiveData<>();
mld.setValue(list);
...
// probably some other Class/Method...
List<String> sameList = mld.getValue();
// won't trigger any notification but changes the initial list
sameList.add("Some String");
// needed to trigger notification:
mld.setValue(sameList);
Wouldn't it be much better to have an Interface (or at least two) like with implementing the Observer-Pattern to be able to notify the observing objects whenever any changing action is triggered? Just with the additional state-awareness?
This won't help with the list-example in the first place unless there isn't some list-type implementing the interface, but if one writes a model-class that basically offers special instructions on a list, this would make way more sense in my opinion. The model itself could have well-designed logics and enforce notifications for every modification.
The calling class does not need to care about when a notification is triggered as long as it applied itself as an observer.
So is LiveData basically designed to be used with predefined classes from other libraries so that one does not need to modify existing code but can just use LiveData as a wrapper and decide when to update manually?
Or is it more common to just extend the LiveData class and add the functionality there?
With Kotlin it seems to be possible to write just an extension-function, like mentioned here: Refreshing MutableLiveData of list of items
But that would mean that one has to write a wrapper-function for every function present in already existing models. This may be feasible with aspect-oriented programming.