2009-09-06 2 views
0

Рассмотрим прямоугольник со сторонами X и Y и площадь Z такие, что Z = X * Y.Как создать класс прямоугольника?

Прямоугольник должен быть смоделирован в чистейшей ООД, который будет поставлять следующие две услуги:

  1. данной стороны X и Y стороны, рассчитать площадь Z.
  2. Учитывая сторона Х и Z площадь, рассчитать сторона Y.

Одним из возможных конструкций я думал на это:

класса Rectangle, который имеет частный инвариант X и Y, метод общедоступного экземпляра Z = ки lcArea(), работающий на X и Y, и метод публичных экземпляров Y = calcSide (Z), работающий на X и по аргументу Z.

Хорошая практика OOD сообщает нам, что Rectangle должен иметь конструктор, который инициализирует X и Y, с некоторыми действительными значениями, оба сразу.

Однако это решение подразумевает, что для вычисления Y, заданного X и Z, необходимо инициализировать конструктор класса с нулевым значением для Y. Инициализация инварианта с Null является грязным программированием.

Есть ли какой-либо чистый, один класс, решение OOD?


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

Например, Black & Модель оценки опционов Sholts выводит цену из указанных 5 финансовых параметров. Одна из этих 5 - волатильность. Бывают случаи, когда вы знаете цену и хотите извлечь подразумеваемую волатильность с использованием того же вычислительного ядра. Кроме того, я нашел необходимость в обратном вычислении с использованием того же вычислительного ядра, что и повторяющийся полезный шаблон. Например, вы можете извлечь цену облигации, зная процентную ставку, но иногда вам нужно извлечь подразумеваемую процентную ставку, зная цену облигации. Часто эти модели работают внутри цикла итераций. Настаивание на использовании функции экземпляра, а не статической функции, имеет достоинство производительности - минимизируя аргументы функции, приложение имеет меньше предварительных условий для проверок.

+0

Могу ли я подвергнуть сомнению помещение? Зачем предлагать вариант 2? Это гипотетично? –

+4

Это звучит очень много, как домашнее задание. – Charles

ответ

6
public class Rectangle { 
    private final double width; 
    private final double height; 

    private Rectangle (double width, double height) { 
     this.width = width; 
     this.height = height; 
    } 

    public double area() { 
     return width * height; 
    } 

    public static Rectangle fromSides(double width, double height) { 
     return new Rectangle(width, height); 
    } 

    public static Rectangle fromSideAndArea(double width, double area) { 
     return new Rectangle(width, area/width); 
    } 
} 
7

Возможно, создается статический метод (в некоторой степени похожий на завод), который создает Rectangle с учетом side и area?

0

Предоставить перегруженные конструкторы и полную инициализацию внутри каждого конструктора.

Для случая, когда вы предоставляете X и Z, есть конструктор, который принимает оба аргумента. Вычислить и инициализировать Y внутри этого конструктора.

3

Простейшее решение - лучший дизайн OO IMO.

Чтобы достичь ТОЛЬКО того, что вы просили; мое приношение:

public static class Rectangle 
{ 
    public static float Side(float side, float area) 
    { 
     return area/side; 
    } 

    public static float Area(float sideX, float sideY) 
    { 
     return sideX * sideY; 
    } 
} 

Kindness,

Dan

+2

Yup, написанные в лучшем духе YAGNI. –

1

Прямоугольник объект может иметь две фабричные методы, чтобы обеспечить X и Y и X и Area.

public static Rectangle CreateRectangleWithXAndY(int? x,int? y) 

public static Rectangle CreateRectangleWithXAndArea(int? x,int? area) 

Или может быть класс RectangleInfo для предоставления информации одному конструктору.

public Rectangle(RectangleInfo rectInfo) 

Я предпочитаю нулевое целое число, чтобы я мог проверить, какая информация предоставлена ​​позже. Расчет может быть предоставлен только для чтения.

public int Area 
{ 
get 
{ 
if(area==null) 
area=_x*_y; 
return area; 
} 
} 

public int Y 
{ 
get 
{ 
if(_y==null) 
_y=area/_x; 
return _y; 
} 
} 
+0

Как компилятор расскажет обо всем конструкторам? –

+0

вы правы :) это могут быть два разных метода фабрики или может быть классом RectangleInfo для предоставления информации для одного конструктора – Beatles1692

-1

создать класс формы, а затем расширить его с классом прямоугольника.

Это предполагается, что вы будете иметь другие формы, а также ..

0

Ленивый загрузить значение площади каре.

public class Square { 
    private int x, y, area = -1; 

    public Square(int x, int y) { 
    this.x = x; 
    this.y = y; 
    } 


    public int CalcSide(int z) { 
    return CalcArea()/z; 
    } 

    public int CalcArea() { 
    return CalcAreaIfNotNull();   
    } 

    private CalcAreaIfNotNull() { 
    if (-1 == area) { 
     area = x * y; 
    } 

    return area; 
    } 
} 
2

Почему «[есть], чтобы быть смоделированы в чистейшей ООД, который будет поставлять следующие две услуги»? Моделирование? ООД? Сервисы? Вы говорите о одном умножении и одном делении, правильно?

Ну, может быть, если сумасшедший профессор настаивал, я бы написать что-то вроде этого:

(defclass rectangle() 
    ((x :initarg :x :initform nil :accessor x) 
    (y :initarg :y :initform nil :accessor y))) 

(defun area (rect) 
    (* (x rect) (y rect))) 

(defun make-rectangle-from-sides (x y) 
    (make-instance 'rectangle :x x :y y)) 
(defun make-rectangle-from-side-and-area (x area) 
    (make-instance 'rectangle :x x :y (/ area x))) 

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

Любой, кто настаивает на «хорошей практике OOD» при создании проблем, которые не существуют в Smalltalk или Lisp, может, ИМХО, наполнить его.

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