Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent code duplication for almost identical interfaces

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?

like image 777
Vincent van der Weele Avatar asked Jun 08 '26 21:06

Vincent van der Weele


1 Answers

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)

like image 167
Damien_The_Unbeliever Avatar answered Jun 11 '26 09:06

Damien_The_Unbeliever