代码之家  ›  专栏  ›  技术社区  ›  Marty Pitt

面向对象/模式:基于环境的定制布局

  •  2
  • Marty Pitt  · 技术社区  · 15 年前

    我有一个应用程序,有微妙的差异,这取决于它在哪里被查看。

    业务逻辑和视图样式的变化很好-这都是通过依赖注入和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...case if...then 到处都是。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Jeff Storey    15 年前

    如果按照接口设计视图,则可以在实现中处理这些差异。例如,假设 labelVisible 方法位于名为 LabelView . 会有办法的 labelVisible() 然后你可能会有一个 KioskLabelView , WebLabelView DesktopLabelView . 将根据环境注入正确的视图类。因为差异是微妙的,我怀疑大多数视图类将在抽象实现中实现,而这些细微的细节将留给子类实现。

        2
  •  1
  •   Don Roby    15 年前
        3
  •  0
  •   Oren A    15 年前

    如何创建一个带有方法签名的抽象类,例如:

    
    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.
    }
    

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

        4
  •  0
  •   Ondrej Tucny    15 年前

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

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

    1. 声明页或自定义控件中所有控件的属性,并使用属性根据环境标记包含或排除;

    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();
                   }
              }
         }
    }