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

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.

Related

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 Oriented Programming beyond just methods?

I have a very limited understanding of OOP.
I've been programming in .Net for a year or so, but I'm completely self taught so some of the uses of the finer points of OOP are lost on me.
Encapsulation, inheritance, abstraction, etc. I know what they mean (superficially), but what are their uses?
I've only ever used OOP for putting reusable code into methods, but I know I am missing out on a lot of functionality.
Even classes -- I've only made an actual class two or three times. Rather, I typically just include all of my methods with the MainForm.
OOP is way too involved to explain in a StackOverflow answer, but the main thrust is as follows:
Procedural programming is about writing code that performs actions on data. Object-oriented programming is about creating data that performs actions on itself.
In procedural programming, you have functions and you have data. The data is structured but passive and you write functions that perform actions on the data and resources.
In object-oriented programming, data and resources are represented by objects that have properties and methods. Here, the data is no longer passive: method is a means of instructing the data or resource to perform some action on itself.
The reason that this distinction matters is that in procedural programming, any data can be inspected or modified in any arbitrary way by any part of the program. You have to watch out for unexpected interactions between different functions that touch the same data, and you have to modify a whole lot of code if you choose to change how the data is stored or organized.
But in object-oriented programming, when encapsulation is used properly, no code except that inside the object needs to know (and thus won't become dependent on) how the data object stores its properties or mutates itself. This helps greatly to modularize your code because each object now has a well-defined interface, and so long as it continues to support that interface and other objects and free functions use it through that interface, the internal workings can be modified without risk.
Additionally, the concepts of objects, along with the use of inheritance and composition, allow you to model your data structurally in your code. If you need to have data that represents an employee, you create an Employee class. If you need to work with a printer resource, you create a Printer class. If you need to draw pushbuttons on a dialog, you create a Button class. This way, not only do you achieve greater modularization, but your modules reflect a useful model of whatever real-world things your program is supposed to be working with.
You can try this: http://homepage.mac.com/s_lott/books/oodesign.html It might help you see how to design objects.
You must go though this I can't create a clear picture of implementing OOP concepts, though I understand most of the OOP concepts. Why?
I had same scenario and I too is a self taught. I followed those steps and now I started getting a knowledge of implementation of OOP. I make my code in a more modular way better structured.
OOP can be used to model things in the real world that your application deals with. For example, a video game will probably have classes for the player, the badguys, NPCs, weapons, ammo, etc... anything that the system wants to deal with as a distinct entity.
Some links I just found that are intros to OOD:
http://accu.informika.ru/acornsig/public/articles/ood_intro.html
http://www.fincher.org/tips/General/SoftwareEngineering/ObjectOrientedDesign.shtml
http://www.softwaredesign.com/objects.html
Keeping it very brief: instead of doing operations on data a bunch of different places, you ask the object to do its thing, without caring how it does it.
Polymorphism: different objects can do different things but give them the same name, so that you can just ask any object (of a particular supertype) to do its thing by asking any object of that type to do that named operation.
I learned OOP using Turbo Pascal and found it immediately useful when I tried to model physical objects. Typical examples include a Circle object with fields for location and radius and methods for drawing, checking if a point is inside or outside, and other actions. I guess, you start thinking of classes as objects, and methods as verbs and actions. Procedural programming is like writing a script. It is often linear and it follows step by step what needs to be done. In OOP world you build an available repetoire of actions and tasks (like lego pieces), and use them to do what you want to do.
Inheritance is used common code should/can be used on multiple objects. You can easily go the other way and create way too many classes for what you need. If I am dealing with shapes do I really need two different classes for rectangles and squares, or can I use a common class with different values (fields).
Mastery comes with experience and practice. Once you start scratching your head on how to solve particular problems (especially when it comes to making your code usable again in the future), slowly you will gain the confidence to start including more and more OOP features into your code.
Good luck.

Template Method and Strategy design patterns

This is probably a newbie question since I'm new to design patterns but I was looking at the Template Method and Strategy DP's and they seem very similar. I can read the definitions, examine the UML's and check out code examples but to me it seem like the Strategy pattern is just using the Template Method pattern but you just happen to passing it into and object (i.e. composition).
And for that matter the Template Method seems like that is just basic OO inheritance.
Am I missing some key aspect to their differences? Am I missing something about the Template Method that makes it more that just basic inheritance?
Note: There is a previous post on this (672083) but its more on when to use it, which kind of helps me get it a bit more but I want valid my thoughts on the patterns themselves.
It basically all comes down to semantics. The strategy pattern allows you to pass in a particular algorithm/procedure (the strategy) to another object and that will use it. The template method allows you to override particular aspects of an algorithm while still keeping certain aspects of it the same (keep the order the same, and have things that are always done at the start and end for example... the 'template') while inheritance is a way of modelling 'IS-A' relationships in data models.
Certainly, template methods are most easily implemented using inheritance (although you could just as easily use composition, especially once you have functors), and strategy patterns are frequently also template methods but where the syntax is similar the meanings are vastly different.
The Strategy design pattern
provides a way to exchange the algorithm of an object
dynamically at run-time
(via object composition).
For example, calculating prices in an order processing system.
To calculate prices in different ways,
different pricing algorithms can be supported
so that which algorithm to use can be selected (injected) and exchanged dynamically at run-time.
The Template Method
design pattern
provides a way to
redefine some parts of the behavior of a class statically at compile-time
(via subclassing).
For example, designing reusable applications (frameworks).
The application implements the common (invariant) parts of the behavior
so that users of the application can write subclasses to redefine
the variant parts to suit their needs.
But subclass writers should neither be able to change the invariant parts of
the behavior nor the behavior's structure
(the structure of invariant and variant parts).

Should entities have behavior or not?

Should entities have behavior? or not?
Why or why not?
If not, does that violate Encapsulation?
If your entities do not have behavior, then you are not writing object-oriented code. If everything is done with getters and setters and no other behavior, you're writing procedural code.
A lot of shops say they're practicing SOA when they keep their entities dumb. Their justification is that the data structure rarely changes, but the business logic does. This is a fallacy. There are plenty of patterns to deal with this problem, and they don't involve reducing everything to bags of getters and setters.
Entities should not have behavior. They represent data and data itself is passive.
I am currently working on a legacy project that has included behavior in entities and it is a nightmare, code that no one wants to touch.
You can read more on my blog post: Object-Oriented Anti-Pattern - Data Objects with Behavior .
[Preview] Object-Oriented Anti-Pattern - Data Objects with Behavior:
Attributes and Behavior
Objects are made up of attributes and behavior but Data Objects by definition represent only data and hence can have only attributes. Books, Movies, Files, even IO Streams do not have behavior. A book has a title but it does not know how to read. A movie has actors but it does not know how to play. A file has content but it does not know how to delete. A stream has content but it does not know how to open/close or stop. These are all examples of Data Objects that have attributes but do not have behavior. As such, they should be treated as dumb data objects and we as software engineers should not force behavior upon them.
Passing Around Data Instead of Behavior
Data Objects are moved around through different execution environments but behavior should be encapsulated and is usually pertinent only to one environment. In any application data is passed around, parsed, manipulated, persisted, retrieved, serialized, deserialized, and so on. An entity for example usually passes from the hibernate layer, to the service layer, to the frontend layer, and back again. In a distributed system it might pass through several pipes, queues, caches and end up in a new execution context. Attributes can apply to all three layers, but particular behavior such as save, parse, serialize only make sense in individual layers. Therefore, adding behavior to data objects violates encapsulation, modularization and even security principles.
Code written like this:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
can be refactored like so:
Book book = author.WriteBook();
printer.Print(book);
publisher.Publish(book);
customer.Buy(book);
reader = new BookReader();
reader.Open(Book);
reader.Read();
reader.Highlight();
reader.Bookmark();
librarian.GetRelatedBooks(book);
What a difference natural object-oriented modeling can make! We went from a single monstrous Book class to six separate classes, each of them responsible for their own individual behavior.
This makes the code:
easier to read and understand because it is more natural
easier to update because the functionality is contained in smaller encapsulated classes
more flexible because we can easily substitute one or more of the six individual classes with overridden versions.
easier to test because the functionality is separated, and easier to mock
It depends on what kind of entity they are -- but the term "entity" implies, to me at least, business entities, in which case they should have behavior.
A "Business Entity" is a modeling of a real world object, and it should encapsulate all of the business logic (behavior) and properties/data that the object representation has in the context of your software.
If you're strictly following MVC, your model (entities) won't have any inherent behavior. I do however include whatever helper methods allow the easiest management of the entities persistence, including methods that help with maintaining its relationship to other entities.
If you plan on exposing your entities to the world, you're better off (generally) keeping behavior off of the entity. If you want to centralize your business operations (i.e. ValidateVendorOrder) you wouldn't want the Order to have an IsValid() method that runs some logic to validate itself. You don't want that code running on a client (what if they fudge it. i.e. akin to not providing any client UI to set the price on an item being placed in a shopping cart, but posting a a bogus price on the URL. If you don't have server-side validation, that's not good! And duplicating that validation is...redundant...DRY (Don't Repeat Yourself).
Another example of when having behaviors on an entity just doesn't work is the notion of lazy loading. Alot of ORMs today will allow you to lazy load data when a property is accessed on an entities. If you're building a 3-tier app, this just doesn't work as your client will ultimately inadvertantly try to make database calls when accessing properties.
These are my off-the-top-of-my-head arguments for keeping behavior off of entities.

Dealing with "global" data structures in an object-oriented world

This is a question with many answers - I am interested in knowing what others consider to be "best practice".
Consider the following situation: you have an object-oriented program that contains one or more data structures that are needed by many different classes. How do you make these data structures accessible?
You can explicitly pass references around, for example, in the constructors. This is the "proper" solution, but it means duplicating parameters and instance variables all over the program. This makes changes or additions to the global data difficult.
You can put all of the data structures inside of a single object, and pass around references to this object. This can either be an object created just for this purpose, or it could be the "main" object of your program. This simplifies the problems of (1), but the data structures may or may not have anything to do with one another, and collecting them together in a single object is pretty arbitrary.
You can make the data structures "static". This lets you reference them directly from other classes, without having to pass around references. This entirely avoids the disadvantages of (1), but is clearly not OO. This also means that there can only ever be a single instance of the program.
When there are a lot of data structures, all required by a lot of classes, I tend to use (2). This is a compromise between OO-purity and practicality. What do other folks do? (For what it's worth, I mostly come from the Java world, but this discussion is applicable to any OO language.)
Global data isn't as bad as many OO purists claim!
After all, when implementing OO classes you've usually using an API to your OS. What the heck is this if it isn't a huge pile of global data and services!
If you use some global stuff in your program, you're merely extending this huge environment your class implementation can already see of the OS with a bit of data that is domain specific to your app.
Passing pointers/references everywhere is often taught in OO courses and books, academically it sounds nice. Pragmatically, it is often the thing to do, but it is misguided to follow this rule blindly and absolutely. For a decent sized program, you can end up with a pile of references being passed all over the place and it can result in completely unnecessary drudgery work.
Globally accessible services/data providers (abstracted away behind a nice interface obviously) are pretty much a must in a decent sized app.
I must really really discourage you from using option 3 - making the data static. I've worked on several projects where the early developers made some core data static, only to later realise they did need to run two copies of the program - and incurred a huge amount of work making the data non-static and carefully putting in references into everything.
So in my experience, if you do 3), you will eventually end up doing 1) at twice the cost.
Go for 1, and be fine-grained about what data structures you reference from each object. Don't use "context objects", just pass in precisely the data needed. Yes, it makes the code more complicated, but on the plus side, it makes it clearer - the fact that a FwurzleDigestionListener is holding a reference to both a Fwurzle and a DigestionTract immediately gives the reader an idea about its purpose.
And by definition, if the data format changes, so will the classes that operate on it, so you have to change them anyway.
You might want to think about altering the requirement that lots of objects need to know about the same data structures. One reason there does not seem to be a clean OO way of sharing data is that sharing data is not very object-oriented.
You will need to look at the specifics of your application but the general idea is to have one object responsible for the shared data which provides services to the other objects based on the data encapsulated in it. However these services should not involve giving other objects the data structures - merely giving other objects the pieces of information they need to meet their responsibilites and performing mutations on the data structures internally.
I tend to use 3) and be very careful about the synchronisation and locking across threads. I agree it is less OO, but then you confess to having global data, which is very un-OO in the first place.
Don't get too hung up on whether you are sticking purely to one programming methodology or another, find a solution which fits your problem. I think there are perfectly valid contexts for singletons (Logging for instance).
I use a combination of having one global object and passing interfaces in via constructors.
From the one main global object (usually named after what your program is called or does) you can start up other globals (maybe that have their own threads). This lets you control the setting up of program objects in the main objects constructor and tearing them down again in the right order when the application stops in this main objects destructor. Using static classes directly makes it tricky to initialize/uninitialize any resources these classes use in a controlled manner. This main global object also has properties for getting at the interfaces of different sub-systems of your application that various objects may want to get hold of to do their work.
I also pass references to relevant data-structures into constructors of some objects where I feel it is useful to isolate those objects from the rest of the world within the program when they only need to be concerned with a small part of it.
Whether an object grabs the global object and navigates its properties to get the interfaces it wants or gets passed the interfaces it uses via its constructor is a matter of taste and intuition. Any object you're implementing that you think might be reused in some other project should definately be passed data structures it should use via its constructor. Objects that grab the global object should be more to do with the infrastructure of your application.
Objects that receive interfaces they use via the constructor are probably easier to unit-test because you can feed them a mock interface, and tickle their methods to make sure they return the right arguments or interact with mock interfaces correctly. To test objects that access the main global object, you have to mock up the main global object so that when they request interfaces (I often call these services) from it they get appropriate mock objects and can be tested against them.
I prefer using the singleton pattern as described in the GoF book for these situations. A singleton is not the same as either of the three options described in the question. The constructor is private (or protected) so that it cannot be used just anywhere. You use a get() function (or whatever you prefer to call it) to obtain an instance. However, the architecture of the singleton class guarantees that each call to get() returns the same instance.
We should take care not to confuse Object Oriented Design with Object Oriented Implementation. Al too often, the term OO Design is used to judge an implementation, just as, imho, it is here.
Design
If in your design you see a lot of objects having a reference to exactly the same object, that means a lot of arrows. The designer should feel an itch here. He should verify whether this object is just commonly used, or if it is really a utility (e.g. a COM factory, a registry of some kind, ...).
From the project's requirements, he can see if it really needs to be a singleton (e.g. 'The Internet'), or if the object is shared because it's too general or too expensive or whatsoever.
Implementation
When you are asked to implement an OO Design in an OO language, you face a lot of decisions, like the one you mentioned: how should I implement all the arrows to the oft used object in the design?
That's the point where questions are addressed about 'static member', 'global variable' , 'god class' and 'a-lot-of-function-arguments'.
The Design phase should have clarified if the object needs to be a singleton or not. The implementation phase will decide on how this singleness will be represented in the program.
Option 3) while not purist OO, tends to be the most reasonable solution. But I would not make your class a singleton; and use some other object as a static 'dictionary' to manage those shared resources.
I don't like any of your proposed solutions:
You are passing around a bunch of "context" objects - the things that use them don't specify what fields or pieces of data they are really interested in
See here for a description of the God Object pattern. This is the worst of all worlds
Simply do not ever use Singleton objects for anything. You seem to have identified a few of the potential problems yourself