将UI与数据/逻辑分开

时间:2015-10-07 18:51:36

标签: c#

我正在开发一个文件索引应用程序,该应用程序生成供第三方应用程序使用的文件元数据。为了减少工作集,我使用文件过滤器。每个文件过滤器都包含许多比较器(例如CompareFileName,CompareFile Extension,CompareFileDateCreated)。所有比较器都实现了一个简单的ICompareFile接口。

$flag_to_find = 530;
$flags = array();
for ($i=0; $i<=26; $i++){
  if ($flag_to_find & (1 << $i)){
    array_push($flags, 1 << $i);
  }  
}
print_r($flags);

这适用于原始编码/测试。我遇到的问题是尝试通过用户界面创建编辑器。我的FileFilter类包含ICompareFile实例的列表。所以,我的问题是,当用户从List中选择ICompareFile时,调用编辑器的最佳方法是什么。

最初,我在考虑访问者模式,但是,我可以将比较器委托给一个插件类,其中我将提供基本的,众所周知的实现。简而言之,解决方案必须是可扩展的。

我的目标是将表示与数据分开。例如,我可以通过多种方式显示比较器。但是,数据非常静态。

问题实际上是将编辑器(某种形式)映射到ICompareFile实例。

我的问题是,ICompareFile具体实现应该指定其编辑器还是外部类应该这样做。就个人而言,我认为后者,(SOLID和DRY原则)。

2 个答案:

答案 0 :(得分:1)

一种方法是使用Factory模式。

在您的工厂中,您将注册具体的类及其相应的UI类,例如:

public class FileCompareUIFactory{
// pseudo code, needs work
  private Dictionary<Type,Type> registered = new {
    { typeof(FileCompareNames), typeof(FileCompareNamesUIView)}
  }
  public void Register<C,V> where C: IFileCompare, V: View{
    registered[typeof(C)] = typeof(V);
  }

  public V GetView<C,V>() where C:IFileCompare, V: View {
    // cache already instantiated if needed
    return (V)(Activator.CreateInstance(registered[typeof(C)])
  }
}

您还可以使工厂成为单身人士,并要求所有插件文件比较器在工厂注册

public class FileCompareUIFactory{
  private static FileCompareUIFactory _instance = null;
  public FileCompareUIFactory Instance{
    get{ return (_instance = _instance ?? new FileCompareUIFactory()); }
  }
  protected FileCompareUIFactory(){ }
}

答案 1 :(得分:0)

我建议在这里使用Strategy Pattern,因为您正在创建一个行为由用户组装的算法。您的ICompareFile界面将成为策略的界面,您的过滤器将根据用户选择的内容包含这些界面的集合。