OOP / Pattern:根据环境自定义布局

时间:2010-09-09 20:08:43

标签: design-patterns language-agnostic oop

我的应用程序根据查看的位置有微妙的差异。

业务逻辑的变化&视图样式很好 - 这都是通过依赖注入和处理来处理的。 CSS分别。

但是,我要解决的问题是视图布局/元素的变化很小。

例如 - 如果用户在店内自助服务终端中运行我们的应用程序,我们使用微妙的不同导航选项,而不是在桌面环境中运行它们,或通过Web浏览器。我们可能会选择隐藏按钮或导航栏。

目前,我正在做的事情如下:

[Inject]
public var environment:Environment;

public function get labelVisible():Boolean
{
    switch (environment.channel)
    {
        case Environment.KIOSK :
            return false;
        case Envirnoment.WEB : 
        case Envirnoment.DESKTOP : 
            return true;
     }
 }

但是,我担心环境类会在整个地方泄漏。

我不想过度设计某些东西,但我想知道是否有一个合适的设计模式,我在这里缺少这些设计模式会让我不能长时间switch...caseif...then'到处都是。

4 个答案:

答案 0 :(得分:2)

如果您根据接口设计视图,则可以在实现中处理这些差异。例如,假设labelVisible方法位于名为LabelView的视图中。它会有labelVisible()方法,然后您可能会有KioskLabelViewWebLabelViewDesktopLabelView。将根据环境注入正确的视图类。由于差异很小,我怀疑大多数视图类都将在抽象实现中实现,只有这些细微的细节留给子类实现。

答案 1 :(得分:1)

这就是Abstract Factory模式的用途。

答案 2 :(得分:0)

如何使用方法签名创建抽象类,例如:


public static string DisplayedLabel(Label label, Environment environment)
{
  //do checks here, return empty string if it shouldn't be drawn.
}

然后每当你需要检查时:


string labelText=DrawLabel(Label label, Environment environment);
if (labelText !=String.Empty)
//draw

注意:这可以通过将静态方法的签名更改为:
来改进


public static bool DrawLabel(Label label, Environment environment,out Label displayedLabel)
{
  //do checks here, return empty string if it shouldn't be drawn.
}

您还可以从要绘制的每个对象继承,并根据所接收的环境更改其构造函数以构建对象。

答案 3 :(得分:0)

根据编程语言的Web编程环境,我会选择一种基于属性的方法,通过依赖注入或某种渲染适配器驱动渲染预处理。

例如,在C#/ ASP.NET中我会使用这种方法:

  1. 声明页面或自定义控件中所有控件的属性,并使用属性根据环境标记包含或排除;
    • 从共同的祖先继承所有页面和自定义控件类,该祖先处理合适的页面生命周期事件中的所有属性,评估可见性条件并更改控件的可见性和/或其他属性。
  2. 伪代码:

    public abstract class InEnvironment : Attribute 
    { 
         [Inject]
         public Environment environment;
    
         public bool abstract IsAvailable();
    }
    
    public class IncludeInEnvironment : InEnvironment { … }
    
    public class ExcludeInEnvironment : InEnvironment { … }
    
    public class MyControl : BaseControl
    {
         // Large label is visible only in Kiosk mode
         [IncludeInEnvironment(Environment.KIOSK)]
         public Label LargeLabel { get; set; }
    
         / small label is visible anywhere but in Kiosk mode
         [ExcludeInEnvironment(Environment.KIOSK)]
         public Label SmallLabel { get; set; }
    
         …
    }
    
    public class BaseControl : Control
    {
         // resolve declarative visibility of control before rendering takes place
         public override void OnPreRender()
         {
              // inspect all properties of this instance's class
              foreach (PropertInfo property in this.GetType().GetProperties())
              {
                   // check if the property has at attribute influencing rendering
                   InEvironment attribute = property.GetAttribute(typeof(InEnvironment));
                   if (attribute != null)
                   {
                        // adjust the control's visibility
                        ((Control)property.GetValue(this)).Visible = attribute.IsAvailable();
                   }
              }
         }
    }