As a learning exercise (I am not in school – just an old guy trying to learn something new), I am trying to write a logic gate simulation that incorporates propagation delay. The user should also be able to group gates together to create higher-level objects.
I want to apply design patterns to my problem, but I am having a hard time.
I am reading Head First Design Patterns, and I see that the Command pattern is a good way to simulate electrical pulses through a circuit with a delay. I also see that the Composite pattern is a good way to simulate nested units. I just don’t know how to mix the two.
In other words, as I loop through my gates, I see that gate ‘x’ should fire. It has a 15 nanosecond delay, so I create a command with a time stamp of 15 ns from current game time. Where is the dispatcher? In the example of the diner, with the command being the ‘Order’, the waitress and the cook each dispatch the command and have the option of introducing a delay. If I have a ‘composite’ gate, does it also have its own dispatcher? Do I need to use a Singleton to manage the queue?
I read what I could find, but I still need a push in the right direction:
- https://stackoverflow.com/questions/2015549/using-command-design-pattern
- https://stackoverflow.com/questions/12016314/client-server-command-design-pattern-with-variable-delays
- https://stackoverflow.com/questions/10560892/composite-of-commands-design-pattern
- https://stackoverflow.com/questions/8874705/how-can-i-calculate-propagation-delay-through-series-of-combinational-circuits-u
5
You may want to look at an example from Programming in Scala, as they have a simulator that does what you are trying to do in Java:
http://www.cs.helsinki.fi/u/wikla/OTS/Sisalto/examples/html/ch30.html#sec6
By looking at their approach you may find how to change your program to get the behavior you want.
You mentioned that you can’t add it easily, so why not explain what your approach is, and what the difficulty that you encounter is, so people can give you some suggestions you may not have considered.
As mentioned, design patterns are ways to talk about what your code is doing, as a shorthand, but the idea of trying to force design patterns in just seems like a bad idea.
Basically a propagation delay shouldn’t be hard.
You can have a base class that is Gate
, and in her put in a delay.
All gates extend from this, and set the actual delay.
Now, when you are following a signal, when in a gate, that thread may sleep for the simulated delay, but this also means you need to map the real-time to your simulated time, as your simulator will be slower than a real system would be.
If you find that you have too many threads, then just put into a sorted list, by next one on top, and when you pause, just put the time the delay is done and on each loop the simulator will pick those that are now ready, do the next action, and then the next delay happens.
This would be similar to a game loop.
In other words, as I loop through my gates, I see that gate ‘x’ should fire.
Then you’re not using the command pattern.
If I have a ‘composite’ gate, does it also have its own dispatcher?
Dear god no. The entire point of the composite pattern is that you can supply a composite object to a location that is expecting merely one object. This allows you to compose behavior in a sane way.
Do I need to use a Singleton to manage the queue?
Hell no. Do you only have one cook and one waitress in the entire world? Do they only have one kitchen?
Mixing the command and composite pattern is fairly straight-forward. You have some interface that represents a command. Each concrete command can override (or otherwise satisfy it in non-inheritance languages) that interface to provide some behavior. Your delay is one such simple behavior.
The composite pattern provides two (or more) objects/behaviors behind a single interface. The simplest use for this example would be a composite command that takes two other commands and then when told to execute, triggers the two stored commands. This way you can take your isolated ‘delay’ command and any arbitrary other command to create a delayed command.