Динамическая форма без реального ООП или объектов? - PullRequest
4 голосов
/ 22 августа 2011

Я занимаюсь большим рефакторингом проекта, и я задал этот вопрос , чтобы подтвердить / понять направление, в котором я должен идти, и я думаю, что получил ответ, который хотел, а невыбросить годами ценность кода.Итак, теперь начинается задача рефакторинга кода.Я читал книги Мартина Фаулера и Мартина Фезерса, и у них есть много понимания, но я ищу совет относительно конечной цели, где я хочу, чтобы приложение было.

Итак, еще раз повторим приложение, это динамическая система форм, с большим количеством логики проверки и логики данных между полями.Основная вставляемая запись - это набор полей формы на странице.Другая часть этого - «Действия», которые вы можете сделать для человека.Эти «Действия» могут отличаться от клиента к клиенту, и существуют сотни «Действия».Говорят также, что мы можем каким-то образом создать движок, который может в конечном итоге взять на себя другие аналогичные области, где «человек» может быть чем-то другим (например, студентом или сотрудником).Поэтому я хочу построить что-то очень не связанное.У нас одна кодовая база, но разные БД для разных клиентов.Набор полей формы на странице является динамическим, но БД - нет - он преобразуется в конкретную таблицу БД с помощью хранимых процедур.Итак, общий набор полей отправляется в сохраненный процесс, и затем сохраненный процесс решает, что делать с полями (выяснить, к какой таблице он должен перейти).Эти таблицы на самом деле довольно статичны, что означает, что они на самом деле не являются динамическими, и в них есть определенная структура.

Что мне особенно не нравится, так это то, как настроить хороший способ управления динамическими формамистр.Кажется, что большая часть логики будет в коде на странице UI / aspx.cs, потому что его загрузка контролирует веб-страницу.Есть ли какой-то способ, которым я могу сделать это, так что это делается в обтекаемой форме, чтобы страница aspx.cs не была длиной 5000 строк?У меня есть объект 'FORM', и одним из свойств является его '' FIELDS ''.Таким образом, этот объект загружается на бизнес-уровне и на уровне данных, но теперь на переднем крае он должен циклически просматривать ПОЛЯ и выводить элементы управления на страницу.Кроме того, в некотором роде было бы полезно иметь возможность контролировать размещение - не знаю, как получить это в этой модели ...

Кроме того, с другой точки зрения - как я могу «реально» получитьэто в объектно-ориентированную структуру?Потому что технически они могут создавать формы чего угодно.И эти поля формы могут представлять любой объект.Так, например, сегодня они могут создать набор полей формы, которые представляют «человека» - завтра они могут создать набор полей формы, которые представляют «мебель».Как я могу перевести это человеку или предмету мебели (или я должен даже пытаться?).И у меня на самом деле нет контроля над полями формы, потому что они могут создавать что угодно ....

Любой мыслительный процесс был бы действительно полезен - спасибо!

Ответы [ 3 ]

2 голосов
/ 29 августа 2011

Как я могу перевести это человеку или предмету мебели (или я вообще должен пытаться?)

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

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

Object {
  ID
  Name
  ... (clientID, etc.) ...
}

Property {
  ID
  ObjectID
  Name
  DBType (int, string, object-id, etc.)
  FormType ( textbox, checkbox, etc.)
  [FormValidationRegex] <== optional, could be used by field controls
  Value
}

Если вы не можете изменить схему базы данных, вы все равно можете применить следующее к старой системе, используя хранимые процедуры и фиксированные таблицы:

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

foreach(Property p in Object.Properties)
{
  switch(p.FormType)
  {
    case FormType.CheckBox:
      PageForm.AddField(new CheckboxFormField(p.Name, p.Value));
      break;
    case FormType.Email:
      PageForm.AddField(new EmailFormField(p.Name, p.Value));
      break;
    case FormType.etc:
      ...
      break;
  }
}

Конечно, я добавил объект PageForm, а также объекты CheckboxFormField и EmailFormField. Объект PageForm может быть просто заполнителем, а CheckboxFormField и EmailFormField могут быть UserControls или ServerControls.

Я бы не советовал пытаться контролировать размещение. Просто перечислите каждое поле по одному вертикально. В любом случае это становится все более и более популярным, даже со статическими формами, макет которых можно полностью контролировать. Например, большинство форм регистрации соответствуют этому соглашению.

Надеюсь, это поможет. Если я неправильно понял ваш вопрос или вам нужны дальнейшие объяснения, дайте мне знать.

0 голосов
/ 01 сентября 2011

Я нашел XML бесценным для этой же ситуации.Вы можете построить граф объекта в своем коде, чтобы представить форму достаточно легко.Этот граф объектов можно снова легко загрузить / сохранить из БД.

Вы можете превратить свой граф объектов в xml и использовать xslt для генерации HTML для отображения.Теперь вы также можете настроить это преобразование для различных клиентов / версий / и т. Д.Я также храню xml в базе данных для повышения производительности и для предоставления мне функции публикации.

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

Я надеюсь, что все имеет смысл.

0 голосов
/ 22 августа 2011

Не уверен, что понимаю вопрос.Но есть два набора инструментов, подходящих для написания общего кода.Это дженерики, и это отражение - как правило, в сочетании.

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

using System.Reflection;
(...)
public void VisitProperties(object subject)
{
    Type subjectType = subject.GetType();
    foreach (PropertyInfo info in subjectType.GetProperties()
    {
         object value = info.GetValue(subject, null);
         Console.WriteLine("The name of the property is " + info.Name);
         Console.WriteLine("The value is " + value.ToString());
    }
}

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

http://codepatrol.wordpress.com/2011/08/19/129/

Это означает, что вы можете создавать свои собственные пользовательские атрибуты или использовать те, которые уже существуют в .NET Framework, для описания ваших типов.Могут быть использованы атрибуты для указания правил проверки, метки поля и даже размещения поля.

public class Person
{
    [FieldLabel("First name")]
    [ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)] 
    [FormColumn(1)]
    [FormRow(1)]
    public string FirstName{get;set;}

    [FieldLabel("Last name")]
    [ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)]
    [FormColumn(2)]
    [FormRow(1)]
    public string LastName{get;set;}
}

Тогда вы будете использовать метод, описанный в моем блоге, чтобы идентифицировать эти атрибуты и предпринять соответствующее действие - например, поместить их в соответствующую строку, дать правильную метку и так далее.Я не буду предлагать, как решить эти проблемы, но по крайней мере рефлексия - отличный и простой инструмент для получения описательной информации о неизвестном типе.

...