Mobx and multiple stores - mobx

I'm designing a site which has an AV room which also has a bunch of other functionality relating to a medical exam. So, I have a store for the room "ExamStore" which contains domain data and logic for the doctor and patient, the notes the doctor has taken, past exams, etc. I also have two other "managers":
DeviceManager which managers things like cameras, mics, etc which are plugged in
AVManager which manages the actual AV functionality (it's a wrapper over Twilio.)
Now, AVManager I have made observable since it has actions like "muteLocalAudio" and computeds like "localAudioIsMuted".
My question is whether I should have one source of truth, "ExamStore", and expose only that to the UI components. So, if a user clicks a mute button, I would call examStore.muteLocalAudio, which would then simply delegate to avManager.muteLocalAudio. Or, should I just expose AVManager as well to my UI components and have them call avManager.muteLocalAudio directly.
I can see the benefit to both: In the first instance, everything goes through ExamStore, which makes tracking things down easy. Also, it's nice for centralizing everything. On the other hand, DeviceManager, AVManager, and other classes I might come up with have very distinct responsibilities from ExamStore. If I just have ExamStore as a pass through which delegates to them I'm, one, giving ExamStore too much responsibility, and, two, potentially making its surface area quite large.
Anyway, just wondering if there are best practices out there for a scenario like this.

Related

Is it common tradeoff to consider, that interaction between Bounded Contexts may "cripple Open Closed Principle"?

I am implementing interaction between bounded contexts and I found out that it "somehow" cripples open closed principle and I am not sure, whether it is natural consequence of designing BCs and common tradeoff to consider or my design failure.
Consider Shop BC where you can create Order out of Cart with some items. Created order consists of OrderItems, each of them containing one of various types of ItemSpecification Value Object Interface like ProductSpecification or FooServiceSpecification, protecting invariants and containing some data. When Order is created, asynchronous event that can be listened to by any other BC is emitted.
That asynchronous event is created out of Order and is represented as (serialized) OrderCreatedEvent object, containing OrderDTO object, all placed in Core namespace which is shared with every BC so that any BC can depend on Core, but not the other way. All good so far, almost:
That OrderItemDTO must contain interface ItemSpecificationDTO, which need be implemented for every type of specification. My ItemSpecification VO (like any other VO/Entity in Order) has toCoreDTO() method to pragmatically achieve easy translation and it also makes relatively hard to implement new ItemSpecification and forget to implement according DTO. That's probably okay.
But what about other BC's which listen to that Event? In every BC this Event needs to be translated in it's AntiCorruption Layer and that BC may be interested only in some types of ItemSpecificationDTO and translate them to various Value Objects, important for that specific BC.
As Uncle Bob says about OCP in a wit:
You should be able to extend the behavior of a system without having
to modify that system.
But when I implement new type of ItemSpecification, for every BC which may be interested in this new type I need to specifically translate that new type from CoreDTO (okay I could write some abstraction for translating in each BC so I would still be just adding code without modyfying anything like adding if($x instanceof X)). But still, by adding new type of ItemSpecification I need to make appropriate extensions (and maybe even modify something because we don't live in ideal world) in other BCs.
And I do not know how to think about that. Is that downside of whole DDD approach? Or maybe feature indeed, because that hunting for what, where and how needs to be further extended in other BCs, is driven by domain needs instead of technical concerns? It seems right. In the end, I'm trying to do domain driven design :-) But it seems to me somehow dangerous too. I am afraid that one day we can forget to update some other BC and something bad happens. But that is probably because I play big part of domain expert role too, under which that "fear" should probably belong. Is my problem just sitting on two chairs or did I got something wrong? :-)
There are a lot of interesting details about this topic, but I would concentrate here on one specific aspect of bounded contexts.
That is that they are bounded for a reason. As in, there should be a boundary between the models/understanding of these contexts. Two contexts, even if they are related should have a different view on the system, even on the data that might be partly shared.
It seems to me that your "bounded contexts" want to work on the same model. You even created a "core" model which everyone can see and apparently must be able to understand. If this is the case, I'd argue that you lost the benefits of having different contexts, and you are just creating one big application, with one model.
To correct this problem, I think you would need to get rid of any central/core models, and work with "local" (bounded) models in the different contexts/services. When you need to communicate with other components, you need to define a protocol for those two, dictated by either or both parties.
For example a Shopping Cart might need to know the product-id for the backend system to create the order there. But the backend system doesn't need to know the model the shopping cart uses to know what the order is about (in its own model).

Role Based Object-Oriented Design - Controller

I'd like to implement a system that actually encompasses 3, each one varying in functionality by user role type. I.e. a system that allows users to perform different tasks based on their role type; role type determined right at user creation. The users cannot use their role to access other components / features of the system, and the UI is unique for each user.*
I need these "systems" to act independently of each other, but I'm finding some common behavior (most often, opportunities for composition) across the board.
Currently, I have 3 controllers, as this was the original intent of my design - RoleType1Controller, RoleType2Controller, RoleType3Controller. Obviously, these branch out independently, and touch the classes they need to touch.
I'm preparing for some pretty large enhancements in functionality as soon as I get my feet off the ground and need to take these enhancements into consideration, as some of them will be co-driving points of the system. I.e. I want the system to do a couple things, all of equal importance, but can only implement one major feature at this time.
Concerning the OOD, I'm thinking this "three systems in one" approach may be best suited for upcoming changes. However, these opportunities for composition and the desire to keep with standards of having a single controller is weighing heavily on my decision making process.
Does anyone have experience with something like this or, if not, is experienced in OOD and can point me in the right direction? I'm building from the ground up, so (obviously) the framework of the system is being defined in this first iteration. I'd like it to be as robust and flexible as possible.
Any help would be greatly appreciated.
*I am NOT using the UI to drive my design process...I just thought this extra bit of information may be of some help.
The answer, in this case, is to have multiple controllers. Not necessarily by role (though this is how my domain model is currently formed); these should be defined through the process of delegating use case controllers responsibility. I found this through my initial stage of design - defining SSDs and the class diagram.
In Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (an incredible introductory book pulling its context from various, proven best practice definitions and their authors), Craig Larman states there are two ways to approach defining your controllers:
Assign the responsibility to a class representing one of the following choices:
• Represents the overall “system,” a “root object,” a device that the software is running within, or a major
subsystem—these are all variations of a facade controller.
• Represents a use case scenario within which the system event occurs, often named Handler,
Coordinator, or Session (use case or session controller).
• Use the same controller class for all system events in the same use case scenario.
• Informally, a session is an instance of a conversation with an actor. Sessions can be of any length but are
often organized in terms of use cases (use case sessions).
Previous experience has always lead me to the first solution, because the systems I was helping design were of a much lower level of complexity. However, I ran into this issue: bloated controller.
From the same text, Larman proposes this:
Issues and Solutions
Poorly designed, a controller class will have low cohesion—unfocused and handling too many areas of responsibility;
this is called a bloated controller. Signs of bloating are:
• There is only a single controller class receiving all system events in the system, and there are many of them.
This sometimes happens if a facade controller is chosen.
• The controller itself performs many of the tasks necessary to fulfill the system event, without delegating the
work. This usually involves a violation of Information Expert and High Cohesion.
• A controller has many attributes, and it maintains significant information about the system or domain, which should have been distributed to other objects, or it duplicates information found elsewhere.
Among the cures for a bloated controller are these two:
Add more controllers—a system does not have to need only one. Instead of facade controllers, employ use case controllers.
For example, consider an application with many system events, such as an airline reservation system. It may contain the following controllers:
Use case controllers
MakeReservationHandler
Use case controllers
ManageSchedulesHandler
ManageFaresHandler
Design the controller so that it primarily delegates the fulfillment of each system operation responsibility
to other objects.
2) by itself wasn't going to help me because I had actors speaking to the same classes but in their own ways...I was already delegating as much responsibility as I could to other classes while trying to maintain a simple and consistent interaction for the user. As stated before, this lead me to the "bloated controller" issue.
Because OOA/D is an evolving process, I won't be able to say this is my final solution until it's truly implemented. Really, these use case controllers could lead me down a different path...instead of (like) controllers for each (like) use case, I could end up with 3 (or 4 or 5 or 6), and this may be just a means of getting there. But for now, things are going a lot smoother than they were before - I'm beginning to see the realization of the ultimate solution.

How do cross-console games work, codewise?

When a company decides to make a new game cross-console, what happens in terms of the code for the game? I'm thinking of major games i.e. Bioshock, Call of Duty, etc. that run on xbox, ps3, wii and/or PC.
When a game is being designed, does it have to be designed with each platform's API (assuming they all have different APIs)? I just picture it in my head as game companies doing three times the work for three consoles, but I know that must not be right. How do they get essentially the same game on different consoles?
It's all about abstraction, never call the os/console's file api or gfx api directly, abstract it. If you do that you will only have to change your abstractions, and not find every trace of the other os/console in your program, and change it.

What kind of OOP structures work well in an application that has many different modes?

What can I do to structure my application so the code stays manageable as it gets bigger? I am building an application that will be in a certain state which will change depending on how the user interacts with it, and there will be many different states the application can be in. I've tried looking for tutorials/resources, but what I find only covers an application with a couple of modes, whereas mine will have lots of different behaviors.
For instance, you can click on object type A or B, so there can be a different behavior for each. If you hold the mouse down and try to drag one, they will behave differently too. But if you weren't holding your mouse down, that means it's not a drag. It's knowing what mode to move into when X event happens while you're in Y state that has me confused because I don't want to have a massive switch statement that handles everything.
It's not clear what exactly you mean by 'different modes.'
Lots of people spend a ton of time dreaming up abstract structures, behavioral, and organizational patterns for code. Another term for these concepts is design patterns. Aside from cleanly formatting and documenting your code, these concepts help you keep your code logically and functionally clean and operational.
They are well-known and mainstream because they have been proven to work in many implementations; you won't use all of them on every project, but you will probably start using combinations/variations of them if you want to scale. My advice would be to familiarize yourself with these and then reflect on where a particular pattern would work well in your application/state machine.
EDIT: Response to your edits.
For GUI development, in principle, you want to achieve separation of presentation code, behavior code, and state code. Some patterns lend themselves naturally to this end, for example the Model-View-Controller (MVC) pattern.

Event handling in component based game engine design

I imagine this question or variations of it get passed around a lot, so if what I'm saying is a duplicate, and the answers lie elsewhere, please inform me.
I have been researching game engine designs and have come across the component-based entity model. It sounds promising, but I'm still working out its implementation.
I'm considering a system where the engine is arranged of several "subsystems," which manage some aspect, like rendering, sound, health, AI, etc. Each subsystem has a component type associated with it, like a health component for the health subsystem. An "entity," for example an NPC, a door, some visual effect, or the player, is simply composed of one or more components, that when together give the entity its functionality.
I identified four main channels of information passing: a component can broadcast to all components in its current entity, a component can broadcast to its subsystem, a subsystem can broadcast to its components, and a subsystem can broadcast to other subsystems.
For example, if the user wanted to move their characters, they would press a key. This key press would be picked up by input subsystem, which then broadcasts the event and would be picked up by the player subsystem. The player subsystem then sends this event to all player components (and thus the entities those components compose), and those player components would communicate to its own entity's position component to go ahead and move.
All of this for a key press seems a bit winded, and I am certainly open to improvements to this architecture. But anyway, my main question still follows.
As for the events themselves, I considered where an event behaves as in the visitor pattern. The importance of what I want is that if an event comes across a component it doesn't support (as in a move event has nothing directly to do with AI or health), it would ignore the component. If an event doesn't find the component it's going after, it doesn't matter.
The visitor pattern almost works. However, it would require that I have virtual functions for every type of component (i.e. visitHealthComponent, visitPositionComponent, etc.) even if it doesn't have anything to do with them. I could leave these functions empty (so if it did come across those components, it would be ignored), but I would have to add another function every time I add a component.
My hopes were that I would be able to add a component without necessarily adding stuff to other places, and add an event without messing with other stuff.
So, my two questions:
Are there any improvements my design could allow, in terms of efficiency, flexibility, etc.?
What would be the optimal way to handle events?
I have been thinking about using entity systems for one of my own projects and have gone through a similar thought process. My initial thought was to use an Observer pattern to deal with events - I too, originally considered some kind of visitor pattern, but decided against it for the very reasons you bring up.
My thoughts are that the subsystems will provide a subsystem specific publish/subscribe interface, and thus subsystem dependencies will be resolved in a "semi-loosely" coupled fashion. Any subsystem that depends on events from another subsystem will know of the subscriber interface to that subsystem and thus can effectively make use of it.
Unfortunately, how these subscribers get handles to their publishers is still somewhat of an issue in my mind. At this point, I am favoring some kind of dynamic creation where each subsystem is instantiated, and then a second phase is used to resolve the dependencies and put all the subsystems into a "ready state".
Anyway, I am very interested in what worked out for you and any problems you encountered on your project :)
Use an event bus, aka event aggregator. What you want is an event mechanism that requires no coupling between subsystems, and an event bus will do just that.
http://martinfowler.com/eaaDev/EventAggregator.html
http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices
etc
this architecture described here http://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf
There are at least three problems I encountered implementing this in a real project:
systems aren't notified when something happen - only way is to ask about it - player is dead? wall isn't visible? and so on - to avoid this you can use simple MVC instead of observer pattern.
what if your object is a composit (i.e. consists of objects)? system will traverse through all hierarchy and asking about component state.
And main disadvantage is that this architecture mixes all together -for e.g why do player need to know that you pressed a key?
i think that answer is layered architectures with abstracted representation...
Excuse my bad English.
I am writing a flexible and scalable java 3d Game Engine based on Entity-Component System. I have finished some basic parts of it.
First i want to say something about ECS architecture, I don't agree that a component can communicate with other components in a same entity. Components should only store data and systems process them.
In event handling part, I think the basic input handling should not be included in a ECS. Instead, I have a System called Intent System and have a Component called Intent Component which contains many intents. A intent means a entity wants to do something toward a entity.
the Intent System process all the intents, When it processes a intent, it broadcasts the corresponding information to other systems or add other components to the entity.
I also write a interface called Intent Generator. In local game, you can implement a Keyboard Input or Mouse Input Generator and in multiple-player game, you can implement network intent generator. In AI system, you can also generate intents.
You may think the Intent System processes too many things in the game. But in fact, it shares many processing to other systems And I also write a Script System. For specific special entity it has a script component doing special things.
Originally when I develop something, I always want to make a great architecture which includes every thing. But for game developing sometimes it is very inefficient. Different game object may have completely different functions. ECS is great as data-oriented programming system. but we can not include every thing in it for a complete game.
By the way, Our ECS-based game engine will be open source in near future, then you can read it. If u are interested in it, I also invite u to join us.