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

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

Да. Но это чуть другое из DbC.
-Изменение ширины не влияет на значение длины - это отсутствие побочных эффектов.
в то время как у квадрата побочный эффект обязателен. Изменение "ширины" _должно_ приводить к изменению "длины" ( кавычки тут к тому, что у квадрата сложно выделить ширину и длину :) )
25 окт 10, 17:05    [9671966]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
egorych
Siemargl
Инварианты могут разными, в зависимости от задачи:
-вариант 1. Все стороны равны.
-вариант 2. Все углы прямые
-вариант 3. Сторон не больше 4х.
-вариант 4. Величины длины и ширины могут меняться независимо


да.

SetWidth(Square(5), 10)
вернет значение
Rectangle(10, 5)
25 окт 10, 18:47    [9672897]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4759
ZyK_BotaN
SetWidth(Square(5), 10)
вернет значение
Rectangle(10, 5)
это смотря как реализована SetWidth(). Если, что логично, она будет спрашивать встроенный метод Rectangle.SetWidth(), то вернёт вполне себе квадрат ( 10, 10 ), иначе или SetWidth должна знать, кого ей передают, или реализация Square::SetWidth() должна быть очень необычна ( и нарушать принцип наименьшего удивления при этом )
25 окт 10, 19:57    [9673143]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
egorych
ZyK_BotaN
SetWidth(Square(5), 10)
вернет значение
Rectangle(10, 5)
это смотря как реализована SetWidth(). Если, что логично, она будет спрашивать встроенный метод Rectangle.SetWidth(), то вернёт вполне себе квадрат ( 10, 10 ), иначе или SetWidth должна знать, кого ей передают, или реализация Square::SetWidth() должна быть очень необычна ( и нарушать принцип наименьшего удивления при этом )

Ну вот код:

public class Rectangle {
	private double w,h;
	Rectangle(double w, double h) {
		this.w = w;
		this.h = h;
	}
	Rectangle setWidth(double newW) {
		return new Rectangle(newW, h);
	}
	Rectangle setHeight(double newH) {
		return new Rectangle(w, newH);
	}
	double getWidth() {
		return w;
	}
	double getHeight() {
		return h;
	}
	void show() {
		System.out.println("Rectangle("+getWidth()+","+getHeight()+")");
	}
}



public class Square extends Rectangle {
	Square(double side) {
		super(side, side);
	}
	void show() {
		System.out.println("Square("+getWidth()+","+getHeight()+")");
	}
}


public class Main {
	public static void main(String[] args) {
		Square s = new Square(5);
		Rectangle r = s.setWidth(10);
		s.show();
		r.show();
	}
}


в результате будет вывод:

Square(5.0,5.0)
Rectangle(10.0,5.0)
25 окт 10, 20:24    [9673231]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
подправил класс Square:

public class Square extends Rectangle {
	Square(double side) {
		super(side, side);
	}
	Square setSide(double newSide) {
		return new Square( newSide );
	}
	void show() {
		System.out.println("Square("+getWidth()+")");
	}
}

теперь программа:
public class Main {
	public static void main(String[] args) {
		Square s = new Square(5);
		Rectangle r = s.setWidth(10);
		s.show();
		r.show();
		s = s.setSide(3);
		s.show();
	}
}
выдает:
Square(5.0)
Rectangle(10.0,5.0)
Square(3.0)
25 окт 10, 20:33    [9673258]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
_мод
tchingiz
В дизайне по контракту совершенно на теоретико множественных пальцах (то есть понятно) рассказывают, почему в примере Роберта Мартина с квадратами и прямоугольниками нельзя делать наследование.

Равенство сторон - это инвариант, который усилен в подтипе. Так что все правильно - квадрат подтип прямоугольника.

не правильно.
1)
Область определения функций (методов класса) была сужена.
(У прямоугольников была плоскость, у квадратов диагональ плоскости.)
2)
методы у так называемого ребенка - квадратов удовлетворяют аксиомам противоречащим
аксиомам методов так называемого родителя - прямоугольников.
поэтому, оказалось невозможное корректное выполнение цепочка
а) преобразование из ребенка в родителя
б) выполнение метода
в) восстановление ребенка взад.

если на шаге б) выполнялся метод родителя, нарушался инвариант ребенка.
если на шаге б) выполнялся метод ребенка, нарушались условия,
выполнения функций (клиента), которые были написаны в предположении
аксиом родителя.

пысы.
поскольку сам Карделли разрешил использовать наивную модель памяти при толковании
ооп, в которой
обьект это пара (кортеж, множество_методов), то
моя функциональная запись классов и обьектов в виде
абстрактных автоматов оказывается точным описанием.
(класс это пара (множество_допустимых_значений, множество_функций),
объект - это пара (кортеж , множество_функций))
А проблема не возможности наследования остается все равно.
Так что функциональность тут не причем.
Дело в несовместимости аксиом описания классов, совмещением которых
и занят Мейер в своем методе программирования по контракту
25 окт 10, 21:15    [9673344]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
вот аксиомы обоих классов
https://www.sql.ru/forum/actualthread.aspx?tid=756625&pg=4#9543464
25 окт 10, 21:18    [9673351]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4759
ZyK_BotaN, красиво, но у меня 2 замечания:
1. методы set какбы намекают, что я меняю текущий объект, а не создаю новый
2. вообще говоря, я ведь могу захотеть сделать
Square s  = new Square( 5 );
Square evil = s.SetWidth( 10 ); // опа!
25 окт 10, 21:33    [9673385]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
Siemargl
Member

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

Ну пц, пояснил )))))
Еще хуже стало.

Если я понял правильно, то для решения проблем преобразования "родственников" есть виртуальные ф-ции. Инвариант ес-но, тоже должен быть виртуальным.
И еще мне кажется, что "теорию происхождения видов" неправильно привязывать к ООП - суть разная. (Майерса не читал, что он имел в виду - не знаю)
25 окт 10, 21:44    [9673419]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
egorych
ZyK_BotaN, красиво, но у меня 2 замечания:
1. методы set какбы намекают, что я меняю текущий объект, а не создаю новый
2. вообще говоря, я ведь могу захотеть сделать
Square s  = new Square( 5 );
Square evil = s.SetWidth( 10 ); // опа!

перечитай исправленную версию:

Square s  = new Square( 5 );
Square evil = s.setSide( 10 ); // опа!
[/quot]

что мне не нравится в моем коде, дак это метод show.
я его написал, что-бы короче было. лучше было бы написать два метода
showSquare и showRectangle
25 окт 10, 21:56    [9673446]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

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

Ну пц, пояснил )))))
Еще хуже стало.

Если я понял правильно, то для решения проблем преобразования "родственников" есть виртуальные ф-ции. Инвариант ес-но, тоже должен быть виртуальным.
И еще мне кажется, что "теорию происхождения видов" неправильно привязывать к ООП - суть разная. (Майерса не читал, что он имел в виду - не знаю)

1
не правильно. для решения проблем родственников - нужны совместимые
системы аксиом.
2
у прямоугольников аксиома говорит о не зависимости методов
 all h: UReal, f: Figure:- GetWidth(SetHeight(f, h)) = GetWidth(f)
для любого вещественного х, и любой фигуры ф, гетШирина(сетДлина(ф,х))
равно гетШирина(ф), взятие ширины не зависит от применения установить длину.

а у квадратов зависит
,[gw_sh]
all h: UReal, f: Figure:- GetWidth(SetHeight(f, h)) = h
взятьширину возвращает, то что задано задатьдлину.

шо тут непонятно?

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

3
не Майерс, а Бертран Мейер.
25 окт 10, 22:10    [9673472]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
В результате клиент умирает от удивления, со словами: "а мы так не договаривались"
25 окт 10, 22:14    [9673482]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
Более того, точно такой же техникой на с++,
какой записывалось порождение квадратов из прямоугольников,
можно записать порождение прямоугольников из квадратов.
с точно той же проблемой не соответствия аксиом.
Эти классы не ребенок и родитель, а два близнеца.
Их не надо, вообще, один из другого порождать.
25 окт 10, 22:22    [9673499]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
belugin
Member

Откуда: Москва
Сообщений: 874
tchingiz,

как только ты делаешь квадрату setWidth он перестает быть квадратом. Надо просто в объектную модель ввести predicate classes как в языке cecil.
25 окт 10, 22:29    [9673516]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

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

как только ты делаешь квадрату setWidth он перестает быть квадратом. Надо просто в объектную модель ввести predicate classes как в языке cecil.


конечно, я это выше и продемонстрировал с примерами кода.
25 окт 10, 22:35    [9673535]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
под словом квадрат я не имею ввиду ничего другого кроме как
объекты обсуждаемого класса Square.
Они заданы однозначно и совершенно понятно формальным описанием
на с++ в примера Роберта Мартина.
После вызова функций setWidth из своего класса, квадрат квадратом быть не перестает.
Это переменная, объявленная классом, возможно, оказавшаяся в противоречивом состоянии..
И обсуждается смысл техники программирования,
а не смысл геометрических фигур на плоскости.
25 окт 10, 22:39    [9673549]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
tchingiz
под словом квадрат я не имею ввиду ничего другого кроме как
объекты обсуждаемого класса Square.
Они заданы однозначно и совершенно понятно формальным описанием
на с++ в примера Роберта Мартина.

а чем тебе не понравилась моя реализация фигур?
25 окт 10, 22:52    [9673599]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
а что ты хотел добиться? А то я недопонял пока
Перестал нарушаться принцип Лисков?
25 окт 10, 23:17    [9673693]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
tchingiz
а что ты хотел добиться? А то я недопонял пока
Перестал нарушаться принцип Лисков?

если игнорировать метод show, то да.
25 окт 10, 23:25    [9673731]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6219
tchingiz,
Пока не прочитал статью Лисковой, не понятно было о чем вы говорите )

Теперь возвращаюсь к своему же предыдущему утверждению:
инварианты (аксиоматика) связана с наследованием, и обязательна к учитыванию при проектировании.
25 окт 10, 23:50    [9673844]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

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

Откуда:
Сообщений: 33378
Статья не Лисков, а Мартина
26 окт 10, 00:45    [9674024]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
tchingiz
Member

Откуда:
Сообщений: 33378
ZyK_BotaN
tchingiz
а что ты хотел добиться? А то я недопонял пока
Перестал нарушаться принцип Лисков?

если игнорировать метод show, то да.

не понял, что да.
ты написал в функциональном стиле. Мне кажется, что это означает что цепочка
z -некоторый кортеж
Square s = new Square(5);
Rectangle r = s;
r.method(z);
s = r;
должна быть изменена в


z -некоторый кортеж;
Square s = new Square(5);
Rectangle r = s;
s = r.method(z);

вопрос, в том, что
1) все ранее, написанные программы работают при применении методов, если подсунуть ребенка,
под видом родителя;
2) можно выполнить обратное преобразование родитель -> ребенок, после применения
методов, когда ребенок был под видом родителя.

у тебя нет обратного преобразования.
А в примере Мартина оно неявно требуется, при в начальном обсуждении,
когда выполнялось статическое связывание.

вот это главное,
[color=red]s = r;[/color]
а ты просто увильнул.
Так и у Мартина нет проблемы. Скопировал квадрат в прямоугольник, изменил его ширину и все.
26 окт 10, 01:04    [9674060]     Ответить | Цитировать Сообщить модератору
 Re: Выгоды контрактного программирования (design by contract)  [new]
ZyK_BotaN
Member

Откуда: Новгород-Северский
Сообщений: 106569
tchingiz
ZyK_BotaN
tchingiz
а что ты хотел добиться? А то я недопонял пока
Перестал нарушаться принцип Лисков?

если игнорировать метод show, то да.

не понял, что да.

только метод show нарушает принцип Лисков.

tchingiz

ты написал в функциональном стиле. Мне кажется, что это означает что цепочка
z -некоторый кортеж
Square s = new Square(5);
Rectangle r = s;
r.method(z);
s = r;
должна быть изменена в


z -некоторый кортеж;
Square s = new Square(5);
Rectangle r = s;
s = r.method(z);

здесь можно подробней? я не понял.


tchingiz

у тебя нет обратного преобразования.
А в примере Мартина оно неявно требуется, при в начальном обсуждении,
когда выполнялось статическое связывание.

вот это главное,
[color=red]s = r;[/color]
а ты просто увильнул.
Так и у Мартина нет проблемы. Скопировал квадрат в прямоугольник, изменил его ширину и все.

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

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

вот это главное,
[color=red]s = r;[/color]
а ты просто увильнул.
Так и у Мартина нет проблемы. Скопировал квадрат в прямоугольник, изменил его ширину и все.



public class Rectangle {
	private double w,h;
	public Rectangle(double w, double h) {
		this.w = w;
		this.h = h;
	}
	public Rectangle setWidth(double newW) {
		return new Rectangle(newW, h);
	}
	public Rectangle setHeight(double newH) {
		return new Rectangle(w, newH);
	}
	public double getWidth() {
		return w;
	}
	public double getHeight() {
		return h;
	}
}



public class Square extends Rectangle {
	public Square(double side) {
		super(side, side);
	}
	public Square(Rectangle r) {
		this(r.getHeight());
	}
	public Square setSide(double newSide) {
		return new Square( newSide );
	}
	
}


public class Main {
	static void showRectangle(Rectangle r) {
		System.out.println("Rectangle("+r.getWidth()+","+r.getHeight()+")");
	}
	static void showSquare(Square s) {
		System.out.println("Square("+s.getWidth()+")");
	}
	
	public static void main(String[] args) {
		Square s = new Square(5);
		Rectangle r = s.setWidth(10);
		showRectangle(r);
		showSquare(new Square(r)); //явное преобразование вниз по иерархии
	}
}

вывод:

Rectangle(10.0,5.0)
Square(5.0)
26 окт 10, 01:28    [9674099]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5 6 7 8 9 10   вперед  Ctrl      все
Все форумы / Программирование Ответить