Здравствуйте, skiner.dp, Вы писали:
SD>Сделал набросок решения программы, а вот правильно ли!?
Я бы не принял. У вас может быть только один букет цветов. Я не могу за один сеанс работы создать несколько букетов.
Здравствуйте, LeonidV, Вы писали:
LV>Здравствуйте, skiner.dp, Вы писали:
SD>>Сделал набросок решения программы, а вот правильно ли!? LV>Я бы не принял. У вас может быть только один букет цветов. Я не могу за один сеанс работы создать несколько букетов.
Дык в основном букет это НЕ один цветок, сказано ж создать несколько объектов цветов!
Здравствуйте, skiner.dp, Вы писали:
SD>Дык в основном букет это НЕ один цветок, сказано ж создать несколько объектов цветов!
Вы ошибку делаете. Вместо того, чтобы подумать что неправильно у вас, вы начинаете защищать свой код (в некоторой степени признак плохого программиста, кстати) и искать чего неправильного в том, что вам говорят.
Здравствуйте, skiner.dp, Вы писали:
SD>Сделал набросок решения программы, а вот правильно ли!? SD>Заразанее спасибо!
Что значит правильно — неправильно? Работать — работает. Ну а реализация — ужас, что могу сказать. В простейшем задании столько косяков .
1) область видимости почему такая выбрана? Почему к полям есть свободный доступ на уровне пакета, какова цель всего этого? Где инкапсуляция?
2) какое static total? Это называется завуалированное использование глобальных переменных.
3) иерархией тут и не пахнет, более того, она искусственная. Хотя, name можно и оставить в базовом, но его значения делать константой в наследниках, по желанию. В конструкторе тогда 2 параметра, а не 3, за счет чего будет хоть какая то выгода от иерархии. Базовый класс неплохо б абстрактным сделать, если так. Снова — где инкапсуляция? Мы можем фиалку с названием "роза" создать — что это такое? А вот класс Букет — вот он нужен, и именно там должна фигурировать цена. То есть 2 класса должно быть.
Здравствуйте, LeonidV, Вы писали:
LV>Здравствуйте, skiner.dp, Вы писали:
SD>>Дык в основном букет это НЕ один цветок, сказано ж создать несколько объектов цветов! LV>Вы ошибку делаете. Вместо того, чтобы подумать что неправильно у вас, вы начинаете защищать свой код (в некоторой степени признак плохого программиста, кстати) и искать чего неправильного в том, что вам говорят.
Почему вы считаете, что защита своего кода является признаком плохого программиста?
Огромное количество задач может быть решено сильно различающимися способами и трудозатраты и конечная производительность кода зачастую будут примерно равны.
Но желающих рассказать что их решение лучше обычно немерено. Т.е. зачастую приходится наблюдать своего рода холивар с целью доказать, что твое решение лучше решения соседа просто потому, что оно твое.
Здравствуйте, skiner.dp, Вы писали:
SD>Дык в основном букет это НЕ один цветок, сказано ж создать несколько объектов цветов!
1. Ну и зачем новые классы, которые не имеют дополнительных свойств?
2. А как насчет
Violet vio1 = new Violet(55.56, "Роза", "Колючая");
в вашей иерархии. Это уже нонсенс. Получили совсем не то что нужно
Здравствуйте, BlackEric, Вы писали:
BE>Здравствуйте, LeonidV, Вы писали:
LV>>Здравствуйте, skiner.dp, Вы писали:
SD>>>Дык в основном букет это НЕ один цветок, сказано ж создать несколько объектов цветов! LV>>Вы ошибку делаете. Вместо того, чтобы подумать что неправильно у вас, вы начинаете защищать свой код (в некоторой степени признак плохого программиста, кстати) и искать чего неправильного в том, что вам говорят.
BE>Почему вы считаете, что защита своего кода является признаком плохого программиста?
Защищать в данном случае несколько выдрано из контекста.
Идея вот в чем. Программист пишет код. Как и всякий человек, он старается сделать все хорошо и правильно. Получившийся код это нечто сделанное тобой, куда ты вложил душу. Со временем код может стать плохим и мешать развитию системы. Так вот, хороший программист без сожаления выкинет мешающий код. А плохой будет его любить подстраивать под него систему.
В случае же неопытных программистов (а все программисты неопытные, когда рядом есть кто-то более опытный), "плохость" кода может вылезти сразу. И очень важно, чтобы программист задумался, почему его код считается плохим и переделал, не продолжая его защищать выискивая недостатки в критике.
С другой стороны, я считаю, что программист обязан суметь объяснить каждую строчку своего кода (то есть суметь его "защитить").
Здравствуйте, skiner.dp, Вы писали:
SD>Сделал набросок решения программы, а вот правильно ли!? :???: SD>Заразанее спасибо!
SD>Задание таково: SD>Определить иерархию цветов. Создать несколько объектов-цветов. Собрать букет с определением его стоимости.
Я бы сделал как-то так:
public class Bouquet {
private double price;
private List<Flower> flowers = new ArrayList<Flower>();
public double getPrice() {
return price;
}
public Bouquet addFlower(Flower flower) {
flowers.add(flower);
price += flower.getPrice();
return this;
}
}
public enum Color {
Red, Yellow, Green;
}
public class Flower {
private final double price;
private final String name;
private final Color color;
protected Flower(double price, String name, Color color) {
if (price < 0) {
throw new IllegalArgumentException("Price can not be less then zero.");
}
this.price = price;
if (name == null) {
throw new NullPointerException("Argument name can not be null.");
}
if (name.isEmpty()) {
throw new IllegalArgumentException("Name of flower can not be empty.");
}
this.name = name;
if (color == null) {
throw new NullPointerException("Argument color can not be null.");
}
this.color = color;
}
public double getPrice() {
return price;
}
public String getName() {
return name;
}
public Color getColoe() {
return color;
}
}
public class Rouse extends Flower{
private final static String name = "Роза";
public Rouse(double price, Color color) {
super(price, name, color);
}
}
public class Violet extends Flower{
private final static String name = "Фиалка";
public Violet(double price, Color color) {
super(price, name, color);
}
}
public class Tulip extends Flower{
private final static String name = "Тюльпан";
public Tulip(double price, Color color) {
super(price, name, color);
}
}
public class Main {
public static void main(String[] args) {
double total = 0;
Rouse ros1 = new Rouse(36.5, Color.Red);
Rouse ros2 = new Rouse(20, Color.Green);
Violet vio1 = new Violet(55.56, Color.Yellow);
Bouquet bouquet = new Bouquet();
bouquet.addFlower(ros1).addFlower(ros2).addFlower(vio1);
System.out.println(bouquet.getPrice());
}
}
... 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());
}
Здравствуйте, Other Sam, Вы писали:
OS> // По идее точнее было-бы OS> // BigDecimal.valueOf(127).divide(BigDecimal.valueOf(100), RoundingMode.HALF_EVEN) OS> // .setScale(2, RoundingMode.HALF_EVEN) OS> // Но такой код очень сложно читать. Так что я через float задал.
Проще сразу BigDecimal.valueOf(127, 2). Оно в документации рядом с теми двумя, которые вы указали . А в каких-нибудь финансовых приложениях правильнее скорее всего было бы использовать конструктор от BigDecimal и MathContext (опционально со scale). Это чтобы не указывать при всех операциях режимы округления и необходимую точность.
On 03/09/10 13:44, Other Sam wrote: > BigDecimal.valueOf(1.27).setScale(2, RoundingMode.HALF_EVEN)
Вот так: new BigDecimal("1.27"), пока профайлер не обругает.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай