2014-01-16 3 views
1

У меня возникли проблемы с проектированием модуля, может ли кто-нибудь мне помочь?Какой шаблон дизайна и как его использовать с помощью ООП в этом сценарии

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

Требование

Это в основном сельскохозяйственный проект (веб-приложение). Мне нужно создать модуль, в котором происходят некоторые вычисления.

Существуют различные культуры, такие как кукуруза, помидор, окра и т. Д. Каждая из этих культур имеет разные черты.

Каждая черта имеет шкалу измерения, которая находится в целочисленном размере, таком как 200-1000. Теперь предположим, что я посадил урожай и сделал измерения, отмеченные чертами. Теперь я хочу сделать какое-то измерение. Некоторые измерения просты, а некоторые сложны.

Пример

Давайте пример культур кукурузы. Я записал наблюдения по 15 признакам. (Мы будем использовать trait1-trait15 в качестве примера, фактическое имя может быть как plt_ht, YLD и т.д.)

я записал 5 наблюдений для каждого признака:

trait1 trait2 trait3 trait5 trait6..... trait15 
01,02,03,04 01,02,03,04 01,02,03,04 

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

Сложность/центр проблемы

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

Пример: черта YLD имеет формулу, на основе которой я должен вычислить ее значение, что также может зависеть от некоторых других признаков. У каждого другого урожая могут быть разные черты.

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

Мой код должен обрабатывать как простые, так и сложные вычисления. Простые вычисления легки, я беру среднее значение, введенное для характеристики. Проблема возникает, когда мне приходится выполнять сложные вычисления, так как каждый урожай имеет разные черты с собственными формулами, поэтому для расчета я должен проверять урожай, а затем на сложный признак. Поэтому мне нужно жестко указать имя признака сложных признаков. Может ли кто-нибудь сказать мне, как я могу создать это с помощью Java oops [?!?], Чтобы я мог сделать его общим?

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

hasZeroValue = (HashMap<String, ArrayList<String>>) dataValues[1]; 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_70")) { 
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_100")) { 
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_60")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_90")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_120")) { 
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg, dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues); 
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("ELCV_60")) { 

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

ответ

0

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

Некоторые вещи, которые вы делаете, могут быть улучшены сразу же. Ваш шаблон if a && b then x else if a && c then y else if a && d и т.д., может быть изменен на:

if a 
{ 
    if b { x } 
    else if c { y } 

... 
} 

Что еще более важно, если вы можете сделать классы для культур и/или расчетов, вы можете хранить коллекцию таких объектов и использовать их, чтобы заменить последовательность if/then/else. Например: создать хэш-карту объектов, индексированных вашим значением «traitName» выше; вместо if/then/else, получить ссылку на соответствующий объект, используя HashMap.get(), и поместить метод вычисления в этот объект.

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

2

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

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

Идея здесь состоит в том, чтобы распространять ее более удобной для пользователя, что добавит больше урожаев и черт или изменит существующие ветры.


EDIT:

Если у вас есть произвольное число культур/признаков, то писать отдельный класс на урожай не будет решение здесь. И индивидуальность культур будет исходить из определенных свойств и состояний более обобщенных классов.

Однако, если на случай, некоторые урожаи/черты имеют сходные/одинаковые функции/черты (которые я предполагаю, что с тех пор, как вы упомянули около 100 культур/признаков и т. Д.), Вы можете сгруппировать их по отдельному классу. (GrainCrop.class или что-то вдоль линий)

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

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

Из вашего примера, если мы анализируем его, мы можем видеть, что наиболее повторяющиеся свойства есть идентификаторы культур (cropId.equalsIgnoreCase("OK") и cropId.equalsIgnoreCase("TO"))

Так вместо бесчисленное количество раз, проверяя ли идентификатор урожая «К» или «OK «вы можете проверить это один раз и иметь две отдельные ветви для проверки свойств« TO »и« OK ».

Кроме того, если возможно, некоторые культуры имеют один и тот же общий набор операций, то вы могли сгруппировать их под BasicCropOperations.class, а затем, возможно, разделить остальную часть сложных операций в подобные наборы поведения как EnvironmentalCropOperations.class или что-то если, например, были такие вещи, как тепло и влажность.

Идея по-прежнему остается тем же, хотя разделить все на более мелкие модули в разумных пределах. (например: писать 200 классов для разных культур/признаков нецелесообразно)

+0

Я добавил несколько пунктов в конце queestion above.Please посмотрите на него. – Vividata

+0

@vividata это решение должно охватывать это редактирование – Pureferret

0

О риске того, что это рассматривается как легкомысленный ответ или вообще не отвечает ... Не используйте Java для этого, используйте Scala или динамический язык, такой как Ruby. Вы даже использовали правильное название для такого рода вещей в Scala: «черта».

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

Смежные вопросы