我正在使用 Unity3D 和 C# 创建一个媒体播放器应用程序。
(我的问题与 Unity 无关,纯属设计问题)
这是我目前拥有的:
一个
IApp
接口,带有实现者:TextViewer
ImageViewer
MediaPlayer
一个
IFile
接口,带有实现者:TextFile
ImageFile
MediaFile
- 带孩子:VideoFile
AudioFile
这是界面:
public interface IApp
{
void Open(IFile file);
Type SupportedType { get; }
}
每个应用程序都有可以打开的特定支持的文件类型。
关于 my 的一句话MediaPlayer
,它可以打开/播放音频和视频文件。但是我打开视频的方式与我打开音频的方式不同,因此每种方式都有其独特的逻辑。
现在这是代码 - 非常简单(但尚未完全实现):
public class MediaPlayer : IApp
{
public Type SupportedType { get { return typeof(MediaFile); } }
public void Open(IFile file)
{
if (file is MediaFile)
Console.WriteLine("MediaPlayer opening media file...");
}
List<MediaFile> Medias = new List<MediaFile>();
public MediaFile Current { private set; get; }
public PlaybackControls Controls { private set; get; }
public PlaybackSettings Settings { private set; get; }
public MediaPlayer()
{
Controls = new PlaybackControls(this);
Settings = new PlaybackSettings(this);
}
public class PlaybackControls
{
private MediaPlayer player;
private int index;
public PlaybackControls(MediaPlayer player)
{
this.player = player;
}
public void Seek(float pos) { }
public void Next()
{
index = (index + 1) % player.Medias.Count;
player.Current = player.Medias[index];
}
public void Previous()
{
index--;
if (index < 0)
index = player.Medias.Count - 1;
player.Current = player.Medias[index];
}
private void PlayVideo(VideoFile video)
{
// video logic
}
private void PlayAudio(AudioFile audio)
{
// audio logic
}
public void Play(MediaFile media)
{
IsPlaying = true;
if (media is AudioFile)
PlayAudio(media as AudioFile);
else if (media is VideoFile)
PlayVideo(media as VideoFile);
}
public void Play()
{
Play(player.Current);
}
public void Pause()
{
IsPlaying = false;
}
public void Stop()
{
IsPlaying = false;
Seek(0);
}
public bool IsPlaying { get; private set; }
}
public class PlaybackSettings
{
// Volume, shuffling, looping, etc
}
}
我不太喜欢的是Play(Media)
方法。在里面,我正在检查媒体类型,根据媒体是视频还是音频,我正在调用正确的方法。我不喜欢这样,我觉得这不太对。如果我有其他类型的媒体,比如图片怎么办?如果我想搬到ImageFile
下面MediaFile
怎么办?然后我将不得不添加另一个else-if
语句,它根本不是多态的。
我可以做的是让媒体文件选择要调用的方法,例如:
public abstract class MediaFile : IFile
{
//...
public abstract void Open(MediaPlayer from);
//...
}
public class AudioFile : MediaFile
{
public override void Open(MediaPlayer from)
{
from.PlayAudio(this);
}
}
public class VideoFile : MediaFile
{
public override void Open(MediaPlayer from)
{
from.PlayVideo(this);
}
}
现在在MediaPlayer
:
public void Open(MediaFile media)
{
media.Open(this); // polymorphically open it
}
没有更多的其他 - 如果,很好!但这会带来我不喜欢的其他不便:
VideoFile
&MediaPlayer
和AudioFile
&MediaPlayer
现在耦合得更紧密了。- 现在有一个循环依赖(
MediaPlayer
必须知道Audio/VideoFile
,反之亦然) - 我认为
Audio/VideoFile
s 能够自己打开自己是没有意义的(尽管他们并没有真正这样做,他们只是在告诉MediaPlayer
如何打开它们。MediaPlayer
应该知道如何打开它们,他不知道'不需要任何人告诉他如何做他的工作。) - 感觉很多余,好比叫人指着自己的耳朵,于是右手绕着脑袋,指向了自己的左耳而不是右耳!- 正在发生的事情是我们要去:
任何一个
MediaPlayer.Open(Media) -> AudioFile.Open(AudioFile) -> MediaPlayer.OpenAudio(AudioFile)
或者
MediaPlayer.Open(Media) -> VideoFile.Open(VideoFile) -> MediaPlayer.OpenVideo(VideoFile)
我们以多态的名义绕着自己转,我们可以直接找到正确的方法。
我认为上述两种方法都不是最好的,但如果我要选择一种,我会选择第一种。
你怎么看?有没有更好的办法?- 一种漂亮、优雅、强大的多态方式,用一块石头射杀所有鸟类?我应该怎么做呢?也许我可以在这里使用一种设计模式?
如果我的判断有误,请纠正我。
非常感谢您提前提供的任何帮助。