用于在离散行为模式之间切换的模式

时间:2010-09-27 17:23:49

标签: design-patterns user-interface abstraction mvp

设计哲学问题:

  1. 假设我有一个用户控件,用于绘制对象集合特征的图形。
  2. 控件放置在具有长期控制器类的表单上,该控件类公开要绘制的对象集合。
  3. 表单还包含一个控件,允许在“模式”或不同的绘图样式之间切换。从中抽取的对象用于暴露其公共属性的逻辑在不同模式之间根本不同,但控件并不关心这一点。
  4. 将数据初始缓存到对象实例非常费力,并且会导致显示控件的某些功能出现性能问题。
  5. 尽管有不同的逻辑,但对象实例代表了模式更改之前和之后的一组建模变量/事物(无论你想要它们如何)
  6. 第3点中问题的性质表明收集的实例应该作为抽象基础,并且有两个不同的派生类具有不同的内部逻辑。不幸的是,这表明应该在每个模式开关处完全重新生成整个对象集合,浪费时钟周期。

    是否有人有任何关于在基础的不同实现之间传输缓存数据的简洁模式的示例?我考虑了一个重载的构造函数,它接受了基类的一个实例,但是这看起来非常可怕。也许人们不同意并且喜欢这种风格,在这种情况下我会考虑解决问题。

    编辑#1:

    对这个问题的具体细节作了一些澄清;我猜想我原来的问题可能很模糊......

    例如,让控件附加的绑定属性为List<BaseClass> ControllerClass.Items

    让控件询问的属性完成其工作

    double BaseClass.NumericProperty
    IEnumerable<Thing> BaseClass.AggregateProperty
    

    让{至少}两个不同的BaseClass子类称为DerivedClass1DerivedClass2。当控件切换模式时,意图是ControllerClass.Items将表示执行适当内部逻辑以暴露这些属性的项目列表。

    我建议在模式开关内部,即设置Controller.Mode = NewMode,控制器将通过执行类似DerivedClass2的操作来创建一组新的_list_internal[i] = new DerivedClass2(_list_internal[i]),其中_list_internal当前包含一组DerivedClass1,然后引发事件(如INotifyPropertyChanged或其他)以通知控件。 DerivedClass1DerivedClass2的构造函数都将BaseClass作为参数,将其分解以检索两者共有的数据。

    我的问题是,这是一种公认​​的模式;如果不是,为什么不,以及有哪些替代方案,请记住效率以及每次UI做任何事情时都不要丢弃数据的需要。

1 个答案:

答案 0 :(得分:2)

我同意迈克曼的观点,这个问题有点模糊,但据我所知,为了在切换模式时获得最佳性能,你必须接受稍微高一点的启动危机:

  • 控制器应与图形用户控件和模式切换器一起使用。基本上,它变成了页面控制器而不是任务控制器。
  • 控制器应预先水合并维护包含所有显示模式的基础数据的对象集合。这些可以是域模型中的实际对象,也可以是包含从域计算的结果的轻量级DTO集合。
  • 当要求切换模式时,控制器应使用单独的DrawHelper类将数据点转换为图形。每个DrawHelper适用于一种图形模式,它们对控制器看起来都一样(它们从相同的基本类型或接口继承)。这被称为战略模式。

以下是no-nos:

  • 请勿将数据转换为图形点所需的逻辑进入域模型。域模型不应该知道你打算如何使用它的数据,因为如果它确实如此,并且发生了变化,那么当域(它的基本责任,应该是它唯一的一个)没有时,域对象就会改变。 / LI>
  • 每次都不要将数据重新水化,毫无例外。这就是你所知道你要避免的,但要做到这一点,确保你的控制器实际上是“长寿”的;许多Web框架生命周期都会破坏请求之间在服务器端使用的所有内容,只保留“会话”状态,并要求您重新保护控制器。
  • 不要将绘图逻辑放在控制器中;它会变得巨大。你甚至不应该把DrawHelper选择逻辑放在控制器中;相反,让控制器了解一个“工厂”,它可以根据当前模式为它提供所需的DrawHelper。