Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Программирование Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4] 5 6 7 8 9 10   вперед  Ctrl      все
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
вот так он поломался. Не код, а объект.
Был квадрат, а стороны стали разными.
теперь его нельзя назад преобразовать.
Почему Мартину это ясно, я не знаю. Это мистический ооп туман.
Если назад пробразовывать не надо - нет проблем.
26 окт 10, 03:51    [9674223]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
ZyK_BotaN
tchingiz,

но в моем ведь коде этой проблемы нет.

из за этого
	showSquare(Square(rhomb));
?
так это явное преобразование любого кого попало в квадрат
26 окт 10, 03:54    [9674224]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
вот так он поломался. Не код, а объект.
Был квадрат, а стороны стали разными.
теперь его нельзя назад преобразовать.
Почему Мартину это ясно, я не знаю. Это мистический ооп туман.
Если назад пробразовывать не надо - нет проблем.


у меня ничего не ломается.
потому, что я использую неизменяемые объекты.

пускай и Мартин их узает и не парит себе башку.

а если использовать изменяемые объекты и/или виртуальные методы, то принцип лисков будет нарушен.
26 окт 10, 03:55    [9674226]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
ZyK_BotaN
tchingiz,

но в моем ведь коде этой проблемы нет.

из за этого
	showSquare(Square(rhomb));
?
так это явное преобразование любого кого попало в квадрат


это не старый код.
этот код новый, ведь мы уже знаем о типе Square и явно к нему приводим.
я добавил приведение только потому, что ты попросил.
можно удалить этот конструктор, и избавиться от проблемы.
26 окт 10, 03:56    [9674227]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
у тебя не ломается, потому что ты используешь явное преобразование.
Поэтому принцип Лисков и нафиг не нужен вообще.
можно строку в квадрат преобразовать.
26 окт 10, 03:57    [9674229]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
у тебя не ломается, потому что ты используешь явное преобразование.
Поэтому принцип Лисков и нафиг не нужен вообще.
можно строку в квадрат преобразовать.

если удалить этот конструктор, принцип нарушаться будет?
26 окт 10, 03:58    [9674232]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
пользователь может написать:

showSquare(Square(rhomb.getSide()));
и ничего не ломается, мы явно игнорируем угол.
26 окт 10, 04:03    [9674234]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
вот тут надо писать
int _tmain(int argc, _TCHAR* argv[])

{
	Square s = Square(5);
///	showRectangle(foo(s)); не это 
	showSquarе(foo(s)); а это
	return 0;
}

у тебя foo выдает родителя, которого нельзя приводить к ребенку

void showSquare(Square s) {
		std::cout << "Square(" << s.getSide() << ")" << std::endl;
	}

правильно?
26 окт 10, 04:16    [9674242]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
ZyK_BotaN
пользователь может написать:

showSquare(Square(rhomb.getSide()));
и ничего не ломается, мы явно игнорируем угол.


а это типа еще короче? чем?
showSquare(Square(rhomb));
26 окт 10, 04:19    [9674244]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 31758
вот эти твои комбинации называны в шаго 0 анафемой програмирования.
    void showRectangle(Rectangle r) {
		std::cout << "Rectangle(" << r.getWidth() << "," << r.getHeight() << ")" << std::endl;
	}
	void showSquare(Square s) {
		std::cout << "Square(" << s.getSide() << ")" << std::endl;
	}
	void showRhomb(Rhomb r) {
		std::cout << "Rhomb(" << r.getA() << "," << r.getSide() << ")" << std::endl;
	}


К сообщению приложен файл. Размер - 0Kb
26 окт 10, 04:22    [9674247]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6042
ZyK_BotaN,

У тебя нет клиента, полагающегося на аксиоматику базового класса. Потому и не ломается - нечему )))
Заведи в базовом классе ф-цию расчета площади (Она будет клиентом). Без ее явного переписывания (override) в наследниках работать будет неверно.
Вариант 2 предъявления проблемы. Возьми сторонний класс, который получает фигуры, например коллекцию. И напиши функцию суммирования площади хранимых объектов.

Если соблюсти DbC, то при работе программы правильно сформулированный инвариант родителя обломится, и ты узнаешь о проблеме.
26 окт 10, 09:34    [9674651]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6042
ZyK_BotaN> class Square: public Rectangle, public Rhomb

странное наследование. Чего хотим получить, козловерблюда?
26 окт 10, 09:40    [9674707]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4740
ZyK_BotaN
методы работающие с прямоугольником могут работать и с квадратом, возвращая абсолютно идентичный результат(принцип Лисков).
это не правда, точнее, не вся правда. Правдой будет написать, что "методы, работающие с прямоугольником, будут скомпилированы и с квадратом, возвращая абсолютно непредсказуемый вариант". В пояснение простой пример: есть функция, которая вписывает произвольный прямоугольник в заданный и возвращает полученный прямоугольник. Я хочу ей воспользоваться, чтобы в заданный прямоугольник вписать квадрат, а потом дальше использовать его, как квадрат. Для пары Rectangle( 10, 2 ) + Square( 5 ) я получу правильный ответ, для пары Rectangle( 2, 10 ) + Square( 5 ) - неправильный.
26 окт 10, 09:45    [9674745]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4740
Siemargl
ZyK_BotaN,

У тебя нет клиента, полагающегося на аксиоматику базового класса.
у него нет ни одной проверки инвариантов ни для прямоугольника, ни для квадрата.
Хотим изменить сторону у квадрата, воспользовавшись функцией базового класса - "бам!" - на тебе произвольный прямоугольник, хотим сделать квадрат из прямоугольника 3х4 - "бам!" - на тебе квадрат 4х4! почему именно такой, почему не 3х3? - потому что гладиолус! какие уж тут "контракты" )))
26 окт 10, 09:56    [9674826]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
_мод
Guest
tchingiz
оказалось невозможное корректное выполнение цепочка
а) преобразование из ребенка в родителя
б) выполнение метода
в) восстановление ребенка взад.

А зачем делать а), если можно сразу сделать б) и не делать с)
Другое дело, что выполнение б) может нарушить инвариант ребенка и вызовет ошибку, так это нормальное поведение, так и д.б. Похоже, проблемы то и нет.
26 окт 10, 12:20    [9676436]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
_мод
Guest
tchingiz
(класс это пара (множество_допустимых_значений, множество_функций),

множество_допустимых_значений - это тип данных, а вот множество_функций - очень расплывчато. Я могу написать очень много функций, использующих этот тип данных в качестве парметров или значений, не включая их в класс. И что это будет ? Итак мы плавно возвращаемся к модульности в терминах АДы.
26 окт 10, 12:26    [9676485]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
_мод
Guest
tchingiz
вот аксиомы обоих классов
https://www.sql.ru/forum/actualthread.aspx?tid=756625&pg=4#9543464

Просто для квадрата SetWidthe и SetHeight должны вызываться одновременно (как один оператор или транзакция) и с одной и то же величиной, чтобы не разрушить квадрат.
begin sq.SetWidthe(10),sq.SetHeight(10) end
begin sq.SetWidthe(5),sq.SetHeight(10) end  - а это ошибка
26 окт 10, 12:32    [9676538]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
_мод
Guest
tchingiz
Потом ты пишешь ребенка, херишь аксиомы родителя, и подсовываешь тем
программам, которые написаны в предположении похереных аксиом
ребенка под видом родителя.
В результате клиент умирает от удивления. Нарушен принцип подстановки Лисков.

аксиомы родителя полностью сохраняются, только дополняются аксиомами ребенка.
попытки применить методы родителя к ребенку никакого удивления вызывать не должны - ошибки ожидаемы и запрограммированы.
26 окт 10, 12:37    [9676586]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
вот тут надо писать
int _tmain(int argc, _TCHAR* argv[])

{
	Square s = Square(5);
///	showRectangle(foo(s)); не это 
	showSquarе(foo(s)); а это
	return 0;
}

у тебя foo выдает родителя, которого нельзя приводить к ребенку

в коде, где знают только о существовании суперкласса не могут использовать ф-и для работы с подкласом(showSquarе(foo(s)))
зато клиент который вызывает старую ф-и(возвращающую прямоугольник), понимает что результат доанной ф-и не всегда можно привести к наследнику без потери точности.


геде в принципе Лисков сказано о том, что родителя можно приводить к ребенку?

tchingiz

void showSquare(Square s) {
		std::cout << "Square(" << s.getSide() << ")" << std::endl;
	}

правильно?

да
26 окт 10, 13:00    [9676839]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
ZyK_BotaN
пользователь может написать:

showSquare(Square(rhomb.getSide()));
и ничего не ломается, мы явно игнорируем угол.


а это типа еще короче? чем?
showSquare(Square(rhomb));

нет, просто можно обойтись и без приведения типов.
во втором случае нет неоднозначностей, мы явно игнорируем угол ромба.
в первом случае, перерасчет сторон квадрата не однозначен, ведь ф-я приведения может быть реализована по разному(например сохранять площадь фигуры).
26 окт 10, 13:02    [9676866]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
tchingiz
вот эти твои комбинации называны в шаго 0 анафемой програмирования.
    void showRectangle(Rectangle r) {
		std::cout << "Rectangle(" << r.getWidth() << "," << r.getHeight() << ")" << std::endl;
	}
	void showSquare(Square s) {
		std::cout << "Square(" << s.getSide() << ")" << std::endl;
	}
	void showRhomb(Rhomb r) {
		std::cout << "Rhomb(" << r.getA() << "," << r.getSide() << ")" << std::endl;
	}


мы говорим о принципе Лисков?
значит этот принцип предан анафеме
как может выполняться принцип Лисков, если мы будем использовать виртуальные ф-и?
26 окт 10, 13:04    [9676893]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
Siemargl
ZyK_BotaN,

У тебя нет клиента, полагающегося на аксиоматику базового класса. Потому и не ломается - нечему )))
Заведи в базовом классе ф-цию расчета площади (Она будет клиентом). Без ее явного переписывания (override) в наследниках работать будет неверно.
Вариант 2 предъявления проблемы. Возьми сторонний класс, который получает фигуры, например коллекцию. И напиши функцию суммирования площади хранимых объектов.

Если соблюсти DbC, то при работе программы правильно сформулированный инвариант родителя обломится, и ты узнаешь о проблеме.


перерасчет будет работать верно,

double sumOfSpace(std::vector<Rectangle> rs) {
		double sum = 0;
		for (std::vector<Rectangle>::iterator i = rs.begin(); i != rs.end(); ++i) {
			sum += (*i).getSpace();
		}
		return sum;
	}
int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<Rectangle> v;
	v.push_back(Rectangle(5, 4));
	v.push_back(Square(3));
	v.push_back(Square(2));
	std::cout << sumOfSpace(v) << std::endl;
	return 0;
}
вывод : 33.
что я делаю не так?
26 окт 10, 13:17    [9677031]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 103663
egorych
[quot Siemargl]ZyK_BotaN,

Хотим изменить сторону у квадрата, воспользовавшись функцией базового класса - "бам!" - на тебе произвольный прямоугольник


где?
у базового класса(Rectangle) нет ф-и изменения стороны, есть только изменение ширины или высоты.

у базового класса Rhomb - есть ф-я изменения стороны и она работает коректно, гарантировано возвращая квадрат(так как угол тоно не измениться).
26 окт 10, 13:20    [9677057]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6042
ZyK_BotaN

вывод : 33.
что я делаю не так?

Ты код то покажи. Полный, где getSpace() описан.
26 окт 10, 13:40    [9677289]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4740
ZyK_BotaN
egorych
[quot Siemargl]ZyK_BotaN,

Хотим изменить сторону у квадрата, воспользовавшись функцией базового класса - "бам!" - на тебе произвольный прямоугольник
где?
у базового класса(Rectangle) нет ф-и изменения стороны, есть только изменение ширины или высоты.
0. про ромб пока забудем опять, говорим за прямоугольник.

1. теперь по буквам:
- мы говорим: квадрат - это прямоугольник ( отнаследовали квадрат от прямоугольника ).
- у прямоугольника есть ширина и высота ( аксиома прямоугольника ),
- у квадрата есть ширина и высота ( аксиома наследования ).
- у квадрата ширина и высота совпадают ( аксиома квадрата ).
- изменяя ширину ( или высоту ) я надеюсь получить квадрат ( принцип наименьшего удивления ), пусть приведённый к типу родителя ( требование языка ).
Но! либо я получаю прямоугольник и по типу, и по содержанию, что противоречит аксиоме квадрата. Или я получаю квадрат ( переопределив сеттеры в наследнике ) и нарушаю аксиомы прямоугольника. Но противоречий ты технично не замечаешь.

2. по остальным пунктам обвинения сказать определённо нечего, ась? ;-))
26 окт 10, 16:08    [9679067]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4] 5 6 7 8 9 10   вперед  Ctrl      все
Все форумы / Программирование Ответить