Classroom Examples for decoupling software components - javascript

I'm trying to get to grips with highly-decoupled, low-cohesion patterns for designing components.
I'm designing each Feature of a larger system as a Web Component - analogous to the concept of a "Module" in design patterns, e.g Export-PDF functionality, Boards functionality etc.
The issue is that some components are dependent between them - they call methods of each, have access to their public variables etc.
Since each component needs to be testable in isolation, must be highly-decoupled, must have low inter-dependency with other components, what are some classroom examples for decoupling one from one another?
Considering this scenario:
User presses CTRL+P
Keybindings are handled by the Shortcuts Component
Shortcuts Component calls Export-PDF Component .print() method.
Some solutions I've though about:
Use events
Each component dispatches an event which is then caught in the other component, e.g using this.addEventListener(...
Pros:
Allows testing in isolation since there are no direct calls to another component's methods.
Cons:
Will result in many dispatches/listeners which might impact performance.
There is still a lot of coupling and it has the potential of getting unmanageable.
Use direct calls to methods of the other component
Each component simply calls the other components method directly, e.g exportPDF.printPages().
Pros:
It's the most simple.
Cons:
Each component is interdependent to one another.
Component is NOT testable in isolation.
What are some other methods of decoupling components?
For the record, the language of interest is JavaScript.
Although concepts and methods might be applicable across many programming languages, I'm specifically talking about concepts and solutions to the problems using features that JavaScript has.

Related

React - Components to create and update db model, inheritance or composition?

I'm relatively new to React. My use case implies a create page for a database model and an update page. I have a lot of duplicate code in those and coming from regular OOP design I would create a base class for it and let the two component inherit.
However, after reading several forums, I saw that you should mostly prefer composition over inheritance with React. Would that also apply in this use case? It seems odd to model this via composition.
I think composition also applies to your use case. From what I understand you will have almost the same page for update and create, all your model files will be the same in both cases. So you can make a reusable component, some form. And use it in create and update page, just perform the right action for each of them.

How stateless components are optimised in React v16.0?

In the react docs, I read:
This pattern is designed to encourage the creation of these simple
components that should comprise large portions of your apps. In the
future, we’ll also be able to make performance optimizations specific
to these components by avoiding unnecessary checks and memory
allocations.
There are several discussions on github like this but these are quite old, what I want to ask is if there are any optimisations done in React v16.0 or before for functional components like implicit shouldComponentUpdate etc. and if these optimisations are done then what are those?
So there isn't any official documentation for FSC (functional stateless components) performance gains over class components. But, I came across this well written medium article that explains how you can get performance gains using FSC.
TLDR: Directly calling functional components as functions instead of mounting them using React.createElement is much faster.
For instance, a FSC looks like this:
const Avatar = (props) => {
return <img src={props.url} />;
}
The way we usually use these components is with the JSX component syntax:
<Avatar url="/path" />
But, through some careful benchmarking and exploration, the author was able to get ~45% speed improvement by calling the FSC as a function:
Instead of mounting them as components, let’s just call them as what they really are: plain JavaScript functions.
Avatar({ url: "/path" });
I think getting performance gains from this method really depends on your app structure, but I thought that it was a neat trick that could potentially be really useful.
There aren't any Optimizations done on the stateless components yet as of v16.0.0 is concerned. The changes that are done from v15 yo v16 are
fragments, error boundaries, portals, support for custom DOM attributes, improved server-side rendering, and reduced file size.
You can see the React Blog for more details on this changes
The only current optimization that I am aware of is that instance objects of stateless components are never created nor retained. So one less object gets created and stored in memory per rendered instance.

React Flux: Store dependencies

so I have recently playing with React and the Flux architecture.
Let's say there are 2 Stores A and B. A has a dependecy on B, because it needs some value from B. So everytime the dispatcher dispatches an action, first B.MethodOfB gets executed, then A.MethodOfA.
I am wondering what are the advantages of this architecture over registering A as a listener of B and just executing the A.MethodOfA everytime B emits a change event?
Btw: Think about a Flux implementation without the "switch case" of the example dispatcher from facebook!
The problem with an evented approach is that you don't have a guarantee as to which handlers will handle a given event first. So in a very large, complex app, this can turn into a tangled web where you're not really sure what is happening when, which makes dependency management between stores very difficult.
The benefits of the callback-based dispatcher are twofold: the order in which stores update themselves is declared in the stores that need this ordering, and it is also guaranteed to work exactly as intended. And this is one of the primary purposes of Flux -- getting the state of an app to be predictable, consistent and stable.
In a very small app that is guaranteed to not grow or change over time, I can't argue with what you are suggesting. But small apps have a tendency to grow into large ones, eventually. This often happens before anyone realizes it's happening.
There are certainly other approaches to Flux. Quite a few different implementations have been created and they have different approaches to this problem. However, I'm not sure which of these experiments scale well. On the other hand, the dispatcher in Facebook's Flux repo and the approach described in the documentation has scaled to truly gigantic applications and is quite battle tested.
In my opinion I think this dispatcher is somehow an anti-pattern.
In distributed architectures based on event sourcing OR CQRS, autonomous components do not have to depend on each others as they share a same event log.
It's not because you are on the same host (the browser/mobile device) that you can't apply these concepts. However having autonomous stores (no store dependencies) means that 2 stores on the same browser will probably have duplicate data as the same data may be needed by 2 different stores. This is a cost to pay but I think in the long term it has benefits as it removes the store dependencies. This means that you can refactor one store entirely without any impact on components that do not use that store.
In my case, I use such a pattern and create some kind of autonomous widgets. An autonomous widget is:
A store that listen to an event stream
A component
A LESS file (maybe useless now because of React Styles?)
The advantage of this is that if there is a bug on a given widget, the bug almost never involve any other file than the 3 mentionned above ;)
The drawback is that stores that host the same data must also maintain it. On some events, many stores may have to do the same action on their local data.
I think this approach scales better to larger projects.
See my insights here: Om but in javascript

When should I use KnockoutJS Components vs. Templates?

So trying to get my hands dirty with KnockoutJS 3.2. I've read the docs and I've successfully implemented components within my current project. I don't use an AMD, so I'm just using script elements to hold the views.
My question is: If i'm not using the asynchronous loading features, is there any real practical difference to using components rather than templates?
General description of both
As stated in the other answer, a template is only a piece of HTML which can be bound to a viewmodel, or viewmodel section. And a component is composed of a template, and its corresponding viewmodel. Besides, this viewmodel, apart from observables can include some simple business logic, and functionality to communicate with the server.
Coupling and encapsulation
Another important difference is the coupling. A template it's bound to the main viewmodel, and its bound to the main viewmodel's observables, so it's highly coupled to the viewmodel: a change in the viewmodel will break the template, and viceversa. So, if you're reusing a template in several places, and you change it, you have to correct the corresponding viewmodels.
A component is bound to its own viewmodel. It's only coupled to the main viewmodel if there are parameters provided from it. This means that you can easily change the component template as well as the component viewmodel, and, if there are no parameters, or you don't change them, nothing will be broken.
So using components helps in decoupling and modularizing.
Communication between main viewmodel and component
The last section is a double edged sword: if there is a high interaction between the main viewmodel and the template or component, it's much easier to use a template, because all the logic and properties are held in the main viewmodel and the interactions are easily implemented. If you used a component you'd need to provide complex parameters, or even make something to allow the component to expose functionality to the main viewmodel.
Polymorphism
It's not strange to have some parts of an application that require different behaviors and visualization to solve the same kind of task. For example, let's imagine you have to implement a payment system in your application: if you accept for example paypal and credit card payment you have two different visualization and functionalities. If you used templates, you'd need to have the particular implementation of each payment system in the main viewmodel. If you used components, they'd share a common interface (parameters) but each of them would have its own implementation. If tomorrow you had to include a new payment system, it would be easy to implement a new component with the common interface.
NOTE: pay attention to the last paragraph
Binding
In the case of a template the binding it's not done at the template level, but inside it. I.e. each element inside the template must be bound to observables of the main viewmodel. In the case of a component the binding is much simpler: at most, it requires the component name and the parameters, if they exist.
Component registration and custom tags
If you register the component you can use custom tags. This makes the views more easyly readable and understandable: instead of specifying the component name in a binding, you use a tag with the component name, and parameters are passed as attributes.
Dynamic loading
If you use templates you have to dynamically load them by yourself, and, as this is an asynchronous task, you'll have to take care of using the template only when it's already available. That's way in most occasions you'll use inline templates. This is not good if they must be reused in several places.
If you have used some AMD implementation, like require.js, and you understand the benefits of this technology, you'll be happy to know that you can easily use AMD to load component templates and viewmodels. One of the advantages is that you don't have to worry about the template or component being available when you need to use them.
Testability
No matter if you do manual or automated tests, it's much easier to test a bunch of independent components, one by one, that to test a complex viewmodel with or without templates.
My choice
So far, I've exposed facts about templates, and components, and I've tried not to show my personal preferences. However, in this last section, I must say that in most situations I prefer to use components for their advantages:
modularity
low coupling
easy reuse
testability
binding syntax
(optional) dynamic loading
However, templates are also a better fit on some occasions
The last paragraph have to do with big applications. If you're dealing with small applications or simply enhancements of interfaces rendered by another technology (like ASP.NET MVC), you'll probably get none of the advantages of using components. So, you don't need them.
There are other cases when it's not worth using components. For example, if you have to show a list (JavaScript array) of items which have different properties which must be shown in a different way, it's easier to use templates. Note that the choice in this case is because each of the instances doesn't have a complex viewmodel with a lot of functionality, but a simple bunch of properties. In this particular case it's not only not worth, but it can also be counterproductive to use components.
You can understand this last example as polymorphism. But, in this case it's nearly "visual" polymorphism. I.e. each kind of item must be shown in a different way, but there is no need to implement any special logic in each of the components.
However, even in this case, if the templates are complex enough, or must be used in many different places, it's also much better to use a simple component that includes the template as well as a parameter that receives the whole item. So, even in this case, it's not a bad idea to use components.
If you'd read this far, thank you, and I hope you have some criteria to help you choosing the best option.
They aren't completely different. Components are made up of templates (html) and data/logic (view model i.e. JavaScript). When you have a modular view you want to attach a view model to you can utilize components. Here's a link discussing components a bit more: http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html

On using mixins in a CoffeeScript game engine

I am working on a CoffeeScript game engine for Html5 canvas. I came up with the "cool" idea to utilize mixins after I checked a very neat CoffeeScript implementation. I thought, it may be a very cool idea to reduce the various hierarchy of objects that game objects usually provide, by developing a set of mixin-based components, each of which has a very specific functionality. Then, when developing an actual game, one could build unique game objects on the fly by basically starting from one component and mixing it with a bunch of other components. This reduces the hierarchies and allows for frequent changes.
Then I thought about the possible collisions that might come up, for example having a few components define a method with the same signature. Now, I am not as excited as before.
What should I do? Is this a good way? I still like it, especially because of JS' underlying prototype mechanism, which allows for such an easy way to combine stuff on the fly.
You're talking about an entity component system. There are a couple written in JS; the most popular is Crafty, which is big but worth looking at. I recently wrote one in CoffeeScript (just for funsies; will probably never release it).
A few notes about collisions:
So first, the problem may be worse than you think: collisions will happen if two methods have the same name; JS doesn't differentiate function signatures. It also might not be so bad: why don't you just create a namespacing convention, where each behavior (meaning method) is named after the component it belongs to, like burnable_burn?
To take a step back though, mixins aren't the only way to build this - behaviors (i.e. things a component can do) don't have to be methods at all. The motivating question I ask is, how do you trigger a behavior? For example, you might do:
if entity.hasComponent "burnable" #hasComponent provided by your framework
entity.burn()
But that doesn't sound right to me; it creates a weird coupling between what's happening in your game and what components you have, and it's awkward to check if your entities implement the relevant component. Instead, I'd like behaviors to be listeners on events:
entity.send("applySeriousHeat") #triggers whatever behaviors are there
And then have your component do whatever it needs to do. So when you add a component to an entity, it registers listeners to events. Maybe it looks like (just sketching):
register: (entity) -> #called when you add a component to an entity
entity.listen "applySeriousHeat", -> #thing I do when this event is sent to me
#do burnination here
To bring that point home, if you do that, you don't care about collisions, because your behaviors don't have names. In fact, you want "collisions"; you want the ability to have more than one component respond to the same event. Maybe it burns and melts at the same time?
In practice, I used both setups together. I made entity.addComponent mix in the component's functions, since it's occasionally convenient to just call a behavior as a method. But mostly, the components declare listeners that call those methods, which helped with decoupling and reduced the awkwardness of having to use scoped names, since I don't call them directly in most cases.

Categories

Resources