【问题标题】:OOP / Pattern: Customizing layout based on environmentOOP / Pattern:根据环境自定义布局
【发布时间】:2010-09-09 20:08:42
【问题描述】:

我有一个应用程序,根据查看位置的不同而存在细微差异。

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

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

例如 - 如果用户在店内信息亭中运行我们的应用程序,我们使用的导航选项与他们在桌面环境中或通过网络浏览器运行时略有不同。我们可以选择隐藏按钮或导航栏。

目前,我正在做类似的事情:

[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;
     }
 }

但是,我担心 Environment 类会到处泄漏。

我不想过度设计某些东西,但我想知道是否有一种合适的设计模式我在这里遗漏了,这将使我避免长时间使用 switch...caseif...then地点。

【问题讨论】:

    标签: design-patterns language-agnostic oop


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这就是 Abstract Factory 模式的用途。

      【讨论】:

        【解决方案3】:

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

        
        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】:

          根据编程语言和 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();
                         }
                    }
               }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多