OS设计问题:程序关联的文件类型
我在用Unity3D和C#来建立一个伪游戏操作系统
UA Crosslink
请注意这是一个纯粹的设计问题,没有Unity相关知识也可以回答。
这是我所拥有的:
概要文件夹,有子:
- TextFile
- MediaFile
- ImageFile
另外,概要应用,有子:
- TextViewer
- MediaPlayer
- ImageViewer
很明显,TextViewer应该打开TextFile, MediaPlayer应该打开MediaFile,ImageViewer应该打开ImageFile。
现在,我想了一会,我应该把“谁打开谁”这一信息放在哪里?在文件夹里创建一个开始概要,并在子文件夹重写?我认为那没有意义,因为一个文件夹,不会知道去打开它自己,是应用知道怎样打开一个文件夹。例如:一个PDF文件,如果没有PDF Reader(Adode或者其他的什么),你就不能打开PDF。
这意味着TextViewer应该有一个打开(TextFile文本)的方法,MediaPlayer应该有一个打开(MediaFile媒体)的方法,ImageViewer应该有个打开(ImageFile图片)的方法。
这可以在应用程序声明中通过泛型来实现,例如:
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表的大概样子:
看起来还不错,现在到了有趣的部分,怎样绑定/关联每个文件类型,用正确的程序打开?也就是说,邮件单机文本文件| 出现选择列表"Open", "Rename", "Delete"等| 选择 "Open" – 接下来发生什么?
我想到一个主意,在文件和应用之间调停,想一下,一个真正的操作西戎,就像Windows那样是如何做的?如果执行开始| 默认程序| 关联文件类型或关联程序协议,你将看到一个字典类型列表,有键(文件类型)和值(关联程序),我想到了那样做,创建一个字典,用它注册,应用程序文件类型,这就是我遇到问题的地方。
第一,我的字典里应该用什么样的键和值?我想了一下,觉得应该类似<Type, Application>,但是问题是,我不能只写应用程序本身,我地指定泛型T参数。
我的对应方法是创建inbetweener类应用,然后让应用从它继承:
public abstract class App { }public abstract class Application <T> : App where T : FILE { /* stuff... */ }
OK, 现在我的字典是 <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. //这是我无法应付的地方, APP离没有打开方法
}
}
哎呀,那不起作用!如你所见,我在尽我所能避免如下的事情:
if (file is TextFile) // 用text viewer打开
else if (file is MediaFile)
// 用media player打开
else if (file is ImageFile)
// 用image viewer打开
else if etc
这对我来说简直就是一场噩梦。
我可以制作我的应用程序单例来避免所有麻烦,,所以现在每个文件夹里:
public class TextFile : FILE{
public override void Open()
{
TextViewer.Instance.Open(this);
}
}
对于文件的其他部分也这样。但是我不想那样做,我不想放弃,不想使用单例,如果我想让MediaPlayer或者TextViewer0有不止一个实例该怎么办呢?
我已经纠结这一点很久了,我希望我把我的问题表述清楚了。我只是想知道,关联文件类型的应用程序如何正确工作(例如,就像Window一样)?我怎样才能优雅的实现功能强大的效果?是否有我可以使用的设计类型?我的上述所有尝试,想法是对的吗?我接近正确答案了吗?感谢一切助我推进的建议。
原问题:An OS design issue: File types associated with their appropriate programs
回答:
来自@competent_tech 的回答:
没有把大量的思想融入设计,也不知道Unity,如何真正描绘你的文件,我采用的方法是基于接口的,而不是基于泛型的。
首先,我定义一个借口来定义文件类型,也就是说,IFile,在每个文件夹执行这个。
public interface IFile{
}
public class MediaFile : IFile
{
...
}
接下里,我将定义一个定义我的应用类的接口,也就是说,IApplication,在每个应用执行这个。
public interface IApplication{
Type GetSupportedApplicationType();
void OpenFile(IFile oFile);
}
public class MediaApplication : IApplication
{
#region IApplication Members
public Type GetSupportedApplicationType()
{
return typeof(MediaFile);
}
public void OpenFile(IFile oFile)
{
// do the work
}
#endregion
}
文件夹和应用之间的链接,将会是一个字典,它包含文件的class类型,作为键,以及应用程序的class类型,作为值。
<GetType(MediaFile), GetType(MediaPlayer)>
当调解被传递给文件来执行,它将找到合适应用,通过使用文件类型搜寻字典得到合适的应用类型。
只要找到合适的应用类型,可以使用System.GetActivator创建实例。然后,由于它实现IApplication,你可以给应用执行一个方法,例如OpenFile(IFile)。
唯一的技巧在于创建最初的字典条目。为了实现这一点,我使用映射来收集执行IApplication 的class的列表,
一旦你这样做,你可以用System.GetActivator创建每个class的实例,然后执行一个已知的方法,例如:GetSupportedFileType,返回IApplication 支持的IFile实现完整类型
(下面的代码需要一个快捷方式注册到应用程序,这比执行映射方法更简单)
public static class Mediator{
static private Dictionary<Type, Type> dic = new Dictionary<Type, Type>();
static Mediator()
{
RegisterApp(new MediaApplication());
}
static void RegisterApp(IApplication oApp)
{
dic.Add(oApp.GetSupportedApplicationType(), oApp.GetType());
}
static public void Open(IFile file)
{
Type appType = dic[file.GetType()];
if (appType == null)
{
Console.WriteLine("No application was assigned to open up " + file);
return;
}
IApplication app = (IApplication)System.Activator.CreateInstance(appType);
app.OpenFile(file);
}
}
来自@terrybozzio 的回答:
或许这个对你有用,代替在应用class中声明概要方法,建立泛型,你可以制作一个接口,实现它自己的打开方法,例如:
public interface IFile<T> {
void Open(T path);
}
public abstract class Application
{
//public abstract void Open();
}
public class TextViewer : Application, IFile<TextFile>
{
public void Open(TextFile path)
{
//open textfile....
}
}
public class MediaPlayer : Application, IFile<MediaFile>
{
public void Open(MediaFile path)
{
//open media file...
}
}
public class ImageViewer : Application, IFile<ImageFile>
{
public void Open(ImageFile path)
{
//open imagefile....
}
}
以上是 OS设计问题:程序关联的文件类型 的全部内容, 来源链接: utcz.com/p/189571.html