Пример странного ООП
От: sobakam  
Дата: 23.07.12 09:24
Оценка:
Приветствую!
Лазил по форуму, наткнулся на закрытую тему...
http://www.rsdn.ru/forum/java/3945199.flat.2.aspx

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

От:     Other Sam     
Дата:     03.09.10 12:44
    Оценка:    7 (1) +1
...
SD>Определить иерархию цветов. Создать несколько объектов-цветов. Собрать букет с определением его стоимости.
 ... поскипано ...

 В такой постановке задача не имеет сколько нибудь обоснованного решения.
 Вот примерное решение с разъяснением на какие грабли наступаем, и какие обходим.
// 1. Я решил запихать все что можно в абстрактный базовый класс
// чтобы код конкретных цветочков был как можно короче.
// 2. Хотя нет абстрактных методов, все равно класс помечен как абстрактный,
// чтобы никто не подумал добавлять неконкретный цветочек в букет.
public abstract class Flower {
    private final String name;
    private final BigDecimal price; // Деньги это не вещественные цисла. Поэтому для их подсчета
                                    // нужно всегда использовать какой-то целочисленный тип.

    protected Flower(String name, BigDecimal price) {
        this.name = name;
        this.price = price;
    }

    // 3. Общие методы для всех цветочков перенесены сюда.
    // (чтобы не дублировать в каждом цветочке)
    public String getName() {
        return name;
    }

    // 4. А вот этот метод относится не к цветочку, а к товару!!!
    // Здесь у нас произошло смешивание понятий. Цена это атрибут товара
    // а не растения!!! Но поскольку смешались оставим пока так.
    public BigDecimal getPrice() {
        return price;
    }
}

public class Rose extends Flower {
  // 5. собственно конкретный класс цветов
  public Rose() {
    super("Rose", BigDecimal.valueOf(5.22).setScale(2, RoundingMode.HALF_EVEN));
  }
}

public class Tulip extends Flower {
  public Tulip() {
    // Реально при работе с деньгами я видел две стратегии.
    // Использовать рубли/копейки (т.е. 2 знака после запятой)
    // или использовать 4 цифры после запятой.
    // Здесь я использую 2 цифры после запятой.
    // Кстати это является потенциально опасным местом
    // В коде закодированно вещественное число 1.27, которое затем округляется
    // до целочисленного 1.27
    // По идее точнее было-бы
    // BigDecimal.valueOf(127).divide(BigDecimal.valueOf(100), RoundingMode.HALF_EVEN)
    //   .setScale(2, RoundingMode.HALF_EVEN)
    // Но такой код очень сложно читать. Так что я через float задал.
    super("Tulip", BigDecimal.valueOf(1.27).setScale(2, RoundingMode.HALF_EVEN));
  }
}

// 6. Собственно класс букетика.
// Поскольку нужно "собрать" букет и посчитать его цену
// появляются две обязанности "собрать букет" "посчитать цену"
// Эти обязанности нельзя возлагать на классы цветочков. (Это определяется анализом)
// Следовательно новый класс для "собрать букет".
// Собирание букета сильно похоже на использование коллекций - поэтому
// будем пользоваться уже готовой коллекцией.
// Но чтобы в готовую коллекцию добавить еще одну ответственность -
// "посчет стоимости".
// Так и сделаем - добавим метод.
public class FlowerPack extends ArrayList<Flower> {
  public BigDecimal getPackPrice() {
    BigDecimal summ = BigDecimal.ZERO;
    for (Flower f : this) {
      summ = summ.add(f.getPrice());
    }
    return summ;
  }
}

public void testBuket() {
    FlowerPack pack = new FlowerPack();
    pack.add(new Rose());
    pack.add(new Rose());
    pack.add(new Tulip());
    System.out.println(pack.getPackPrice());
}


возникает интересный вопрос...
Что будет с нашим букетом. если там 20 одинаковых роз...
Разве целесообразно будет в лист напихивать 20 объектов? Есть мысль напихивать объекты цветов, чтобы добавлялся не сам объект, а попутно с количеством. Но само количество по моему не должно быть атрибутом объекта цветка....
Прошу подсказать идею по букету
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.