ООП / Шаблон: Настройка макета в зависимости от среды - PullRequest
2 голосов
/ 10 сентября 2010

У меня есть приложение, которое имеет небольшие различия в зависимости от того, где оно просматривается.

Вариации в бизнес-логике и стилях представления хороши - все это обрабатывается посредством внедрения зависимостей и 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;
     }
 }

Тем не менее, я обеспокоен тем, что класс окружающей среды протекает повсюду.

Я не хочу что-то чрезмерно проектировать, но мне интересно, есть ли подходящий шаблон проектирования, который я здесь упускаю, который не даст мне долго иметь switch...case или if...then по всему место.

Ответы [ 4 ]

2 голосов
/ 10 сентября 2010

Если вы разрабатываете свои представления с точки зрения интерфейсов, вы можете справиться с этими различиями в реализациях. Например, предположим, что метод labelVisible находится в представлении, называемом LabelView. У него будет метод labelVisible(), и тогда у вас могут быть KioskLabelView, WebLabelView и DesktopLabelView. Правильный класс представления будет введен в зависимости от среды. Поскольку различия незначительны, я подозреваю, что большинство ваших классов представления будут реализованы в абстрактной реализации, и только эти тонкие детали будут оставлены для реализации подкласса.

1 голос
/ 10 сентября 2010

Это то, для чего был создан шаблон Abstract Factory .

0 голосов
/ 10 сентября 2010

В зависимости от языка программирования и среды веб-программирования, я бы выбрал подход, основанный на атрибутах, с предварительной обработкой рендеринга, управляемой путем внедрения зависимостей или какого-либо адаптера рендеринга.

Например, в 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();
               }
          }
     }
}
0 голосов
/ 10 сентября 2010

Как насчет создания абстрактного класса с сигнатурами методов, такими как:

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

А потом, когда вам нужно проверить, просто сделайте:

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

Примечание: это можно улучшить, изменив сигнатуру статического метода на:

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

Вы также можете наследовать от каждого объекта, который хотите нарисовать, и изменять их конструкторы для построения объекта в соответствии с окружающей средой, которую они получают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...