我正在使用 Unity3D 和 C# 创建一个伪游戏内操作系统(有点野心)
请注意,这是一个纯粹的设计问题,您可以在不了解 Unity 的情况下回答。
这是我所拥有的:
有孩子的摘要FILE
:
TextFile
MediaFile
ImageFile
此外,还有一个带有孩子的摘要Application
:
TextViewer
MediaPlayer
ImageViewer
显然,TextViewer
应该打开TextFile
s,MediaPlayer
应该打开MediaFile
s和ImageViewer
应该打开ImageFile
s。
现在,我想了想,我应该把谁打开谁的信息放在哪里?我应该让每个文件自己打开吗?通过在 中创建摘要并Open
在FILE
子文件中覆盖它?- 我认为这没有意义,因为文件并不真正知道如何打开自己,它是知道如何打开文件的应用程序。比如一个pdf文件,如果你没有pdf阅读器(Adobe之类的),是无法打开pdf的。
这意味着TextViewer
应该有一个Open(TextFile text)
方法,MediaPlayer
应该有一个Open(MediaFile media)
并且ImageViewer
应该有一个Open(ImageFile image)
方法。
这可以通过在 的声明中使用泛型来实现Application
,例如:
public abstract class Application<T> where T : FILE
{
public abstract void Open(T file);
}
然后:
public class TextViewer : Application<TextFile>
{
public override void Open(TextFile file)
{
Console.WriteLine("TextViewer opening text file...");
}
}
public class MediaPlayer : Application<MediaFile>
{
public override void Open(MediaFile file)
{
Console.WriteLine("MediaPlayer opening media file...");
}
}
public class ImageViewer : Application<ImageFile>
{
public override void Open(ImageFile file)
{
Console.WriteLine("ImageViewer opening image file...");
}
}
下面是 UML 图的样子:
看起来不错......现在有趣的部分,如何绑定/关联,每个文件类型,正确的应用程序应该打开它?即右键单击文本文件| 获取选项列表:“打开”、“重命名”、“删除”等 | 选择“打开”——接下来会发生什么?
我想出了一个想法,在FILE
和Application
- 如果我们想一想,像 Windows 这样的真正的操作系统是如何做到的?- 好吧,如果你开始 | 默认程序 | 将文件类型或协议与程序相关联。- 你会看到一个字典类型列表,键(文件类型)和值(关联程序) - 所以我想这样做,创建一个字典,我用它注册,一个应用程序的文件类型。这就是我被困的地方......
首先,我应该在字典中使用什么类型的键和值?- 我想了一会儿,得出的结论应该是<Type, Application
> - 但问题是,我不能自己写Application
,我必须指定泛型T
参数:(
我通过创建一个中间类来破解它,App
然后让我Application<T>
继承自:
public abstract class App { }
public abstract class Application <T> : App where T : FILE { /* stuff... */ }
好的,现在我可以让我的字典成为<Type, App>
public static class Mediator
{
static private TextViewer tv;
static private MediaPlayer mp;
static private ImageViewer iv;
static private Dictionary<Type, App> dic = new Dictionary<Type, App>();
static Mediator()
{
tv = new TextViewer();
iv = new ImageViewer();
mp = new MediaPlayer();
// register what we have
dic.Add(typeof(TextFile), tv);
dic.Add(typeof(MediaFile), mp);
dic.Add(typeof(ImageFile), iv);
}
static public void Open(FILE file)
{
App app = dic[file.GetType()];
if (app == null)
{
Console.WriteLine("No application was assigned to open up " + file);
return;
}
app. // here is where my hack falls short, no Open method inside App :(
}
}
哎呀,这完全没用!- 如您所见,我正在尽力避免以下事情:
if (file is TextFile)
// open with text viewer
else if (file is MediaFile)
// open with media player
else if (file is ImageFile)
// open with image viewer
else if etc
这对我来说就像一场噩梦!
通过使我的应用程序成为单例,我可以避免所有麻烦,所以现在在每个文件中:
public class TextFile : FILE
{
public override void Open()
{
TextViewer.Instance.Open(this);
}
}
其余的文件依此类推。但我不想那样做,我不想放弃使用单例!如果我希望我的MediaPlayer
orTextViewer
有多个实例而不是一个实例怎么办?
我已经为此苦苦挣扎了很长时间,希望我能弄清楚我的问题。我只是想知道,将文件类型与正确的应用程序相关联如何以正确的方式工作(例如在 Windows 中) - 我怎样才能以优雅、强大的方式实现我所追求的?- 有没有我可以使用的设计模式?- 我上面所有的尝试,我想对了吗?我接近解决方案了吗?
非常感谢您提前提供的任何帮助。