Основы объектно-ориентированного проектирования


Законные побочные эффекты: пример - часть 2


Они всегда определены (исключая theta для комплексного числа 0). Помимо инфиксных функций "+" и других предполагаем процедуру add и другие. Вызов: z1 + z2 дает новое комплексное число, вызов z1.add (z2) изменяет z1. На практике могут понадобиться только функции или только процедуры.

Наш класс включает следующие секретные (закрытые) атрибуты:

cartesian_ready: BOOLEAN polar_ready: BOOLEAN private_x, private_y, private_rho, private_theta: REAL

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

invariant cartesian_ready or polar_ready polar_ready implies (0 <= private_theta and private_theta <= Two_pi) -- cartesian_ready implies (private_x and private_y являются текущими) -- polar_ready implies (private_rho and private_theta являются текущими)

Последние два предложения выражены неформально в форме комментария.

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

Две закрытые процедуры доступны для проведения изменений представления:

prepare_cartesian is -- Сделать доступным декартово представление do if not cartesian_ready then check polar_ready end -- Поскольку инвариант требует, чтобы одно -- из двух представлений было текущим private_x := private_rho * cos (private_theta) private_y := private_rho * sin (private_theta) cartesian_ready := True -- Здесь cartesian_ready и polar_ready равны true: -- Оба представления являются текущими end ensure cartesian_ready end prepare_polar is -- Сделать доступным полярное представление do if not polar_ready then check cartesian_ready end private_rho := sqrt (private_x ^ 2 + private_y ^ 2) private_theta := atan2 (private_y, private_x) polar_ready := True -- Здесь cartesian_ready и polar_ready равны true: -- Оба представления являются текущими end ensure polar_ready end

Функции cos, sin, sqrt и atan2 берутся из стандартной математической библиотеки, atan2(y, x) вычисляет arctangent(y/x).




Начало  Назад  Вперед



Книжный магазин