我正在使用Unity3D和C#创建一种伪游戏操作系统(有点雄心勃勃)。
UA Crosslink
请注意,这是一个纯设计问题,您可以在不了解Unity的情况下回答。
以下是我的设计:
一个抽象的
现在,我想了一会儿,应该把“谁打开谁”的信息放在哪里呢?我应该让每个文件自己打开吗?通过在
这意味着
这可以通过在
我想到了一个中介者的想法,位于
首先,我应该在字典中使用什么类型的键和值?-我想了一会儿,得出结论应该是类似于
我通过创建一个中间类
抱歉,操作失败了!- 你可以看到,我尽力避免类似的事情:
这对我来说就像是一场噩梦! 为了避免麻烦,我可以将我的应用程序变成单例模式,这样每个文件中:
其余文件同理,但我不想这样做,我不想放弃使用单例!如果我希望我的
我已经苦苦挣扎了很长时间了,希望我表达的问题清晰明了。我只是想知道,如何以正确的方式将文件类型与正确的应用程序关联起来(例如在Windows中)- 如何以优雅、健壮的方式实现我所追求的目标? - 我能使用设计模式来解决这个问题吗? - 我上面的所有尝试,我想得对吗?我离解决方案近了吗?
非常感谢您提前的任何帮助。
以下是我的设计:
一个抽象的
FILE
,具有以下子元素:
TextFile
MediaFile
ImageFile
Application
,具有以下子元素:
TextViewer
MediaPlayer
ImageViewer
TextViewer
应打开TextFile
,MediaPlayer
应打开MediaFile
,ImageViewer
应打开ImageFile
。现在,我想了一会儿,应该把“谁打开谁”的信息放在哪里呢?我应该让每个文件自己打开吗?通过在
FILE
中创建一个抽象的Open
,并在子文件中覆盖它来实现? - 我认为这没有意义,因为一个文件并不真正知道如何打开自己,是应用程序知道如何打开文件。例如,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
或TextViewer
拥有多个实例而不仅仅是一个呢?我已经苦苦挣扎了很长时间了,希望我表达的问题清晰明了。我只是想知道,如何以正确的方式将文件类型与正确的应用程序关联起来(例如在Windows中)- 如何以优雅、健壮的方式实现我所追求的目标? - 我能使用设计模式来解决这个问题吗? - 我上面的所有尝试,我想得对吗?我离解决方案近了吗?
非常感谢您提前的任何帮助。