2013-11-11 7 views
0

Я относительно новичок в Java и пытаюсь решить проблему. У меня есть базовый класс, для этого примера можно назвать его полем, и у меня есть еще 3 класса ячеек, наследующих базовый ящик класс. Причина этого в том, что каждый из этих трех ящиков имеет разные характеристики, которые отличает их друг от друга. Давайте сделаем вид, что: Box01 может ТОЛЬКО быть изготовлен из картона и иметь длину от 15 до 30 см. Box02 может ТОЛЬКО изготавливаться из алюминия и иметь длину более 30 см. box03 может ТОЛЬКО быть изготовлен из пластика и иметь длину менее 100 см.Выбор Java-объектов во время выполнения

В рассматриваемой программе пользователь не может выбрать тип коробки специально, но в качестве альтернативы должен предоставить свои требования, и программа должна ответить, если это возможно. Таким образом, пластиковая коробка размером 120 см невозможна, также нет картонной коробки размером 50xm.

Мое текущее решение заключается в использовании, если такие утверждения, как:

if(boxType == 'cardboard' && length >= 15 && length <= 30){ 
    Box = new box01(boxType, length); 
else if(boxType == 'aluminium' && length >= 30){ 
    Box = new box02(boxType, length); 
} 

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

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

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

+4

Подробнее о ** Factory Design Pattern **. Вот ссылка http://www.tutorialspoint.com/design_pattern/factory_pattern.htm – Prateek

+0

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

+0

Причиной наличия отдельных классов для ящиков является, например: Box01 может или не может быть подан в подарок. это специфично для этого окна, и поэтому bool будет передан конструктору box01 true/false. Box02 и Box03 не должны быть полностью украшены подарками, поэтому им не имеет смысла иметь доступ к этой функциональности. Я читаю на заводах в настоящее время. Я могу видеть их полезность, но у них все еще есть инструкции OF для определения правил? Просто, что он будет скрыт внутри фабрики, а не снаружи внутри основного класса и т. Д. – user2981060

ответ

0

Хороший подход для этого было бы структурировать приложение, как это:

  1. Используйте интерфейс или абстрактный класс с основной реализацией для де:

    public interface BoxType(){ //Or BoxFactory or smth like that 
    
        public boolean isApplicable(int userInput1, String userInput2...);  /// If you have more than 1-2 user input elements, create a special object (something like `UserInput`) with the user input/requirements and just pass it. 
    
        public Box buildBox(int userInput1, String userInput2...); 
        ... 
    } 
    
  2. Реализовать каждую коробку тип, определяющий его применимость в методе isApplicable() и как его построить в методе buildBox().

  3. Где бы вы ни находились, чтобы проверить тип коробки, просто перейдите по существующим (зарегистрированным) типам ящиков и проверьте, какой из них применим и как построить.
+0

Разве это не «фабрика», о которой вы говорите :) – Prateek

+0

Да, отсюда комментарий BoxFactory :) Хотя я думаю, что в этом простом случае легче понять, называется ли это типом. –

+0

Привет, Cosmin SD, спасибо за ваши ответы. Сегодня я попытаюсь реализовать этот и вышеупомянутые методы и посмотреть, какой из них лучше всего подходит для меня. Я буду продолжать проверять здесь также и любые дальнейшие комментарии. Я ценю все отзывы. Это очень полезно! – user2981060

0

Это то, что я говорил:

import java.util.Arrays; 
import java.util.List; 

enum Material { 
    CARDBOARD, ALUMINIUM, PLASTIC 
} 

class BoxProperties { 
    public Material material; 
    public double length; 
} 

abstract interface RuleSet { 
    public boolean isSatisfiedBy(BoxProperties props); 
} 

class MyRuleSet implements RuleSet { 
    private final Material material; 
    private final double[] length; 

    public MyRuleSet(Material mat, double minLength, double maxLength) { 
     this.material = mat; 
     this.length = new double[] {minLength, maxLength}; 
    } 

    @Override 
    public boolean isSatisfiedBy(BoxProperties props) { 
     if (props.material != material) return false; 
     if (props.length < length[0] || props.length > length[1]) return false; 
     return true; 
    } 

} 

public class Box { 
    private static final List<? extends RuleSet> rules; 
    public final Material material; 
    public final double length; 

    private Box(BoxProperties props) { 
     this.material = props.material; 
     this.length = props.length; 
    } 

    public static Box createBox(BoxProperties props) 
      throws IllegalArgumentException { 
     for (RuleSet rs : rules) { 
      if (rs.isSatisfiedBy(props)) { 
       return new Box(props); 
      } 
     } 

     //XXX This should probably be made a checked exception 
     throw new IllegalArgumentException(
       "No supported box type can fullfil the requests"); 
    } 

    static { 
     rules = Arrays.asList(
       new MyRuleSet(Material.CARDBOARD, 15, 30), 
       new MyRuleSet(Material.ALUMINIUM, 30, Double.POSITIVE_INFINITY), 
       new MyRuleSet(Material.PLASTIC, 0, 100) 
       ); 
    } 
} 

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

В любом случае, я повторяю, что я не думаю, что вы должны подкласс, потому что класс клиента все равно будет видеть Box.Для того, чтобы определить, если она может быть обернуты, он должен сделать что-то вроде

if (returnedBox instanceof MaybeWrappableBox && ((MaybeWrappableBox)returnedBox).isWrappable()) { 
    ... 
} 

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

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