Шаблон разработки для класса с вверх 100 свойств

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

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

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

Однако конфигурация XML является определенным моим главным объектом неприязни... Я стараюсь избегать его любой ценой.

22
задан Community 23 May 2017 в 11:54
поделиться

17 ответов

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

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

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

Имейте в виду, что абстракция, которую вы выбираете для моделирования проблемы, и абстракция, необходимая для связи с какой-либо другой системой (или бизнес-процессом), не обязательно должны быть одинаковыми. Фактически, часто бывает продуктивно применять шаблон моста , чтобы позволить отдельным абстракциям развиваться независимо.

11
ответ дан 29 November 2019 в 03:26
поделиться

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

удачи :)

0
ответ дан 29 November 2019 в 03:26
поделиться

Словарь? почему бы и нет, но не обязательно. Я вижу тег C #, у вашего языка есть отражение, хорошо для вас. В моем коде Python было несколько таких слишком больших классов, и отражение мне очень помогает:

0
ответ дан 29 November 2019 в 03:26
поделиться

If an entity has a hundred unique attributes than a single class with a hundred properties is the correct thing to do.

It may be possible to split things like addresses into a sub class, but this is because an address is really an entity in itself and easily recognised as such.

A textbook (i.e. oversimplified not usable in the real world) invoice would look like:-

 class invoice:
    int id;
    address shipto_address;
    address billing_address;
    order_date date;
    ship_date date;
    .
    .
    . 
    line_item invoice_line[999];

  class line_item;
    int item_no.
    int product_id;
    amt unit_price;
    int qty;
    amt item_cost;
    .
    .
    .

So I am surpised you dont have at least an array of line_items in there.

Get used to it! In the business world an entity can easily have hundreds and sometimes thousands of unique attributes.

0
ответ дан 29 November 2019 в 03:26
поделиться

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

0
ответ дан 29 November 2019 в 03:26
поделиться

Похоже, для конечного результата вам нужно создать объект счета-фактуры примерно со 100 свойствами. У вас есть 100 таких объектов на каждый случай? Возможно, вам понадобится фабрика, класс, который будет выставлять счет с меньшим набором параметров. Для каждого сценария, в котором релевантны соответствующие поля счета-фактуры, можно добавить другой заводской метод.

1
ответ дан 29 November 2019 в 03:26
поделиться

Я использовал Dictionary для чего-то вроде этого.

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

1
ответ дан 29 November 2019 в 03:26
поделиться

Вы не должны руководствоваться чисто эстетическими соображениями.

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

Если нет реальной ценности в создании этого объекта из частей, что именно достигается за счет сокрытия его функции и назначения?

Это могут быть веские причины:

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

2 - У вас есть другие системы, которые могут использовать различные подмножества полей этого объекта. Здесь повторное использование является мотивирующим фактором.

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

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

1
ответ дан 29 November 2019 в 03:26
поделиться

Хммм ... Все ли они действительно имеют отношение конкретно , а только к счету? Обычно я видел что-то вроде:

class Customer:
.ID
.Name

class Address
.ID 
.Street1
.Street2
.City
.State
.Zip

class CustomerAddress
.CustomerID
.AddressID
.AddressDescription ("ship","bill",etc)

class Order
.ID
.CustomerID
.DatePlaced
.DateShipped
.SubTotal

class OrderDetails
.OrderID
.ItemID
.ItemName
.ItemDescription
.Quantity
.UnitPrice

И все это связывает:

class Invoice
.OrderID
.CustomerID
.DateInvoiced

При печати счета объедините все эти записи вместе.

Если вы действительно должны иметь один класс с более чем 100 свойствами, может быть лучше использовать словарь

Dictionary<string,object> d = new Dictionary<string,object>();
d.Add("CustomerName","Bob");
d.Add("ShipAddress","1600 Pennsylvania Ave, Suite 0, Washington, DC 00001");
d.Add("ShipDate",DateTime.Now);
....

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

6
ответ дан 29 November 2019 в 03:26
поделиться

Было бы слишком много столбцов, если бы ваш класс / таблица, в которой вы их храните, начинает нарушать правила нормализации.

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

2
ответ дан 29 November 2019 в 03:26
поделиться

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

Наличие реальных свойств имеет свои преимущества (тип- безопасность, обнаруживаемость / интеллигентность, возможность рефакторинга), но это не имеет значения, если весь код получает их из другого места, отображает в пользовательском интерфейсе, отправляет в веб-службу, сохраняет в файл и т. д.

3
ответ дан 29 November 2019 в 03:26
поделиться

Это считается плохим ОО-стилем, но если все, что вы делаете, это заполняете объект свойствами, чтобы передать их для обработки, и обработка только считывает свойства (предположительно для создания какого-то другого объекта или обновления базы данных), возможно, вам нужен простой объект POD, имеющий все общедоступные члены, конструктор по умолчанию и никаких других методов-членов. Таким образом, вы можете рассматривать его как контейнер свойств, а не как полноценный объект.

2
ответ дан 29 November 2019 в 03:26
поделиться

Вы можете попытаться «нормализовать» его, как таблицу базы данных. Может быть, поместите все свойства, связанные с адресом, в класс Address , например, - затем добавьте свойство BillingAddress и MailingAddress типа Address в свой Счет-фактура класс. Эти классы могут быть повторно использованы и позже.

33
ответ дан 29 November 2019 в 03:26
поделиться

В этой статье вы можете найти несколько полезных идей о свойствах, названных Стивом Йегге. универсальный шаблон дизайна .

1
ответ дан 29 November 2019 в 03:26
поделиться

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

0
ответ дан 29 November 2019 в 03:26
поделиться

Очевидно, что неправильный дизайн присутствует в системе, которую вы отправляете - ни один счет-фактура не содержит более 100 свойств, которые нельзя сгруппировать в подструктуру. Например, в счете-фактуре будет клиент, а у клиента - идентификатор и адрес. Адрес, в свою очередь, будет содержать улицу, почтовый индекс и т. Д. Но все эти свойства не должны напрямую относиться к счету-фактуре - в счете-фактуре нет идентификатора клиента или почтового индекса.

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

22
ответ дан 29 November 2019 в 03:26
поделиться

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

Простой DTO может выглядеть так:

class Form
{
    public $stuff = array();
    function add( $key, $value ) {}
}

Шлюз таблиц может быть больше похоже на:

class Form
{
    function findBySubmitId( $id ) {} // look up my form
    function saveRecord() {}       // save it for my session
    function toBillingInvoice() {} // export it when done
}

И вы можете довольно легко расширить это в зависимости от того, есть ли у вас варианты счета. (Может оказаться целесообразным добавление метода validate () для каждого подкласса.)

class TPSReport extends Form { 
    function validate() {}
}

Если вы хотите отделить свой DTO от механизма доставки, поскольку механизм доставки является общим для всех ваших счетов, это может быть легко. Однако вы можете оказаться в ситуации, когда существует бизнес-логика в отношении успеха или неудачи счета. И здесь я, наверное, ухожу в сорняки. Но именно здесь и ОО-модель может быть полезной ... Я заплачу копейки, что будут разные счета и разные процедуры для разных счетов, а если представление счетов не работает, вам понадобятся дополнительные процедуры: -)

class Form { 
    function submitToBilling() {}
    function reportFailedSubmit() {}
    function reportSuccessfulSubmit() {}
}
class TPSReport extends Form { 
    function validate() {}
    function reportFailedSubmit() { /* oh this goes to AR */ }
}

Примечание Дэвид Лайвлис отвечает: это хорошее понимание. Часто поля в форме представляют собой собственные структуры данных и имеют свои собственные правила проверки. Таким образом, вы можете довольно быстро моделировать составные объекты. Это позволит связать каждый тип поля с его собственными правилами проверки и обеспечить более строгую типизацию.

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

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

table FormSubmissions (
    id         int
    formVer    int -- fk of FormVersions
    formNum    int -- group by form submission
    fieldName  int -- fk of FormFields
    fieldValue text
)
table FormFields (
    id         int
    fieldName  char
)
table FormVersions (
    id
    name
)
select s.* f.fieldName from FormSubmissions s
left join FormFields f on s.fieldName = f.id
where formNum = 12345 ;

Я бы сказал, что это определенно тот случай, когда вы захотите пересмотреть свой подход, пока не найдете что-то удобное. Надеюсь, у вас есть некоторый контроль над такими вещами, как схема и ваша объектная модель. (Кстати ... эта таблица известна как `` нормализованная ''? Я видел варианты этой схемы, обычно организованные по типу данных ...

1
ответ дан 29 November 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: