Design patterns 面向对象/模式:基于环境定制布局
我有一个应用程序,它有细微的差异,这取决于它在哪里被观看 业务逻辑和视图样式的变化很好-这都分别通过依赖项注入和CSS处理 然而,我要解决的问题是视图布局/元素的一些小变化 例如,如果用户在店内信息亭中运行我们的应用程序,我们使用的导航选项与他们在桌面环境或web浏览器中运行的导航选项略有不同。我们可以选择隐藏按钮或导航栏 目前,我正在做以下工作:Design patterns 面向对象/模式:基于环境定制布局,design-patterns,language-agnostic,oop,Design Patterns,Language Agnostic,Oop,我有一个应用程序,它有细微的差异,这取决于它在哪里被观看 业务逻辑和视图样式的变化很好-这都分别通过依赖项注入和CSS处理 然而,我要解决的问题是视图布局/元素的一些小变化 例如,如果用户在店内信息亭中运行我们的应用程序,我们使用的导航选项与他们在桌面环境或web浏览器中运行的导航选项略有不同。我们可以选择隐藏按钮或导航栏 目前,我正在做以下工作: [Inject] public var environment:Environment; public function get labelVis
[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;
}
}
然而,我担心的是环境类泄漏到处都是
我不想过度设计一些东西,但我想知道是否有一种我在这里缺少的合适的设计模式,可以阻止我长时间地
切换…case
或如果…那么
。如果您在接口方面设计视图,您可以在实现中处理这些差异。例如,假设labelVisible
方法位于名为LabelView
的视图中。它将有一个方法labelVisible()
,然后您可能会有一个KioskLabelView
,WebLabelView
和DesktopLabelView
。将根据环境注入正确的视图类。由于差异很细微,我怀疑您的大多数视图类都将在抽象实现中实现,而这些细微的细节将留给子类实现。如何创建一个具有方法签名的抽象类,例如:
public static string DisplayedLabel(Label label, Environment environment)
{
//do checks here, return empty string if it shouldn't be drawn.
}
公共静态字符串DisplayedLabel(标签标签,环境)
{
//在此处进行检查,如果不应绘制,则返回空字符串。
}
然后,当您需要检查时,只需执行以下操作:
string labelText=DrawLabel(Label label, Environment environment);
if (labelText !=String.Empty)
//draw
字符串labelText=DrawLabel(标签标签,环境);
if(labelText!=String.Empty)
//画
注意:将静态方法的签名更改为:
public static bool DrawLabel(Label label, Environment environment,out Label displayedLabel)
{
//do checks here, return empty string if it shouldn't be drawn.
}
公共静态bool DrawLabel(标签标签、环境、外标签显示标签)
{
//在此处进行检查,如果不应绘制,则返回空字符串。
}
也可以从要绘制的每个对象继承,并根据所接收的环境更改其构造函数以构建对象。根据编程语言的不同,我会选择基于属性的方法,通过依赖项注入或某种渲染适配器驱动渲染预处理
例如,在C#/ASP.NET中,我将使用以下方法:
声明页面或自定义控件中所有控件的属性,并使用属性根据环境标记包含或排除;
- 从处理适当页面生命周期事件的所有属性、评估可见性条件并更改控件的可见性和/或其他属性的公共祖先继承所有页面和自定义控件类
伪代码:
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();
}
}
}
}
这就是这个图案的用意