Can You please explain what are analogues of MVC / Observer techniques in two cases:
Immutable Objects (OOP style)
Immutable Data (functional style)
For example let's consider following simple GUI example (You can try it live here http://tinkerbin.com/0XDHRXIl click 'Run' button to start it and wait 2 sec for text to appear)
It's built with JavaScript because it's easy to play and MVC / Observer are very natural to it
// Model containing the data.
var Post = Backbone.Model.extend({})
var PostView = Backbone.View.extend({
initialize: function() {
// Registering view rendering method as
// an observer on the model.
this.model.on('all', this.render.bind(this))
},
// Every time state of model changes
// this method will be called.
render: function() {
// Printing value of model.text attriubute.
this.$el.html(this.model.get('text'))
return this
}
})
// Now, any time the model is updated the view will be also
// automatically updated.
post.set({text: "hello, it's me"})
But I don't quite understand how to do the same with Immutable OOP and Functional styles, what ways are there?
In case of classical MVC and OOP techniques there are implicit identifier for every object - its reference. Observer relies on this reference/identifier to dispatch messages to correct objects.
In Immutable world reference doesn't identify object anymore (there may be multiple references for different versions of object) and in functional world there's no objects at all. So, we need to explicitly supply the object identity.
The analogue of Observer in Immutable/Functional world is a Pub/Sub with explicitly provided object IDs.
Regarding an immutable OOP style I would suggest to apply the following modifications: Instead of "changing the model state" you would have to create a new model state each time there is a state change. Instead of pulling the state in the observing function in the view, I would pass the immutable state as parameter to the observe function (here: the render function).
As inspiration for a more functional approach to the observer design pattern, you might want to have a look at reactive functional programming. Particularly, I would recommend the somewhat controversial paper on Deprecating the Observer Pattern.
Related
I am working on a small chess website based on fastAPI and Vue 3 (composition API).
The chess logic is managed by the chessjs lib from which I can instanciate a chess object with a full package of handy methods.
In order to synchronize my component and my chess object, I created a chess reactive:
let chess = reactive(new Chess())
A lot of computed properties and template linked to those properties later, I just figured out that all methods calculation launched on the proxy become very slow compared to the raw object (example, looking for the possible moves from a position takes 3ms with the raw object and 180ms with the proxy). This is independant from the quantity of rendering demanded.
I understand that Vue needs to check what needs a render or an update but I find it pretty awkward.
What am I missing here?
My workaround for now is to use the raw object and use a computed prop which depends on refs hat are updated by some functions that are trigged with event:
click on UI (or whatever other event) => triggers a function that use the raw chess method that returns some array and update a ref => updates a computed prop based on the ref => makes the template update
instead of
click on UI (or whatever other event) => call chess.method() that updates the chess proxy object => makes the template update
I feel like I am not use Vue as it should be...
Can someone give me some advices?
You shouldn't be making the entire Chess instance reactive since it likely contains a significant amount of internal properties, most of which are not necessary to detect a change. Since chess.js doesn't look it has any "listener" methods for detecting a change to the board, the correct solution would be to use a shallowRef (https://vuejs.org/api/reactivity-advanced.html#shallowref) and manually call triggerRef (https://vuejs.org/api/reactivity-advanced.html#triggerref) whenever you make changes to the chess board.
According to the LiveData documentation, one of the features has been designed to notify data changes using observable pattern.
(Along with this,LiveData offers a number of other promising features)
On the other hand, the Observable data object based on its documentation is capable of notifying others about changes in its data.
As a result, these two features seem are same.
The question is:
isn't it better to use LiveData with its other features?
According to LiveData documentation:
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.
So it is essentially a lifecycle-aware observable, now it is an advantage, isn't it?
However, there is really no restriction about using only RxJava or LiveData, the two can be used along with each other.
Actually, it better to use RxJava when there is no lifecycle available like Repository in the data layer and keep LiveData in layers that lifecycle is important like the Presentation layer.
LiveData is like an observable but like unlike an observable, it is lifecycle aware. So this means that the live data will only update app component observers that are in an active state. However, you don't always need to use livedata. I would say livedata comes in handy when there are lifecycle components involved such as activities and fragments. For more information look at When to use RxJava in Android and when to use LiveData from Android Architectural Components?
The observable in the question is ObservableFields, not RxJava Obervervable like the other answers mentioned.
It's a good question to compare between LiveData and ObservableFields. Because live data is lifecycle aware, it can do a lot of things. You can observe the live data from the view model and update the UI from the code. You can also extend the live data and use it like an event bus to notify the data change between 2 Android components and you don't need to worry about the lifecycle issue.
But does that mean it is not necessary to use ObservableFields at all? No. Because data binding itself is lifecycle aware, it already checks when the view is active. You can use LiveData or ObservableFields or even Stateflow
In one-way data binding, you can use any of them, but in 2-way data binding, I still prefer observable fields, because it's more flexible, and you can easily write custom logic in the observable field setter, and when the UI changes, it can call the setter to do some additional stuff.
class LoginViewModel : BaseObservable {
// val data = ...
#Bindable
fun getRememberMe(): Boolean {
return data.rememberMe
}
fun setRememberMe(value: Boolean) {
// Avoids infinite loops.
if (data.rememberMe != value) {
data.rememberMe = value
// React to the change.
saveData()
// Notify observers of a new value.
notifyPropertyChanged(BR.remember_me)
}
}
}
And in xml file.
<CheckBox
android:id="#+id/rememberMeCheckBox"
android:checked="#={viewmodel.rememberMe}"
/>
So i am learning the flux pattern using redux as a framework for it, to generate a mobile application in react-native (no backend).I feel I have been fighting against the pattern for some time due I come from an OO background and was expecting my model to be abstracted and bind somewhere in the pattern.
Last night I think I had an epiphany by thinking that this pattern enforces the idea that all is data and how is treated in reaction to events. So is fully functional programming and no abstractions (that have state) have a place inside this pattern.
So just to map to an OO world I have explain it in this mode to my brain:
internal objects in the store: each is equivalent to the properties of a class.
Event: equivalent to the reaction to something that happen and calls methods from a class.
reducer: the methods that transform the data inside a class.
views: the representation to the user of those abstractions.
My questions then are:
Is this weird theory (models inside the store). valid or just a bad idea?
if not valid, where do my models hook in a redux based application?
if not valid, this means this pattern is just to use on the front-end?
This is more general question to any OOP, please before answer consider readability and efficiency.
Here is example in Javascript:
function fnc () {
this.var = "abc";
this.setVar = function (val) {
this.var = val;
}
this.getVar = function () {
return this.var;
}
}
Now, i can set value of var via method:
fnc.setvar("abc");
or
fnc.var = "abc";
I can also get it directly:
console.log(fnc.var)
or via get method:
console.log(fnc.getVar())
Here comes the question:
If the result is the same which option is better? what are the pros and cons for direct or method way?
This highly depends on the features and patterns used in a given language.
Behaviour driven languages
In Java or C++ classes are defined by their behaviour, read "methods". The interfaces and the whole inheritance are based on methods. Fields are 2nd class citizens. Therefore you use methods to get and set attributes. This is the only way of overriding the access and ensuring the integration is correct after you change something later on. Having all fields hidden behind methods also enables you finer grained control (for example getter without a corresponding setter, or a setter that does a calculation instead of simply setting an attribute), but you need a lot of boilerplate, so you write lots of code that does not really add to your business logic and makes the code harder to read from within the class. What makes the code harder to read, however, makes it easier to understand from the client-side through interfaces, as they fully define a class. This concept of methods over attributes usually comes along with visibility settings for methods and attributes. This way you define what is meant for outside world and what is meant for this class or package only. Attributes are almost always private (read "for this class only").
Property driven languages
In languages like JavaScript or Python classes/objects are defined by their fields, read "attributes". Even methods are nothing more than attributes and so both methods and attributes can be overriden (or hidden), switched at runtime etc. Given that you gain nothing but false security using getters and setters, and given that every function call less means better performance and shorter stacktrace, using fields directly is the preferred usage in scripting languages. Regarding readability: the code itself is much easier to read and to understand, but interfaces as known from behaviour based languages don't exist here except in form of documentation (if the code author writes one). Visibility of methods and attributes is usually always public, but some languages offer special annotations or naming schemas to show which methods or fields are meant to be private. There is no strong or no enforcement at all though.
BTW-JFYI: Python has a special solution for the extendability of fields: properties. This is a special thing which enables you using getter and setter with proper logic inside the class but present the field as plain attribute to the outside world. See Python #property versus getters and setters for further reading.
Don't consider the immediate result only. Most software is going to be modified at some point. Considering that, you are more flexible when using getter and setter methods as opposed to direct attribute access.
However the best option - if applicable - is to not use setters at all but create immutable objects.
Let's say I have an class to model a city. Its characteristics are the following:
It has only two properties "name" and "population", both private, that are set in the constructor.
It has getters for these properties, but not setters.
I don't want any user of this class to set the properties, I want them to use a public .edit() method.
This method needs opens up a form to input the new name of the city and population, i.e.: a view. Then, if I have a view, I would like to implement the MVC pattern, so the idea would be that the controller receives the .edit() call, renders the view, retrieves the data back, and sends it to the view so that it changes its state.
But, if I do so, I have to change the properties of the city model from private to public. So, if any user instantiates my class, she/he can directly change the properties.
So, the philosophical question: Isn't that breaking the encapsulation?
EDIT Just to make it more explicit:
This city_instance.edit() method should be the only way to mutate the object.
Besides, I see that part of my problems comes from the misunderstanding that a model is an object (you can read that on php mvc frameworks), when it is actually a different abstraction, it's a layer that groups the business logic (domain objects + I guess more things)
Disclaimer: I don't really understand where are you proposing the .edit() method to be implemented, so it would help if you could clarify that a little bit there.
The first thing to consider here is that in the bulleted list of your question you seem to imply that a City instance acts like an immutable object: it takes its instance variables in the constructor and doesn't allow anybody in the outside to change them. However, you later state that you actually want to create a way to visually edit a City instance. This two requirements are clearly going to create some tension, since they are kind of opposites.
If you go the MVC approach, by separating the view from the model you have two main choices:
Treat your City objects as immutable and, instead of editing an instance when the values are changed in the form, throw away the original object and create a new one.
Provide a way to mutate an existing City instance.
The first approach keeps your model intact if you actually consider a City as an immutable object. For the second one there are many different ways to go:
The most standard way is to provide, in the City class, a mutator. This can have the shape of independent setters for each property or a common message (I think this is the .edit() method you mentioned) to alter many properties at once by taking an array. Note that here you don't take a form object as a parameter, since models should not be aware of the views. If you want your view to take note of internal changes in the model, you use the Observer pattern.
Use "friend" classes for controllers. Some languages allow for friend classes to access an object's internals. In this case you could create a controller that is a friend class of your model that can make the connection between the model and the view without having to add mutators to your model.
Use reflection to accomplish something similar to the friend classes.
The first of this three approaches is the only language agnostic choice. Whether that breaks encapsulation or not is kind of difficult to say, since the requirements themselves would be conflicting (It would basically mean wanting to have a model separated from the view that can be altered by the user but that doesn't allow the model itself to be changed for the outside). I would however agree that separating the model from the view promotes having an explicit mutation mechanism if you want mutable instances.
HTH
NOTE: I'm referring to MVC as it applies to Web applications. MVC can apply to many kinds of apps, and it's implemented in many kinds of ways, so it's really hard to say MVC does or does not do any specific thing unless you are talking strictly about something defined by the pattern, and not a particular implementation.
I think you have a very specific view of what "encapsulation" is, and that view does not agree with the textbook definition of encapsulation, nor does it agree with the common usage of it. There is no definition of "Encapsulation" I can find that requires that there be no setters. In fact, since Setters are in and of themselves methods that be used to "edit" the object, it's kind of a silly argument.
From the Wikipedia entry (note where it says "like getter and setter"):
In general, encapsulation is one of the four fundamentals of OOP (object-oriented programming). Encapsulation is to hide the variables or something inside a class, preventing unauthorized parties to use. So the public methods like getter and setter access it and the other classes call these methods for accessing.
http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Now, that's not to say that MVC doesn't break encapsulation, I'm just saying that your idea of what Encapsulation is is very specific and not particularly canonical.
Certainly, there are a number of problems that using Getters and Setters can cause, such as returning lists that you can then change directly outside of the object itself. You have to be careful (if you care) to keep your data hidden. You can also replace a collection with another collection, which is probably not what you intend.
The Law of Demeter is more relevant here than anything else.
But all of this is really just a red herring anyways. MVC is only about the GUI, and the GUI should be as simple as possible. It should have almost no logic in either the view or the controller. You should be using simple view models to deserialize your form data into a simple structure, which can the be used to apply to any business architecture you like (if you don't want setters, then create your business layer with objects that don't use setters and use mutattors.).
There is little need for complex architecture in the UI layer. The UI layer is more of a boundary and gateway that translates the flat form and command nature of HTTP to whatever business object model you choose. As such, it's not going to be purely OO at the UI level, because HTTP isn't.
This is called an Impedance Mismatch, which is often associated with ORM's, because Object models do not map easily to relational models. The same is true of HTTP to Business objects. You can think of MVC as a corollary to an ORM in that respect.