Is Redux asking us not to use OOP? - oop

I come from an OOP background and I'm learning Redux. It seems the more I learn about Redux, I realize how it contrasts with the OOP paradigm by employing more functional constructs.
That said, I've never used Backbone, but I came across this in the redux docs regarding migrating from Backbone models:
Backbone's model layer is quite different from Redux, so we don't suggest mixing them. If possible, it is best that you rewrite your app's model layer from scratch instead of connecting Backbone to Redux...
Source:
https://github.com/reactjs/redux/blob/master/docs/recipes/MigratingToRedux.md#from-backbone
Moreover, I found that initially, this simply read:
Sorry, you’ll need to rewrite your model layer.
It’s way too different!
Source: https://github.com/reactjs/redux/commit/fbe0852a25d4bf9819adfe95fef6aa6702658c07#diff-a7be1d864910aa327225143859006953R30
Sooo... Is Dan saying to rewrite you model layer because models, (such as those from Backbone) are OO in nature and redux prescribes to a more functional paradigm?

Yes and no. You need to rewrite your data stuff to not be models but POJOs in the state. They can look a lot like models and they are definitely objects, but they can't have methods. Well, technically they could and it may not even be a problem, but it's discouraged because the state ought to be serializable.
Because I like setting properties and calling methods more than I like dispatching actions, and because I like to attach my code to my data, I wrote a library that lets you use models instead of the standard Redux action creator/action/dispatch/reducer paradigm. Under the hood, it's 100% Redux, but the Dev API is all OOP. This way it has all of Redux's benefits and all OOP's benefits. You may find it alleviates some of the concerns you voiced.
But you still have to rewrite your model layer.

Related

Is using ES6 classes in vue/vuex(/flux?) an anti-pattern?

I've been using Vuex, and it's adherence to only altering state through it's mutators or actions makes me think your store should only include as flat an object as you can, with only primitives types.
Some threads even prescribe normalising your data (so instead of nested object trees you have objects with arrays of id's to indicate tree relationships). This probably matches closely to your JSON api.
This makes me think that storing classes (that may have methods to alter themselves) in your flux store is an anti-pattern. Indeed even hydrating your store's data into a class seems like you're moving against the tide unless your class performs no modifications to its internal data.
Which then got me thinking, is using any class in a Vue/Vuex/Reactive/Flux an anti-pattern?
The libraries seem explicitly designed to work with plain JS objects and the general interactions you have with the API (data in, data out) makes me feel like a more functional approach (sans immutability) is what the original designers were thinking about.
It also seems be easier to write code that runs from function => test => state mutator wrapper around function.
I understand that JS objects and JS classes behave very similarly (and are basically the same thing), but my logic is if you don't design with classes in mind, then you're more likely to not pollute your state with non-flux state changes.
Is there a general consensus in the community that your flux code should be more functional and less object orientated?
Yes. You are absolutely right in what you are thinking. State containers like Redux, Vuex are supposed to hold your data constructs and not functions. It is true that functions in JavaScript are simply objects which are callable. You can store static data on functions too. But that still doesn't qualify as pure data. It is also for this same reason that we don't put Symbols in our state containers.
Coming back to the ES classes, as long as you are using classes as POJO i.e. only to store data then you are free to use those. But why have classes if you can have simple plain objects.
Separating data from UI components and moving it into state containers has fundamental roots in functional programming. Most of the strict functional languages like Haskell, Elm, OCaml or even Elixir/Erlang work this way. This provides strong reasoning about your data flows in your application. Additionally, this is complemented by the fact that, in these languages, data is immutable. And, thus there is no place for stateful Class like construct.
With JavaScript since things are inherently mutable, the boundaries are a bit blur and it is hard to define good practices.
Finally, as a community, there is no definite consensus about using the functional way, but it seems that the community is heading towards more functional, stateless component approaches. Some of the great examples are:
Elm
ReasonML
Hybrids
swiss-element
Cycle.js
And now, even we have functional components in both Vue and React.

Is there any place for OOP in redux?

I've been using object-oriented programming practices for 25 years and trying to move toward functional programming for the last 5 years, but my mind always goes towards OOP when I'm trying to do something complex and, especially now that ES6 supports decent OOP syntax, that's the natural way for me to build stuff.
I'm now learning Redux and I understand (c.f. How to put methods onto the objects in Redux state?) that it's a no-no to put class instances in your reducers; and the recommended method for computing on top of plain reducer state is by using selectors (e.g., via reselect). And, of course, React recommends composition over inheritance (https://facebook.github.io/react/docs/composition-vs-inheritance.html, React redux oop classes).
But is there any place in the React/Redux ecosystem for class objects with methods and inheritance?
I guess, to sort of answer my own question, OOP classes encourage the addition of data properties and operations on the data in the same place, which is nice for readability, but doesn't fit well with pure functions and immutable data.
If I was going to use OOP, would I need to chuck the idea of having my instances persist and maintain state for any amount of time? Like, every time I want to use one, I would instantiate it from store data, use whatever methods I want, and throw it away? That might obviate a lot of the impetus to use OOP classes. But if I keep instances around, I'll have headaches keeping them synced with the store.
So, is the answer to always use selectors when I'm tempted to use methods and always use composition when I'm tempted to use inheritance? Specifically, I mean when storing and manipulating data held in a Redux store for use in React components. And, if so, where should it fit in? Connected to selectors? Immediately disposable like I suggested?
Adding my use case for clarity: My data is basically a huge graph: lots of objects with lots of properties and lots of relationships between objects. It's read only, but complex. My objects are called "concepts".
Before making the (probably foolish) decision to migrate to Redux, I used classes to structure and represent concepts, sets of concepts, and relationships between concepts. My classes included async api logic to fetch concept sets, information about each concept, and information about other concepts that each concept is related to. If the user chose to drill down, the classes would recursively fetch and instantiate new concept sets. The Redux documentation recommends flat, normalized structures for nested data (http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html) which is probably wise for storage, but my OOP model was good for traversing sections of the graph and stuff. I have a hard time wrapping my head around using selectors and immutable state that might involve nesting, potentially with cycles, or needing to make async calls for more data.
I'm successfully using https://redux-observable.js.org/ for the api stuff.
Maybe #Sulthan's answer is right: I should feel free to use OOP techniques in my Redux application. But it still seems weird. I can't keep my objects around because if the store changes (more data is fetched, for instance), my objects can get stale. If my objects are nested but my store is normalized, I'll instantiate them (from selectors) when I need them and make sure not to keep them around...
The answer is that it's possible but heavily discouraged and non-idiomatic.
React does rely on classes and single-level inheritance of React.Component to implement stateful components with lifecycles, but you are officially discouraged from doing further levels of inheritance in components.
Redux is built around Functional Programming principles. For a variety of reasons, you are encouraged to keep your state as plain JS objects and arrays, and access/manipulate it using plain functions.
I've certainly seen many libraries that tried to add an OOP layer on top of Redux (such as classes whose methods are turned into action creators and reducers). Those work, but are definitely going against the overall spirit of Redux.
I do actually use a library called Redux-ORM, which does allow you to define Model classes that act as a facade over the plain JS objects in your store. However, unlike many of the other libraries that I've seen, it works with Redux rather than trying to change how Redux behaves. I discussed how Redux-ORM works, how I use it, and why it's still reasonably idiomatic, in my blog posts Practical Redux, Part 1: Redux-ORM Basics and Practical Redux, Part 2: Redux-ORM Concepts and Techniques. Overall, it's an excellent tool for helping manage relationships and normalized data in your Redux store.
Finally, I'm currently working on a blog post that will discuss the actual technical limitations that Redux requires (and why), vs how you are intended to use Redux, vs how it's possible to use Redux. I hope to have that up in the next week or so - keep an eye on http://blog.isquaredsoftware.com .
I'll answer my own question by describing what I ended up doing, imperfect as it is.
First, instead of regular ES6 class syntax, I've started using stampit, which is uglier that ES6 classes, but much more flexible.
Mainly, though, my complex objects exist in two forms:
plain JS objects for the store
class (actually stamped) instances for convenience and power of using instance methods.
I use a convention of putting an _underscore in front of all references to the plain objects. My "solution" is kludgy and bad for lots of reasons, but I think trying to use selectors for everything would be worse. If you're curious, here's the place in my code where I "inflate" my plain store objects into instances: https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/conceptSet.js#L292
UPDATE
Turning redux state POJOs into class instances (regular or stampit) is a terrible idea and someone should have stopped me long ago.
I probably should have accepted #markerikson's answer, and maybe the Redux-ORM thing is worth looking at, but I just wanted to say definitively, DON'T DO WHAT I DID. (I always think I'm so smart filling in the "gaps" of technologies I'm learning with clever hacks -- and then I spend painful months cleaning up the mess once I understand why that technology didn't include my hack in the first place.)
Another update
From Composing Software: An Introduction:
What we won’t do is say that functional programming is better than
object-oriented programming, or that you must choose one over the
other. OOP vs FP is a false dichotomy. Every real Javascript
application I’ve seen in recent years mixes FP and OOP extensively.
Looks like there are good ways to think about combining FP and OOP, and it will, no doubt, use some immutable classes and composition without a lot of inheritance. This series on composition looks like what I needed to learn.
This question is a bit opinion-based but let's concentrate on the core points.
There is no contradiction between functional programming and OOP. You just need to use the same programming patterns. There is no problem to use classes (with inheritance) in functional programming, if you keep them immutable.
To prove my point, the popular library Immutable.js that is used by many people to keep state in redux is composed from classes. And those classes have inheritance (e.g. OrderedSet extends Set).
Also note that most React components are classes and they use inheritance, too (... extends React.Component).

Object models in flux / redux

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?

Where does NSURLConnection belong in MVC?

Where does NSURLConnection and it's delegate methods belong in MVC? I think it is Model? But should not model be dumb and not know any thing about connections ? but putting in controller also does not make sense?
IMHO NSURLConnection is model. The connection part is not about model, but about data management that model is actually responsible for.
The answer is in the delegate design pattern.
If your query is fired by UI actions, then the constructor, configuration, and firing of the thing is in the controller. As a "connective" action, it's appropriate for that to be a controller-level function.
If what it updates is underlying model stuff, set up its delegate to point to the model class, and do the data receiving, parsing, and model updating there. The model can then be ignorant about everything but data-related issues.
This is a case where the fundamental design patterns of Cocoa Touch really lend themselves to MVC-style separation of concerns.
(Also you'll be happier learning about ASIHTTPRequest, rather than continuing to use NSURLConnection, but that's not the question you're asking.)

Is this an anemic domain model?

I'm trying to build my first CRUD application, and I don't understand if I should use an object containing getters and setters separated.
Considering that we have the Zend Framework Quick Start tutorial with a Model structure containing:
Gateway
DataMapper
Domain Object (model class)
If the Domain Object (as presented on Zend Quick Start Tutorial) consists of only getters and setters, is that an anti-pattern? In a sense, we are unecessarily dividing the domain object with a transaction script?
Please advise.
The Anemic Domain Model is an Anti-Patern ONLY IF you are trying to build a true Domain Model (aka Domain Model from Domain Driven Design) and end up with entities with only state and without behavior.
For a simple CRUD application an anemic domain model is probably a best practice, especially when you have framework that makes your job very easy.
See Martin Fowler's article about Anemic Domain Model and also Greg Young's Article.
The domain objects are seperated from the business logic of the software. This is an important idea of procedural programming.
However this pattern is considered to be a candidate for an anti-pattern by some developers which means that it might be a ineffective practice.
In fact you could consider disadvantages
your model is less expressive, getters and setters aren't really good to describe the model
code is harder to reuse, you get dublicated code among your transactional scripts
you have to use wrappers which hide the actual data structure (so maybe not really OOP)
there is always a global access to entities
I think the most interesting point to consider is that domain model's objects cannot assure their correctness at any time. Because their mutation takes place in seperated layers.
I worked on a CRUD application with zend framework too. The clear separation between logic and data is really great but when you progress you realize that the amount of layers and mappers gets bigger and bigger. Try to reuse your code as much as you can and avoid dublication.