In my current project, I have a rather funky device, that can perform all kinds of streaming options, for instance, video streaming, audio streaming, and certain kinds of data streaming.
Each device only supports a limited number of each of these streams. For the sake of argument, assume it can support 2 video streams and 1 audio stream.
I designed it somewhat like below. (Most application logic is left out.)
public class FunkyDevice
{
int openVideoStreams;
int openAudioStreams;
public VideoStream openVideoStream(int id)
{
if (openVideoStreams < 2)
{
openVideoStreams++;
return new VideoStream(...);
}
}
public AudioStream openAudioStream(int id)
{
if (openAudioStreams < 1)
{
openAudioStreams++;
return new AudioStream(...);
}
}
}
However, now I need to support more than 1 device. I group these in a user session. Every user session also limits the number of each stream, but of course these numbers are not the same as the device limitations (otherwise the problem would be too easy). For instance, I can have 3 video streams (to either 1, 2, or 3 different devices) and still 1 audio stream.
My best attempt to deal with this is as follows:
public class UserSession
{
int openVideoStreams;
int openAudioStreams;
public VideoStream openVideoStream(int deviceId, int id)
{
if (openVideoStreams < 3)
{
openVideoStreams++;
return getDevice(deviceId).openVideoStream(id);
}
}
public AudioStream openAudioStream(int deviceId, int id)
{
if (openAudioStreams < 1)
{
openAudioStreams++;
return getDevice(deviceId).openAudioStream(id);
}
}
}
As you can see, the public interfaces of FunkyDevice and UserSession are almost identical, except that every method in UserSession has an additional parameter deviceId. In my real application, I have much more than 2 different types of streams (and also want to perform other operations, such as closing the streams), so the interfaces become quite large.
Is there a nicer pattern to facilitate this without introducing this code duplication?
You can make an interface that's generic in terms of the identifier class:
public interface IStreamManager<TIdentifier>{
VideoStream openVideoStream(TIdentifier id);
AudioStream openAudioStream(TIdentifier id);
}
, where for the first you'd have:
public class FunkyDeviceStreamIdentifier {
public int id;
}
And for the second you'd have:
public class UserDeviceStreamIdentifier {
public int deviceId;
public int id;
}
(You may want to make them structs instead, and/or introduce factory methods or implicit conversions that make them easier to deal with)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With