Reagent - methods of storing ui state together with (or separate from?) server-persisted state? - clojurescript

I'm using multiple atoms within a map called app-state and it's working quite well architecturally so far. The state distributed across those atoms is normalised, reflecting as it is stored in datomic, and of course what the client is initialised with is a specific subset of what's in datomic. This is me preparing the way to try out datascript (which is what gave me the aha moment of why client state is so much better fully normalised, even if not using datascript).
I have a question at this point. We all know that some state in reagent is a reflection of what's in the server's database (typically), but there's also state in reagent concerning solely the current condition of the ui. That state will vanish when the page is re-loaded and there's (typically) no need to store that on the server.
So, I'm looking at my list of atoms and realising that I have some atoms which hold database-record-like maps, i.e. they contain exact reflections of datomic entities, (which arrive by transit), which is great.
But now I notice I also want some ui state per datomic entity.
So the question arises whether to (this seems wrong to me) add some keys to what came from datomic, of the ui state that is irrelevant to datomic, but that the client needs (i.e., dump it into the same nested map). That is entirely possible, but seems wrong, and so suggests.... (this being my idea as of now), How about a parallel atom per "entity", like #<entity-name>-ui, containing a map (or even a vector of maps, if multiple entities), with a set of keys for ui state.
That seems an improvement on what I have ended up with by default as of now, which is separate atom for every piece of ui state (I've avoided component local state up to now). (Currently the ui only holds ui state for one record at a time, so these ui atoms need only be concerned with a single current entity).
But if, say, I made a parallel atom (to avoid mixing ephemeral ui and server state), then ui state could perhaps manageably extend deeper. We could hold, say, ui state per entity so switching current-entity back and forth would remember ui state.
Since this is Stack Overflow, I have to ask a specific question, rather than this just be discussion, so: given what I've described, what are some sensible architectural choices in this case, to store state in reagent?

If you are storing your app state in several component-independent reagent atoms already - you can check https://github.com/day8/re-frame which is a widely-adopted reagent-powered framework exactly for your case. Essentially it stores all the application state in a reagent atom but has a well-developed infrastructure to support coordinated storage and updates. They have brilliant documentation with a great high-level explanation of the idea.
Regarding your initial question about server/ui state separation - I think you should definitely go this way. It'll give you a better way of separating concerns and give you an easier way to update server/ui data separately. It is very easy to achieve this with re-frame by storing both parts of the state under separate top-level keys in re-frame application db. E.g.
{:server {:entity-name ...}
:ui {:entity-name ...}}
and then create suitable subscriptions(see re-frame docs) to retrieve it.

Related

CesiumJS - Entity / Graphics Hierarchie in relation to performance

I am working on a Wysiwyg Editor for CesiumJS content.
The user will be able to create many points, lines and other graphics, connect them according to definable relations and group them in separate Groups.
Now I am wondering what the best practises are in terms of performance.
At the moment I create one PointPrimitiveCollection for each Group
and then add points:
group.points = scene.primitives.add(new Cesium.PointPrimitiveCollection());
and then
group.points.add({
position : cartesian,
...
});
for each new point.
Polygons are created using:
network.hull_polygon = viewer.entities.add({
name : 'xxx',
polygon : {
hierarchy : Cesium.Cartesian3.fromDegreesArray(points_array),
material : color,
...
}
});
polylines similarly.
Now since the Objects can also be dragged around / animated, I was wondering where Cesiums entity logic would come in?
Thanks for all help!
Cesium's Entity logic is useful primarily for objects that move along a known path over time, for example the flight plan of an aircraft in the future, or a GPS recording of the route taken by a vehicle in the past. Such routes can be loaded into the Entity system (often via CZML), and the user can run the simulation time forwards and backwards at arbitrary speeds, to review the routes of all the vehicles. The Entity system owns the logic for updating graphics primitive positions based on simulation time changes.
Entities are also often used as a quick way to make some disparate graphics primitives associate with each other. For example, a polygon, a point, and a label can all be created as a single Entity even if they are three separate graphics primitives at the same location. This saves a bit of effort on the part of the application developer, and doesn't hurt performance too much since the properties involved are all marked as constants, so the Entity layer knows not to update them with simulation time.
But, it sounds like you may have a case where paths are not known in advance. For things like user interactive edits or real-time telemetry being received, the Entity system can't know what's coming up next, so its whole system for updating positions from simulation times is not doing you any good. In that case it may be better to skip the Entities, and deal exclusively with graphics primitives for this. This would mean you need to write your own update function to alter graphics positions as new information is being received, similar to the Entity layer's update functions, but based on your own live inputs instead of recorded paths.
Note that the public "Sandcastle" demos only include Entity demos. But, if you download and build the source for Cesium and run Sandcastle locally from a dev build, a separate tab appears in the Sandcastle Gallery called Development that shows a whole set of demos based on graphics primitives as opposed to Entities. This can be useful for seeing examples of how to control things at this layer.
Hopefully this is helpful in understanding how the different layers of Cesium interact.

Multiple data models in AngularJS app?

I'm currently rebuilding a client's small mobile page, on my own dime, as a way to learn MVC and AngularJS, and in preparation for a much larger project for another client. The page I'm learning on is a single-page online ordering app for a pita restaurant. It allows you to choose from a list of pitas, then a second View allows you to customize your pita with various vegetables, cheeses, sauces, etc., followed by a third View, a form which allows you to submit your order.
My question is about the Model. I've built a system which takes the output from the database of menu items (pitas and toppings) and generates a JSON file, the Model, for Angular to parse and display for the user, but I'm curious where the user's selections will be stored.
Do I create another Model specifically for the user's selections or do I modify the original Model to hold the user's selections in addition to the original data?
This is somewhat complicated question in the sense that there are many variables. I am just going to layout how I would approach the decision:
Modifying the existing model being passed to the client means a few things.
First, it means that I won't have another model to deal with, but that the model is not focused on one thing (SRP violation). It is specifying a model in my domain as well as the relationship it has to another thing, the order. This leads to the object being in odd states in the sense it represents different things at different times/situations.
Second, I will have do do this to all my models that maybe connected to an order. Multiplying the above problem.
Creating a new model to represent an order mean another model to deal with (creating an API/service to manage it as well). The plus side is that I will be able to keep it focused on one thing: tracking an order. This means that my other models don't have to change and I know what the object truly represents at all times.
I obviously lean toward creating a new model because it is extendable/flexible and more clear to understand/support.
This doesn't have much to do with Ng or MVC or JSON. It has more to do with creating your models to most accurately and clearly represent your domain.
There maybe other consideration as well given specifics. Let me know by commenting.

What design pattern is best for an RTS game in AS3?

I'm looking to get some good books on design patterns and I'm wondering what particular pattern you'd recommend for a Realtime Strategy Game (like Starcraft), MVC?.
I'd like to make a basic RTS in Flash at some point and I want to start studying the best pattern for this.
Cheers!
The problem with this kind of question is the answer is it completely depends on your design. RTS games are complicated even simple ones. They have many systems that have to work together and each of those systems has to be designed differently with a common goal.
But to talk about it a little here goes.
The AI system in an rts usually has a few different levels to it. There is the unit level AI which can be as simple as a switch based state machine all the way up to a full scale behavior tree (composite/decorators).
You also generally need some type of high level planning system for the strategic level AI. (the commander level and the AI player)
There are usually a few levels in between those also and some side things like resource managers etc.
You can also go with event based systems which tie in nicely with flash's event based model as well.
For the main game engine itself a basic state machine (anything from switch based to function based to class based) can easily be implemented to tie everything together and tie in the menu system with that.
For the individual players a Model-View-Controller is a very natural pattern to aim for because you want your AI players to be exposed to everything the human player has access to. Thus the only change would be the controller (the brain) without the need for a view obviously.
As I said this isn't something that can just be answered like the normal stackoverflow question it is completely dependent on the design and how you decide to implement it. (like most things) There are tons of resources out there about RTS game design and taking it all in is the only advice I can really give. Even simple RTS's are complex systems.
Good luck to you and I hope this post gives you an idea of how to think about it. (remember balance is everything in an RTS)
To support lots of units, you might employ Flyweight and Object Pool. Flyweight object can be stored entirely in a few bytes in a large ByteArray. To get usable object, read corresponding bytes, take empty object and fill it with data from those bytes. Object pool can hold those usable objects to prevent constant allocation/garbage collection. This way, you can hold thousands of units in ByteArray and manage them via dozen of pooled object shells.
It should be noted that this is more suitable to store tile properties that units, however — tile are more-or-less static, while units are created and destroyed on regular basis.
It would be good to be familiar with a number of design patterns and apply them to the architecture of your game where appropriate.
For example, you may employ an MVC architecture for your overall application, factory pattern for creating enemies, decorator pattern for shop items, etc. Point being, design patterns are simply methodologies for structuring your objects. How you define those object and how you decide how they fit together is non prescriptive.

Business Objects - Containers or functional? [closed]

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
Where I work, we've gone back and forth on this subject a number of times and are looking for a sanity check. Here's the question: Should Business Objects be data containers (more like DTOs) or should they also contain logic that can perform some functionality on that object.
Example - Take a customer object, it probably contains some common properties (Name, Id, etc), should that customer object also include functions (Save, Calc, etc.)?
One line of reasoning says separate the object from the functionality (single responsibility principal) and put the functionality in a Business Logic layer or object.
The other line of reasoning says, no, if I have a customer object I just want to call Customer.Save and be done with it. Why do I need to know about how to save a customer if I'm consuming the object?
Our last two projects have had the objects separated from the functionality, but the debate has been raised again on a new project. Which makes more sense?
EDIT
These results are very similar to our debates. One vote to one side or another completely changes the direction. Does anyone else want to add their 2 cents?
EDIT
Eventhough the answer sampling is small, it appears that the majority believe that functionality in a business object is acceptable as long as it is simple but persistence is best placed in a separate class/layer. We'll give this a try. Thanks for everyone's input...
Objects are state and behavior together. If an object has sensible behavior (e.g., calculating age for a Person from their birth date, or a total tax for an Invoice), by all means add it. Business objects that are nothing more than DTOs are termed an "anemic domain model." I don't think it's a design requirement.
Persistence is a special kind of behavior. What I'm calling "sensible" is business behavior. A business object need not know that it's persistent. I'd say that a DAO can keep persistence separate from business behavior. I don't put "save" in the "sensible" category.
Business objects CAN have business functionality.
Persistence is not a business functionality , but is technical implementation.
Long story short:
Save/Update/Delete/Find etc - keep away from the business objects in a persistence layer.
CalculateSalary, ApplyDiscount etc are business related methods and can be:
methods of the business objects (so BO is self contained representation of entity) or;
separate services implementing particular functionality (so BOs are acting more like DTOs).
As for the point 2.
I should mention that the approach 2.1 tends to make the BOs too bloated and violate SRP. While 2.2 introduces more maintenance complexity.
I usually balance in between 2.1 and 2.2 so that I put trivial things related to the data into Business Objects and create services for a bit more complex scenarious (if there are more than 4 lines of code - make it a service).
This shifts the paradigm of Business Objects to be more Data Transfer Objects instead.
But this all makes project easier to develop, test and maintain.
The answer is the same regardless of platform or language. The key to this question is whether an object should be able to be autonomous or whether it is better for any given behavior to be spread out among objects with more focused responsibility.
For each class the answer might be different. We end up with a spectrum along which we can place classes based upon the Density of Responsibility.
(Level of responsibility for behavior)
Autonomy - - - - - - - - - - - - - - - - - - - Dependence
High
C - <<GOD object>> <<Spaghetti code>>
l -
a -
s -
s -
-
s -
i -
z -
e - <<Template>> <<Framework>>
low
Let's say you favor letting the class perform all the behaviours itself, or as many as you can. Starting on the left side of this graph, when you make your class more autonomous, the size of the class will grow unless you continuously refactor it to make it more generic. This leads to a template. If no refactoring is done, the temdency is for the class to become more "god-like" because if there is some behavior it needs, it has a method for that. The number of fields and methods grow and soon become both unmanageable and unavoidable. Since the class already does so much, coders would rather add to the monstrosity than try to piece it apart and cut the Gordian knot.
The right side of the graph has classes that depend on other classes to a large degree. If the dependency level is high but the individual class is small, that is a sign of a framework; each class doesn't do much and requires lots of dependent classes to accomplish some function. On the other hand, a highly-dependent class that also has a large amount of code is a sign that the class is full of Spaghetti.
The key to this question is to determine where you feel more comfortable on the graph. In any event, individual classes will end up spread out on the graph unless some organizational principle is applied, which is how you can achieve the results of Template or Framework.
Having just written that, I would say that there is a correlation between class size and degree of organization. Robert C. Martin (or "Uncle Bob") covers similar ground with package dependencies in his very thorough paper on Design Principles and Design Patterns. JDepend is an implementation of the ideas behind the graph on page 26 and complements static analysis tools such as Checkstyle and PMD.
I think it makes more sense for business objects to know how to "handle" themselves, then to have to put that burden elsewhere in the system. In your example, the most logical place to deal with how to "save" customer data would be, to me, in the Customer object.
This may be because I consider the database to be the "data container", so I'm in favor of "business objects" being the higher level that protects the data container from direct access AND enforces standard "business rules" about how that data is accessed/manipulated.
We've used Rocky Lhotka's CSLA framework for years and love the way it is designed. In that framework all of the functionality is contained in the objects. While I can see the value of separting the logic out, I don't think we'll switch away from this philosophy anytime soon.
Business objects should be about encapsulating data and associated behaviors of the business entity modeled by that object. Think of it like this: one of the major tenets of object-oriented programming is encapsulating data and associated behaviors on that data.
Persistence is not a behavior of the modeled object. I find development progresses more smoothly if business objects are persistence ignornant. Developing new code and unit testing new code happen more quickly and more smoother if the business objects are not specifically tied to the underlying plumbing. This is because I can mock those aspects and forget about having to go through hoops to get to the database, etc. My unit tests will execute more quickly (a huge plus if you have thousands of automated tests that run with each build) and I will have less stress because I won't have tests failing because of database connection issues (great if you often work offline or remotely and can't always access your database and oh, by the way, those aspects (database connectivity etc.) should be tested elsewhere!).
The other line of reasoning says, no, if I have a customer object I just want to call Customer.Save and be done with it. Why do I need to know about how to save a customer if I'm consuming the object?
Knowing that Customer has a Save method is already knowing how to save a customer object. You haven't avoided the problem by embedding that logic in your business object. Instead, you've made your code base more tightly coupled and therefore harder to maintain and test. Push off the responsibility of persisting the object to someone else.
The Business objects, as they are named, should obviously coutain their own business logic, the dynamic of the business logic among the domain being in the service layer.
On the other side, could the BO be a data container (DTO?) composition and methods; meaning BO are pure functionnal? That could avoid all the conversions between BO and DTO.
In an MVC architecture,
Can we say that Model contains business objects.

Can a Sequence Diagram realistically capture your logic in the same depth as code?

I use UML Sequence Diagrams all the time, and am familiar with the UML2 notation.
But I only ever use them to capture the essence of what I intend to do. In other words the diagram always exists at a level of abstraction above the actual code. Every time I use them to try and describe exactly what I intend to do I end up using so much horizontal space and so many alt/loop frames that its not worth the effort.
So it may be possible in theory but has anyone every really used the diagram in this level of detail? If so can you provide an example please?
I have the same problem but when I realize that I am going low-level I re-read this:
You should use sequence diagrams
when you want to look at the behavior
of several objects within a single use
case. Sequence diagrams are good at
showing collaborations among the
objects; they are not so good at
precise definition of the behavior.
If you want to look at the behavior of
a single object across many use cases,
use a state diagram. If you want
to look at behavior across many use
cases or many threads, consider an
activity diagram.
If you want to explore multiple
alternative interactions quickly, you
may be better off with CRC cards,
as that avoids a lot of drawing and
erasing. It’s often handy to have a
CRC card session to explore design
alternatives and then use sequence
diagrams to capture any interactions
that you want to refer to later.
[excerpt from Martin Fowler's UML Distilled book]
It's all relative. The law of diminishing returns always applies when making a diagram. I think it's good to show the interaction between objects (objectA initializes objectB and calls method foo on it). But it's not practical to show the internals of a function. In that regard, a sequence diagram is not practical to capture the logic at the same depth as code. I would argue for intricate logic, you'd want to use a flowchart.
I think there are two issues to consider.
Be concrete
Sequence diagrams are at their best when they are used to convey to a single concrete scenario (of a use case for example).
When you use them to depict more than one scenario, usually to show what happens in every possible path through a use case, they get complicated very quickly.
Since source code is just like a use case in this regard (i.e. a general description instead of a specific one), sequence diagrams aren't a good fit. Imagine expanding x levels of the call graph of some method and showing all that information on a single diagram, including all if & loop conditions..
That's why 'capturing the essence' as you put it, is so important.
Ideally a sequence diagram fits on a single A4/Letter page, anything larger makes the diagram unwieldy. Perhaps as a rule of thumb, limit the number of objects to 6-10 and the number of calls to 10-25.
Focus on communication
Sequence diagrams are meant to highlight communication, not internal processing.
They're very expressive when it comes to specifying the communication that happens (involved parties, asynchronous, synchronous, immediate, delayed, signal, call, etc.) but not when it comes to internal processing (only actions really)
Also, although you can use variables it's far from perfect. The objects at the top are, well, objects. You could consider them as variables (i.e. use their names as variables) but it just isn't very convenient.
For example, try depicting the traversal of a linked list where you need to keep tabs on an element and its predecessor with a sequence diagram. You could use two 'variable' objects called 'current' and 'previous' and add the necessary actions to make current=current.next and previous=current but the result is just awkward.
Personally I have used sequence diagrams only as a description of general interaction between different objects, i.e. as a quick "temporal interaction sketch". When I tried to get more in depth, all quickly started to be confused...
I've found that the best compromise is a "simplified" sequence diagram followed by a clear but in depth description of the logic underneath.
The answer is no - it does capture it better then your source code!
At least in some aspects. Let me elaborate.
You - like the majority of the programmers, including me - think in source code lines. But the software end product - let's call it the System - is much more than that. It only exists in the mind of your team members. In better cases it also exists on paper or in other documented forms.
There are plenty of standard 'views' to describe the System. Like UML Class diagrams, UML activity diagrams etc. Each diagram shows the System from another point of view. You have static views, dynamic views, but in an architectural/software document you don't have to stop there. You can present nonstandard views in your own words, e.g. deployment view, performance view, usability view, company-values view, boss's favourite things view etc.
Each view captures and documents certain properties of the System.
It's very important to realize that the source code is just one view. The most important though because it's needed to generate a computer program. But it doesn't contain every piece of information of your System, nor explicitly nor implicitly. (E.g. the shared data between program modules, what are only connected via offline user activity. No trace in the source). It's just a static view which helps very little to understand your processes, the runtime dynamics of your living-breathing program.
A classic example of the Observer pattern. Especially if it used heavily, you'll hardly understand the System mechanis from the source code. That's why you use Sequence diagrams in that case. It captures the 'dynamic logic' of your system a lot better than your source code.
But if you meant some kind of business logic in great detail, you are better off with plain text/source code/pseudocode etc. You don't have to use UML diagrams just because they are the standard. You can use usecase modeling without drawing usecase diagrams. Always choose the view what's the best for you and for your purpose.
U.M.L. diagrams are guidelines, not strictly rules.
You don't have to make them exactly & detailed as the source code, but, you may try it, if you want it.
Sometimes, its possible to do it, sometimes, its not possible, because of the detail or complexity of systems, or don't have the time or details to do it.
Cheers.
P.D.
Any cheese-burguer or tuna-fish-burguer for the cat ?