This is really a code style sort of question, although as I'm using Vue.js for developing my front end, I'm couching it in Vue terms.
I am working on a reasonably complex web application with Vue.js. Even using single file components, I'm finding some of my components (such as a CustomerEditor, for example) are becoming large and unwieldy and increasingly difficult to edit. Now, I come from a Java background (actually in recent years Grails/Groovy), and my instinct is always to isolate anything which might be usable in more than one place into its own class, so as to keep as much as possible to the DRY principle.
And I've been doing this with Vue.js, breaking things out into smaller components where I see the possibility of reuse. Even so, some of the files are still pretty large. So now I'm at the point of considering something I've never really done before, splitting up some of the components into smaller components even when those smaller components are only going to be used once, in this one place, simply for the sake of making the code more readable/editable. I have to say it feels a rather strange path to embark on, and I'm just wondering whether this is common practice among others or not?
It is verry common in Vue.js to split large components into smaller components which are easier to maintain, even if these will not be reused. The following is a quote from the official documentation:
Components are meant to be used together, most commonly in parent-child relationships: component A may use component B in its own template. They inevitably need to communicate to one another: the parent may need to pass data down to the child, and the child may need to inform the parent of something that happened in the child. However, it is also very important to keep the parent and the child as decoupled as possible via a clearly-defined interface. This ensures each component’s code can be written and reasoned about in relative isolation, thus making them more maintainable and potentially easier to reuse.
Note the "making them more maintainable and potentially easier to reuse." at the end.
Another important thing to notice is to keep the parent and child as decoupled as possible. This will also help to make the code easier to understand/maintain. Another thing that will help to make your data-flow easier to understand is to have a one-way data flow.
Related
Since OpenComponents are intended for rendering small reusable components (with a well defined interface) inside a web page, would using an OpenComponent to render the whole page content including nested OpenComponents be a reasonable use case or would it be considered an anti-pattern?
I have seen indeed OC used for whole pages and I have done it myself in the past.
One thing to reason about, in my opinion, is where the boundaries are in regards of modularising different parts as libraries (so, composition during build time) vs OCs (composition during render time).
In my opinion, despite that is a decision that can be easily reversed during the development, it is worth spending some time at the beginning, perhaps with some Proof of concepts, in order to understand how the development experience is in regard of developing, testing, and deploying.
In my experience, when the ownership of the entire OC content is on a specific team, it's ok to have everything inside modularised as libraries, as there is enough autonomy. When instead, multiple parts are owned by different stakeholders, it makes sense to reason about modularising via OCs, because OC makes easy to explicitly establish the contracts between interfaces and gives autonomy to different owners to develop and deploy independently.
In conclusion, I wouldn't say it is an anti-pattern.
I am recently learning Angular 6 with #ngrx/store while one of the tutorial is to use #ngrx/store for state management, however I don't understand the benefit of using #ngrx/store behind the scene.
For example, for a simple login and signup action, previously by using the service(Let's call it AuthService) we might use it to call the backend api, store "userInfo" or "token" in the AuthService, redirect user to "HOME" page and we can inject AuthService in any component where we need to get the userInfo by using DI, which simply that one file AuthService handles everything.
Now if we are using #ngrx/store, we need to define the Action/State/Reducer/Effects/Selector which probably need to write in 4 or 5 files to handle above action or event, then sometimes still we need to call backend api using service, which seems much much more complicated and redundant...
In some other scenario, I even see some page uses #ngrx/store to store the object or list of object like grid data., is that for some kind of in-memory store usage?
So back to the question, why are we using #ngrx/store over service registration store here in Angular project? I know it's for "STATE MANAGEMENT" usage, but what exactly is the "STATE MANAGEMENT"? Is that something like transaction log and When do we need it? Why would we manage it on the front end? Please feel free to share your suggestion or experience in the #ngrx/store area!
I think you should read those two posts about Ngrx store:
Angular Service Layers: Redux, RxJs and Ngrx Store - When to Use a Store And Why?
Ngrx Store - An Architecture Guide
If the first one explains the main issues solved by Ngrx Store, it also quote this statement from the React How-To "that seems to apply equally to original Flux, Redux, Ngrx Store or any store solution in general":
You’ll know when you need Flux. If you aren’t sure if you need it, you don’t need it.
To me Ngrx store solves multiple issues. For example when you have to deal with observables and when responsability for some observable data is shared between different components. In this case store actions and reducer ensure that data modifications will always be performed "the right way".
It also provides a reliable solution for http requests caching. You will be able to store the requests and their responses, so that you could verify that the request you're making has not a stored response yet.
The second post is about what made such solutions appear in the React world with Facebook's unread message counter issue.
Concerning your solution of storing non-obvervable data in services. It works fine when you're dealing with constant data. But when several components will have to update this data you will probably encounter change detection issues and improper update issues, that you could solve with:
observer pattern with private Subject public Observable and next function
Ngrx Store
I'm almost only reading about the benefits of Ngrx and other Redux like store libraries, while the (in my opinion) costly tradeoffs seem to be brushed off with far too much ease. This is often the only reason that I see given: "The only reason not to use Ngrx is if your app is small and simple". This (I would say) is simply incomplete reasoning and not good enough.
Here are my complaints about Ngrx:
You have logic split out into several different files, which makes the code hard to read and understand. This goes against basic code cohesion and locality principles. Having to jump around to different places to read how an operation is performed is mentally taxing and can lead to cognitive overload and exhaustion.
With Ngrx you have to write a lot more code, which increases the chances of bugs. More code -> more places for bugs to appear.
An Ngrx store can become a dumping ground for all things, with no rhyme or reason. It can become a global hodge podge of stuff that no one can get a coherent overview of. It can grow and grow until no one understands it any more.
I've seen a lot of unnecessary deep object cloning in Ngrx apps, which has caused real performance issues. A particular app I was assigned to work on was taking 40 ms to persist data in the store because of deep cloning of a huge store object. This is over two lost render frames if you are trying to hit a smooth 60 fps. Every interaction felt janky because of it.
Most things that Ngrx does can be done much simpler using a basic service/facade pattern that expose observables from rxjs subjects.
Just put methods on services/facades that return observables - such a method replaces the reducer, store, and selector from Ngrx. And then put other methods on the service/facade to trigger data to be pushed on these observables - these methods replace your actions and effects from Ngrx. So instead of reducers+stores+selectors you have methods that return observables. Instead of actions+effects you have methods that produce data the the observables. Where the data comes from is up to you, you can fetch something or compute something, and then just call subject.next() with the data you want to push.
The rxjs knowledge you need in order to use ngrx will already cause you to be competent in using bare rxjs yourself anyways.
If you have several components that depend on some common data, then you still don't need ngrx, as the basic service/facade pattern explicitly handles this already.
If several services depend on common data between them, then you just make a common service between these services. You still don't need ngrx. It's services all the way down, just like it is components all the way down.
For me Ngrx doesn't look so good on the bottom line.
It is essentially a bloated and over engineered Enterprise™🏢👨💼🤮 grade Rxjs Subject, when you could have just used the good old and trusty Rxjs Subject. Listen to me kids, life is too short for unnecessary complexity. Stick to the bare necessities. The simple bare necessities. Forget about your worries and your strife.
I've been working with NgRx for over three years now. I used it on small projects, where it was handy but unnecessary and I used it in applications where it was perfect fit. And meanwhile I had a chance to work on the project which did not use it and I must say it would profit from it.
On the current project I was responsible for designing the architecture of new FE app. I was tasked to completely refactor the existing application which for the same requirements used non NgRx way and it was buggy, difficult to understand and maintain and there was no documentation. I decided to use NgRx there and I did it because of following reasons:
The application has more than one actor over the data. Server uses
the SSE to push state updates which are independent from user
actions.
At the application start we load most of available data which are
then partially updated with SSE.
Various UI elements are enabled/disabled depending on multiple
conditions which come from BE and from user decisions.
UI has multiple variations. Events from BE can change currently
visible UI elements (texts in dialogs) and even user actions might
change how UI looks and works (recurring dialog can be replaced by
snack if user clicked some button).
State of multiple UI elements must be preserved so when user leaves
the page and goes back the same content (or updated via SSE) is
visible.
As you can see the requirements does not meet the standard CRUD operations web page. Doing it the "Angular" way brought such complexity to the code that it became super hard to maintain and what's worst by the time I joined the team the last two original members were leaving without any documentation of that custom made, non NgRx solution.
Now after the year since refactoring the app to use NgRx I think I can sum up the pros and cons.
Pros:
The app is more organized. State representation is easy to read,
grouped by purpose or data origin and is simple to extend.
We got rid of many factories, facades and abstract classes which lost
their purpose. The code is lighter, and components are 'dumber', with
less hidden tricks coming from somewhere else.
Complicated state calculations are made simple using effects and
selectors and most components can be now fully functional just by
injecting the store and dispatching the actions or selecting the
needed slice of the state while handling multiple actions at once.
Because of updated app requirements we were forced to refactor the
store already and it was mostly Ctrl + C, Ctrl + V and some renaming.
Thanks to Redux Dev Tools it is easier to debug and optimize (yep
really)
This is most important - even thought our state itself is unique the
store management we are using is not. It has support, it has
documentation and it's not impossible to find solutions to some
difficult problems on the internet.
Small perk, NgRx is another technology you can put to your CV :)
Cons:
My colleagues were new to the NgRx and it took some time for them to
adapt and fully understand it.
On some occasions we introduced the issue where some actions were
dispatched multiple times and it was difficult to find the cause of
it and fix it
Our Effects are huge, that's true. They can get messy but that's what
we have pull requests for. And if this code wasn't there it would
still end up somewhere else :)
Biggest issue? Actions are differentiated by their string type. Copy
an action, forget to rename it and boom, something different is
happening than you expect, and you have no clue why.
As a conclusion I would say that in our case the NgRx was a great choice. It is demanding at first but later everything feels natural and logical. Also, when you check the requirements, you'll notice that this is a special case. I understand the voices against NgRx and in some cases I would support them but not on this project. Could we have done it using 'Angular' way? Of course, it was done this way before, but it was a mess. It was still full of boiler plate code, things happening in different places without obvious reasons and more.
Anyone who would have the chance to compare those two versions would say the NgRx version is better.
There is also a 3rd option, having data in service and using service directly in html, for instance *ngFor="let item of userService.users". So when you update userService.users in service after add or update action is automatically rendered in html, no need for any observables or events or store.
If the data in your app is used in multiple components, then some kind of service to share the data is required. There are many ways to do this.
A moderately complex app will eventually look like a front end back end structure, with the data handling done in services, exposing the data via observables to the components.
At one point you will need to write some kind of api to your data services, how to get data in and out, queries, etc. Lots of rules like immutability of the data, and well defined single paths to modify the data. Not unlike the server backend, but much quicker and responsive than the api calls.
Your api will end up looking like one of the many state management libraries that already exist. They exist to solve difficult problems. You may not need them if your app is simple.
NGRX sometimes has a lot of files and a lot of duplicate code. Currently working on a fix for this. To make generic type classes for certain NGRX state management situations that are very common inside an Angular project like pagers and object loading from back-ends
Our company is developing a very complex single page app(something like excel) with vue.js. There are 10000+ components(each cell is a component) and each component would have about 100 reactive props(data items). We also use vuex. It works but we are worried about its performance(Indeed it performs a little slowly). We heard that too many reactive data will bring poor performance.
I often hear people said that if it is rewritten by jQuery it will be faster.
My question is: can vue handle so many reactive data? If not, what is the limit? Or if my app performs poorly, is it really caused by vue itself?
if it is rewritten by jQuery it will be faster
Even if that was true, it would make your app harder to maintain. But this statement is a False Dichotomy, as if the choice between the frameworks/libraries were the deciding factor in determining the application's performance. It's not. However if you want to get the best performance, benchmarks have shown time and time again, that a tuned vanilla js application outperforms any framework.
The key to having anything perform well is to design (and implement) properly. While Vue has many performance improvements built in, there are additional things you can do to improve performance, such as use of functional (stateless) components.
You could also consider react, it doesn't come with the out-of-the-box performance tuning that Vue has, but it makes controlling these things easier. The end result (going back to my original point) will still largely depend on your implementation.
The following link proves Vue/Vuex is not the problem, perhaps your design is flawed?
This simple test measures the creation of elements in an array
and the output to the DOM through a sync and an async loop, on a VUEjs
reactive attribute. From the UX point of view, the async method offers
a better experience as it allows for notifications.
Credits to Pablo Garaguso
Like many aspiring designers and programmers out there, I've stumbled upon the Entity/Component System design, including various excellent articles on the subject and a few working implementations as well. And I, like many others, have taken it upon myself to implement such a system.
Conceptually an Entity is a bag of components, which are nothing more than bags of data to be handled by a series of Systems. So it would seem logical to me that an Entity object could be used to hold all components associated with it, but others' work says otherwise. Across all of my research it seems almost universally understood that an Entity is nothing more than an ID and that you must avoid at all costs falling into the trap of Object Oriented thinking. They suggest storing the components in a manager instead, but without directly addressing the advantages of such a design.
Don't both designs, components held in the entity vs. in the manager result in the same end result? Please let me know if I'm misunderstanding / missing something.
I am in no way an expert with Entity Component Systems, but here is my view on the subject from what I have read.
I think that you should never access components directly. If you do, then your components begin to rely one another, and later, when you decide that you want to change how one component behaves, all of the other components relying on the one you want to change now have to be fixed.
To avoid this problem, components should not know anything about each other. They each have one job and should only focus on that job. If some data is needed from another component (for example, you may need positional data), you should either ask another system for the data, or develop a messaging system.
Of course, once you actually start coding, it is hard to comply with this rule 100% of the time, but you get the idea.
Another reason to avoid storing components in an entity is for speed. When components are contained in systems (where all the like-components are stored together), you can process large amounts of components quickly. You have a chance to setup any data they may be reused, loop through and process each component, and then release any reused data. Not only this, but each system may (should) be able to run on a separate thread, which allows you to easily take advantage of multiple cores.
Again, in practice, this isn't always 100% true, but that is the theory of it.
In summary, keeping components in systems rather than in the entity reduces the temptation of directly accessing components, and allows for bulk updates in systems. I hope this helps, and if you have any questions, please let me know.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
What is the difference between module vs. component design?
I'd like to share my idea about this difference.
Both component and module are used to refer to a group of functions or a part of a function. Module is more logical, for example: module Finance, module HR, module Manufacturing... in ERP system. On the other hand, component is more physical. In software, it can be a dll, ocx, exe,...
There is no criteria to measure which one is greater than the other. One component can contain list of modules, and one module also can contain many components. Components are used to model a system in technical view, and module is used to model the system in function view ( functionalities of the system)
Components and modules are too often confused with each other. They
are, however, not the same, and the implications of one, does not
necessarily hold for the other.
Modularity is the partitioning of code into modules of related
functionality. In many programming languages, a module is simply a
source file. It is common practice that if the source file grows too
big, you can split it into two or more source files, and put these
into a new directory; while a directory is often not called a module,
this kind of decomposition is still modular.
A component, on the other hand, can be composed in different ways with
other components to form different programs. That is, there is a
separate composition stage, where real people decide which components
should be used together.
I have seen component design being used to enforce some notion of hard
modularity. This approach cannot be recommended because of the rather
significant overhead of composition: the composition complexity grows
polynomial with the number of components. And the number of
components grows linearly with the number of functionality groups,
because once you get started with modularity by component
decomposition, you force yourself to create a new component whenever
you would otherwise just need a new module, because that new module
would otherwise not really belong anywhere. At a 100 components, the
composition overhead became a full-time job, and each composition
iteration would take up to a couple of weeks, despite numerous
automation efforts. This significantly impeded development.
My simplest recommendation is to stay away from components if at all
possible; well-knowing that components may sometimes be a necessity.
For instance if multiple independent organizations are involved in a
project, one component for each organization seem acceptable.
It is a matter of taste, how fine grained your decomposition into
modules should be, though everyone agrees that modularity is a good
thing.
If I know the name of a function, my editor will find it soon enough.
On the other hand, if for some reason I don't know the name of a
function (or a class for that matter), modularity becomes more
important.
I would expect the later case, to only be an issue for functionality that
you can experience from using the program, so try to make the
decomposition of your program into modules reflect an intuitive
decomposition of the behaviour of your program into areas of
functionality.
There is a reference in the «OSGi in Action» book, which, I believe, explains the differences well.
Modules vs. components
Doesn't it sound like modules and components have a lot in common? They both provide stuff to each other and consume stuff from each other. They're also packaged as independent deployment units. Couldn't these two be considered one and the same or at least be combined? Yes, they could, but components and modules serve different purposes and are somewhat orthogonal (they're not completely orthogonal, because components are made from code that can ultimately be packaged into modules).
Modules deal with code packaging and the dependencies among code. Components deal with implementing higher-level functionality and the dependencies among components. Components need their code dependencies managed, but they technically don't need a module system to do it (often it's us programmers doing it via the class path).
A good summary is that you can think of modules as dealing with static code and compile-time dependencies, whereas components deal with instances and execution-time dependencies.
— «11.1.1 What are components?», «OSGi in Action» (page 347).
If you mean module in the sense of modularity there is a definition in the IEEE Standard Glossary of Software Engineering Terminology:
"Modularity is the degree to which a system or computer program is composed of discrete components such that a change to one component has minimal impact on other components."
And Dr. Bertrand Meyer stated five criteria for modularity:
Decomposability of the problem into sub-problems
Composability of modules to produce new systems
Understandability of a module in isolation
Continuity - small changes have localized effects
Protection - fault isolation
For digital development and UI consideration (HTML/CSS/JS), I use this approach to ensure I'm staying organized and thinking before doing. Has proven to create cleaner, more organized code which translates nicely to doing more with less.
In a typical stylesheet, I'm currently setting up like this:
/* Style Guide – Mobile First
1. =Setup
2. =Modules as independent units made up of components
3. =Components as group of reusable code containing more than one element
4. =Classes
5. =Responsive as enhancement
*/
Modules as independent units made up of components: Header, Footer, Sections, Articles, Aside, etc. A house is made up of many rooms, all with special styles and functions to create an independent whole.
Components as a group of reusable code containing more than one element: Unordered Lists, Quotes, Cards, Tables, etc.
I wrote a fuller explanation you can read here.
Hope this helps!
Component is a runtime entity (can be made up of modules), independent runnable unit
Module is a partitioned system into implementation units, independent task assignment. Modules might or might not be a component
In my view, Module and Component are all just a couple of functions and assets.
And the different between them is:
Component has business logical and module not.
For example,this text input area is just a Module, but when there was some post api called,it become a Component. you can put a module everywhere and it will work fine, but Componet just can be used in a specific page or view(coz it has a specific api call)