The problem to model is this:
A hierarchy of levels within an Army, starting with the national army in whole, through field armies, subunits, and eventually the individual men. Each level may involve links to one or more other classes such as General or Officer or whatever. The units within say a field army need to be able to communicate with each other, especially for purposes of modeling morale, cohesion, etc, as well as with those of any enemy field army (e.g. a unit routing in my army affects the enemy morale positively). Furthermore, each unit needs to communicate with those above and below it in the hierarchy (for obvious purposes).
I was thinking of having the links in the physical hierarchy represented by actual pointers (possibly bilateral) in each of these entities' classes (e.g. army* in each unit and unit* or a whole collection of them in each army) and then making use of the observer design pattern to implement any communication in other cases (such as the case I mentioned above).
However, being no expert in design patterns or programming for that matter I do not know whether there is any other more efficient manner to do this. Any help would be greatly appreciated.
There is a model/design pattern for communicating events between disparate entities that may not know of eachothers existence before the communication happens. The pattern is called 'Publish/Subscribe'.
Each entity sends events it wants to publish to a broker and tells the broker about what kinds of events it would be interested in. The broker handles making sure the subscribing entities learn of events they find interesting that are published.
This is like the Observer pattern, but in the Observer pattern each interested entity subscribes individually to each entity it wants events from. I think this could result in a lot of overhead because that requires everybody to care about creation and destruction of things.
Anyway, there is a nice Wikipedia article on Publish/Subscribe.
I would use the Composite pattern (which basically means a tree of some form) for the individual armies. And possibly Observer for relationships up and down the hierarchy or with siblings. But Observer requires too much registering and unregistering for it to be workable in the general case.
Sounds like "Small Boy With A Pattern" syndrome. You're looking for a pattern instead of thinking about your problem.
The natural data structure for a hierarchy is a tree. I'd start with that.
If the requirement is that every unit in the tree must communicate with all others, I'd say that Observer is not for you. Every unit would have to be register with all the others. You'll have an N-squared firestorm of messages every time an event was fired.
Mediator might be better. Units would send events to the mediator, allowing consumers to register their interest in receiving a particular kind of message. Producers and consumers only know about the mediator, not each other. Loose coupling is your friend.
For modeling the structure, this looks like classic application of the Composite pattern. Then you can use Visitor or Interpreter for modeling the operations on sub-units.
Related
I am doing my own research project, and I am quite struggling regarding the right choice of architectural/design patterns.
In this project, after the "system" start, I need to do something in background (tasks, processing, display data and so on) and at the same be able to interact with the system using, for example, keyboard and send some commands, like "give me status of this particular object" or "what is the data in this object".
So my question is - what software architectural/design patterns can be applied to this particular project? How the interraction between classes/objects should be organized? How should the objects be created?
Can, for example, "event-driven architecture" or "Microkernel" be applied here? Some references to useful resources will be very much appreciated!
Thank you very much in advance!
Careful with design patterns. If you sprinkle them throughout your code hoping that everything will work great, you'll soon have an unreadable, boilerplate full mess. They are recipes, not solutions.
My advice to you is pick a piece of paper and a pencil and start drawing all the entities of your domain, with all their requisites, and see how they relate. If you want to get somewhat serious about it, you can do something like this.
When defining your entities, strive for high cohesion and loose coupling.
High cohesion means that you should keep similar functionalities together. In a very simple example, if you have a class that reads stuff from a file and processes it, the class has low cohesion, since reading and processing are two very distinct functionalities. In this case, you would want a class for each functionality.
As for loose coupling, it means that your entities should be independent of each other. Using the example above, supposed that you are now the proud owner of two highly cohesive classes - one that reads stuff from a file (Reader), and one that processes that stuff (Processor). Now, suppose that the Processor class has an instance of the Reader class, and calls it in order to get its input. In this case, we can say that both classes are tightly coupled, since Processor won't work without Reader. In the OOP world, the solution for this is typically the use of interfaces. You can find a neat example here.
After defining an initial model of your domain and gathering as much knowledge about it as you can, you can now start to think about the implementation's architecture. This is were you can start thinking about the architectural patterns. Event driven architecture, clean architecture, MVP, MVVM... It will all depend on your domain. It is your job to know which pattern will fit best. Spoiler alert: this can be extremely hard to do correctly even for experienced engineers, so don't be afraid to fail.
Finally, leave the design patterns for the implementation stage. Their use completely depends on your implementation problems and decisions. Also, DON'T FORCE THEM. Ideally, you will solve a problem and, IF APPLICABLE, you'll see a pattern emerging. Trust me, the last thing you want is to have a case of design patternitis. Anyway, if you need literature on patterns, I totally recommend this book. It's great no matter your level as an engineer.
Further reading:
SOLID principles
Onion Architecture
Clean architecture
Good luck!
You have a background task, and it can be used for a message pump/event queue indeed. Then your foreground task would send requests to this background thread and asynchronously wait for the result.
Have a look at the book "Patterns for Parallel Programming".
It is much better if you check a book for Design Patterns. I really like this one.
For example, if you need to get some data from a particular object, you may need the Observer Pattern to work for you and as soon as the object has the data, you (or another object) get to know this data and can work with it, with another pattern (strategy might work, it really depends on what you have to do).
If you have to do some things at the same time, check also the Singleton pattern (well, check the most important ones!).
I have been solving following problem. I'm a newbie in C++ and I need to implement
a state machine for an embedded software. This state machine should constitute
core of an application logic. It should control transitions between states
"STANDSTILL", "RUN" and "FAULT" of a controller. These transitions occur based
on: logic inputs state, analog inputs state, messages received over communication lines and messages created internally in the controller's software.
I would like to implement this state machine in such a manner that I utilize the
power of the C++ (object oriented programming). So I have spent some time in
looking for some appropriate design pattern. I have found the "state" desing
pattern but I am not sure whether it is a good choice for me. As far as
I understand the definition in right manner it is intended for situations when I
have some object (so called context object) which behavior (methods of its public interface) is strongly dependent on its state.
My first idea was that the so called context object could be the controller itself. (I mean a class which will realize the software model of the whole device.) The state dependent methods could be the methods asociated with the above mentioned inputs processed by the state machine i.e. logic inputs, analog inputs, messages received over communication lines and internal messages. But I am not sure whether it is good approach. Does anybody have any experience with such usage of the state design pattern? Thanks for any suggestions.
Just because you are using C++, you are not necessarily using object-oriented design. Nor do you have to use OOD when implementing trivial things. It is quite feasible to implement a state machine without involving OOD, since it is such a simple data structure. Basically it is just an array (of function pointers) with named members.
The "pattern" is known as finite state machine. A typical C implementation for embedded systems can be found here. You could write a simple class around that array. State machines in embedded systems are almost always static and read-only, so the class would have to be a "Singleton". You'll find that there's no obvious benefit of using a class here.
the state pattern is a good design to start with. But as mentioned, there are existing tools that can generate the code for you. Another one you could look at is http://scxmlcc.org. This one create code that uses 'the power of C++' and is also based on the state pattern design.
I'm creating a component-based game object system. Some tips:
GameObject is simply a list of Components.
There are GameSubsystems. For example, rendering, physics etc. Each GameSubsystem contains pointers to some of Components. GameSubsystem is a very powerful and flexible abstraction: it represents any slice (or aspect) of the game world.
There is a need in a mechanism of registering Components in GameSubsystems (when GameObject is created and composed). There are 4 approaches:
1: Chain of responsibility pattern. Every Component is offered to every GameSubsystem. GameSubsystem makes a decision which Components to register (and how to organize them). For example, GameSubsystemRender can register Renderable Components.
pro. Components know nothing about how they are used. Low coupling. A. We can add new GameSubsystem. For example, let's add GameSubsystemTitles that registers all ComponentTitle and guarantees that every title is unique and provides interface to quering objects by title. Of course, ComponentTitle should not be rewrited or inherited in this case. B. We can reorganize existing GameSubsystems. For example, GameSubsystemAudio, GameSubsystemRender, GameSubsystemParticleEmmiter can be merged into GameSubsystemSpatial (to place all audio, emmiter, render Components in the same hierarchy and use parent-relative transforms).
con. Every-to-every check. Very innefficient.
con. Subsystems know about Components.
2: Each Subsystem searches for Components of specific types.
pro. Better performance than in Approach 1.
con. Subsystems still know about Components.
3: Component registers itself in GameSubsystem(s). We know at compile-time that there is a GameSubsystemRenderer, so let's ComponentImageRender will call something like GameSubsystemRenderer::register(ComponentRenderBase*).
Observer pattern. Component subscribes to "update" event (sent by GameSubsystem(s)).
pro. Performance. No unnecessary checks as in Approach 1 and Approach 2.
con. Components are badly coupled with GameSubsystems.
4: Mediator pattern. GameState (that contains GameSubsystems) can implement registerComponent(Component*).
pro. Components and GameSubystems know nothing about each other.
con. In C++ it would look like ugly and slow typeid-switch.
Questions:
Which approach is better and mostly used in component-based design? What Practice says? Any suggestions about (data-driven) implementation of Approach 4?
Thank you.
Vote for the third approach.
I am currently working on component-based game object system and i clearly see some of additional advantages of this approach:
The Component is more and more self-sufficing subentity as it depends only on a set of available subsystems (i presume this set is fixed in your project).
Data-driven design is more applicable. Ideally, this way you may design a system where components are completely defined in the terms of data but not C++.
EDIT: One feature i thought about while working on CBGOS. Sometimes it is convenient to have ability to design and construct subsystemless passive components. When this is on your mind the fourth approach is the only way.
My approach was to implement the proxy pattern within each subsystem. As each subsystem is only interested in a subset of the total components each entity may contain, The proxy stores pointers to only the components the system cares about, eg, a motion system only cares about position and velocity, so it needs a proxy which stores two pointers, to those components. If the entity is missing one or more of those, then the subsystem will ignore it. If both components are present, then a proxy node is created and added to an internal collection. It is also useful for the proxy to store the unique identifier value for the entity, so that proxies may be added/removed in constant time from each subsystem, should it be necessary.
In such a way, should an entity be required to be removed from the engine, a single message containing the id of the entity can be sent to every subsystem. The proxy can then be removed from each subsystem collection independently.
So, I've come back to ask, once more, a patterns-related question. This may be too generic to answer, but my problem is this (I am programming and applying concepts that I learn as I go along):
I have several structures within structures (note, I'm using the word structure in the general sense, not in the strict C struct sense (whoa, what a tongue twister)), and quite a bit of complicated inter-communications going on. Using the example of one of my earlier questions, I have Unit objects, UnitStatistics objects, General objects, Army objects, Soldier objects, Battle objects, and the list goes on, some organized in a tree structure.
After researching a little bit and asking around, I decided to use the mediator pattern because the interdependencies were becoming a trifle too much, and the classes were starting to appear too tightly coupled (yes, another term which I just learned and am too happy about not to use it somewhere). The pattern makes perfect sense and it should straighten some of the chaotic spaghetti that I currently have boiling in my project pot.
But well, I guess I haven't learned yet enough about OO design. My question is this (finally. PS, I hope it makes sense): should I have one central mediator that deals with all communications within the program, and is it even possible? Or should I have, say, an abstract mediator and one subclassed mediator per structure type that deals with communication of a particular set of classes, e.g. a concrete mediator per army which helps out the army, its general, its units, etc.
I'm leaning more towards the second option, but I really am no expert when it comes to OO design. So third question is, what should I read to learn more about this kind of subject (I've looked at Head First's Design Patterns and the GoF book, but they're more of a "learn the vocabulary" kind of book than a "learn how to use your vocabulary" kind of book, which is what I need in this case.
As always, thanks for any and all help (including the witty comments).
I don't think you've provided enough info above to be able to make an informed decision as to which is best.
From looking at your other questions it seems that most of the communication occurs between components within an Army. You don't mention much occurring between one Army and another. In which case it would seem to make sense to have each Mediator instance coordinate communication between the components comprising a single Army - i.e. the Generals, Soldiers etc. So if you have 10 Army's then you will have 10 ArmyMediator's.
If you really want to learn O-O Design you're going to have to try things out and run the risk of getting it wrong from time to time. I think you'll learn just as much, if not more, from having to refactor a design that doesn't quite model the problem correctly into one that does, as you will from getting the design right the first time around.
Often you just won't have enough information up front to be able to choose the right design from the go anyway. Just choose the simplest one that works for now, and improve it later when you have a better idea of the requirements and/or the shortcomings of the current design.
Regarding books, personally I think the GoF book is more useful if you focus less on the specific set of patterns they describe, and focus more on the overall approach of breaking classes down into smaller reusable components, each of which typically encapsulates a single unit of functionality.
I can't answer your question directly, because I have never used that design pattern. However, whenever I have this problem, of message passing between various objects, I use the signal-slot pattern. Usually I use Qt's, but my second option is Boost's. They both solve the problem by having a single, global message passing handler. They are also both type-safe are quite efficient, both in terms of cpu-cycles and in productivity. Because they are so flexible, i.e. any object and emit any kind of signal, and any other object can receive any signal, you'll end up solving, I think, what you describe.
Sorry if I just made things worse by not choosing any of the 2 option, but instead adding a 3rd!
In order to use Mediator you need to determine:
(1) What does the group of objects, which need mediation, consist of?
(2) Among these, which are the ones that have a common interface?
The Mediator design pattern relies on the group of objects that are to be mediated to have a "common interface"; i.e., same base class: the widgets in the GoF book example inherit from same Widget base, etc.
So, for your application:
(1) Which are the structures (Soldier, General, Army, Unit, etc.) that need mediation between each other?
(2) Which ones of those (Soldier, General, Army, Unit, etc.) have a common base?
This should help you determine, as a first step, an outline of the participants in the Mediator design pattern. You may find out that some structures in (1) fall outside of (2). Then, yo may need to force them adhering to a common interface, too, if you can change that or if you can afford to make that change... (may turn out to be too much redesigning work and it violates the Open-Closed principle: your design should be, as much as possible, open to adding new features but closed to modifying existent ones).
If you discover that (1) and (2) above result in a partition of separate groups, each with its own mediator, then the number of these partitions dictate the number of different types of mediators. Now, should these different mediators have a common interface of their own? Maybe, maybe not. Polymorphism is a way of handling complexity by grouping different entities under a common interface such that they can be handled as a group rather then individually. So, would there be any benefit to group all these supposedly different types of mediators under a common interface (like the DialogDirector in the GoF book example)? Possibly, if:
(a) You may have to use a heterogeneous collection of mediators;
or
(b) You envision in the future that these mediators will evolve (and they probably will). Hence providing an abstract interface allows you to derive more evolved versions of mediators without affecting existent ones or their colleagues (the clients of the mediators).
So, without knowing more, I'd have to guess that, yes, it's probably better to use abstract mediators and to subclass them, for each group partition, just to prepare yourself for future changes without having to redesign your mediators (remember the Open-Closed principle).
Hope this helps.
Can someone point out the main differences between the two?
It seems that, at least conceptually, the two are very closely related. If I were to hazard a guess, I would say that the publish/subscribe method is a subset of the mediator pattern (since the mediator need not necessarily be used in the publish/subscribe manner, but the latter seems to require a sort of mediator object). Is that anywhere near close to it?
How I would describe the difference is that in mediator you probably care if the end application receives the message. So you use this to guarantee who is receiving the message. Whereas with pub/sub you just publish your message. If there are any subscribers they will get it but you don't care.
According to this page, the publish-subscribe model is an implementation of the mediator pattern.
Edit
I should note that the design patterns are called "patterns" precisely because there are going to be differences among every implementation. They aren't so much a set of decreed, canonical forms as they are a collection of observations on how people already write software. So there really isn't any way for a design to "strictly" adhere to a design pattern.
The implementation could be the same, but logically they are different (The difference is simple, but it is hard to see).
I'll explain it in a simple way below.
Pratically, in the implementation of the Publish/Subscribe pattern you will have at least an object with the methods "publish" and "subscribe".
But you can have also more of them, so the communication between components is not centralized by definition.
In the implementation of the Mediator pattern you will have JUST ONE object with methods "publish" and "subscribe". So the communication is "centralized" by definition.
In the GoF book, publish/subscribe is known as the Observer Pattern. The Mediator Pattern can be implemented using the Observer Pattern; but that is not the only way to implement a Mediator. The book describes this on page 278.
Colleague-Mediator communication. Colleagues have to communicate with their mediator when an event of interest occurs. One approach is to implement the Mediator as an Observer using the Observer pattern. Colleague classes act as Subjects, sending notifications to the mediator whenever they change state. The mediator responds by propagating the effects of the change to other colleagues.
Another approach defines a specialized notification interface in Mediator that lets colleagues be more direct in their communication... When communicating with the mediator, a colleague passes itself as an argument, allowing the mediator to identify the sender.
Note that even when implementing a Mediator as an Observer, it is described as communicating only among its colleagues whereas an Observer in general would likely communicate with other objects as well.
I think one main point of difference is the context of the problem.
Although a problem could be solved with either pattern, the real concerns are:
1: "How much change to bring about by the events are dependent on the general context ?"
2: "How frequently are the listeners expected to change?"
The classical case for the mediator pattern best illustrates this where you have a complex UI with a lot of components and the updation on each has a complex inter-dependency on the state of other similar components.
Although you can solve this problem with the pub/sub pattern; wherein your components listen for events and contain the logic necessary to update, the context object (along with the event) carry all necessary information. Here the advantage is obviously the proper encapsulation of logic pertaining to a component within itself. The downside is that if such components are supposed to change often then you have to replicate this logic fully in each new component you bring in.
To use a mediator is to introduce another layer and further abstract from the components. These components become thinner as they only deal with representation (UI look and feel) thus, become very easy to change. The only problem I have with this approach is that the updation logic now seems to spill to other components and any updation of the system would require one to change the component and the mediator if the component behavior is also to change.
That to me is the major dilemma/trade-off we need to solve. Please correct me if I haven't got anything correctly.