|
-
February 22nd, 2011, 09:36 AM
#1
Two containers, one class
This isn't specific to C# but I'm working in C# and maybe there's a language-specific solution.
Oh, and it's prob a noob question...
I have a class which looks after two queues. And it must expose a number of functions with each function adding one element to one of the queues. Like this:
Code:
public class Manager : IChores
{
private Queue<string> m_type1Processes;
private Queue<string> m_type2Processes;
public void IChores.WashDishes ()
{
m_type1Processes.Enqueue("Fill sink");
}
public void IChores.ChangeOil ()
{
m_type2Processes.Enqueue("Buy oil");
}
}
And yeah, there does need to be two queues because the times and circumstances in which processes are Dequeued is quite different in the two types.
Some of the queue-processing logic may look a little like this:
Code:
private void UpdateType1Queue ()
{
lock(m_type1QueueLock)
{
if (m_type1Queue.Count == 0)
{
// Do something
}
else
{
// Do something else
}
}
}
So, the issue is that all this code is very error-prone. My queues are not really called "type1" and "type2", but nonetheless it would be easy to mistype and add an element to the wrong queue, and it would create an insidious bug.
And similar mistypes could happen anywhere within the queue-processing logic.
Bearing in mind that I can't change IChores, what's the best way to make this code less error-prone, i.e. make the association between method and queue more overt?
And for processing, is there a way to explicitly say "This function deals with *this* queue, and any attempt to touch the other queue is an error"?
thanks
-
February 23rd, 2011, 04:16 AM
#2
Re: Two containers, one class
Wow, no takers. I'm quite surprised.
As I see it, back in C++ there'd be two ways around this:
1. Make the queues private to a contained class, but make functions like WashDishes() friends of the relevant queue. This greatly reduces the chance of mistyping, since it's necessary to say *twice* which queue a function uses, plus it gives me a nice, neat area of the class where I can see functions mapped to the queues.
2. Split the class in two. One class for each queue.
Here though, I can't do either. C# has no friends , and the fact I can't change IChores means it's pointless splitting the class (the class which implements the interface would have to choose which class to delegate to, and the mistyping issue remains).
-
February 23rd, 2011, 07:59 AM
#3
Re: Two containers, one class
The only way to protect against mistyping is to write unit tests which verify that things are queue/dequeued correctly. That does seem like the best option in your case.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
February 23rd, 2011, 09:31 AM
#4
Re: Two containers, one class
Well, I figured a somewhat hacky way to do it.
I realised you can "simulate" friend functions using reflection and a lookup table. So I can have a private class that accesses the queues on the basis of their method name, like this:
Code:
class QueueContainer
{
private Queue<string> m_queues[];
private const Dictionary<string, int> kLUT = new Dictionary<string, int>()
{
{"WashDishes", 0},
{"ChangeOil", 1}
};
public Queue<string> QueueGet (string methodName)
{
if (kLUT.ContainsKey(methodName))
{
// return appropriate queue
}
else
{
// throw an error
}
}
...and you would use it thus:
Code:
Queue queue = m_container.getQueue(MethodBase.GetCurrentMethod().Name);
queue.Enqueue(task);
...erm, I'm not going to use it, because it is a little hacky (what if someone changes a method name)?
But it's the kind of thing I'm trying to find: it explicitly declares which method belongs to which queue, and it forces each method to use one queue only.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|