Re[89]: ООП головного мозга
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.11 11:34
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, samius, Вы писали:


I>>>И давно C# научили работать с иррациональными числами ?

S>>Как давно на C# запретили писать следующее:
S>>
S>>var sqrt2 = new Sqrt(2);
S>>Assert(sqrt2 * sqrt2 == 2);
S>>

S>>???

I>Здесь нет иррациональных числел Sqrt это функция которая всегда возвращает рациональное число

Тяжелые выходные? В коде нет функции Sqrt.
Re[99]: ООП головного мозга
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.11 11:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, samius, Вы писали:


G>>>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf

G>>>Пункт 3.3.1.1
S>>Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП.
G>Где ты там состояние увидел?
А как без состояния взять указатель на нужную реализацию IUnknown?

S>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html

S>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
G>Тем не менее она не противоречит ООП, также как immutable string не противоречит.
G>А вот если все будет immutable, тогда совсем друга система получится.
Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.

G>>>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп.

S>>В чем это будет не ООП? По каким признакам?
G>По формальным может быть даже получится ООП. Но по сути превратится в ФП.
Вот выделенное имеет значение.

G>>>Нигде, но на глубокой иммутабельности у тебя не получится ООП.

S>>Т.е. потому что ты так решил?
S>>Что будет если у меня будут не только immutable объекты?
G>Тогда у тебя MyEquals будет практически бесполезной функцией.
Весь этот флейм не имеет никакой практической пользы.


S>>>>Причем тут это? QI использует состояние.

G>>>Не использует.

S>>
S>>class MyIDispatchFace : public IDispatch
S>>{
S>>public:
S>>     IUnknown* QI(IID iid)
S>>     {
S>>         case IID_IUnknown:
S>>         ...
S>>     }
S>>};
S>>

S>>Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI.
G>Такого быть не может, IDispatch наследуется от IUnknown.
Все интерфейсы COM наследуются от IUnknown

G>Так что с точки зрения C++ код всегда будет

G>
G>class MyIDispatchFace : public IDispatch
G>{
G>public:
G>     IUnknown* QI(IID iid)
G>     {
G>         case IID_IUnknown:
G>             return this;
G>         ...
G>     }
G>};
G>

Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown).
Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".
Re[90]: ООП головного мозга
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.10.11 11:53
Оценка: :)
Здравствуйте, samius, Вы писали:

I>>>>И давно C# научили работать с иррациональными числами ?

S>>>Как давно на C# запретили писать следующее:
S>>>
S>>>var sqrt2 = new Sqrt(2);
S>>>Assert(sqrt2 * sqrt2 == 2);
S>>>

S>>>???

I>>Здесь нет иррациональных числел Sqrt это функция которая всегда возвращает рациональное число

S>Тяжелые выходные? В коде нет функции Sqrt.

Без разницы. Неужели sqrt2 это бесконечная непериодическая дробь ?

Ты в курсе, что иррациональные числа в разных системах счисления разные ?
Re[44]: ООП головного мозга
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.10.11 12:30
Оценка:
Здравствуйте, gandjustas, Вы писали:

ANS>>"Устарел" != "в корне не прав".

G>Неправ в том что продолжает популяризировать старые идеи. Большинство из которых потеряли актуальность.

Фаулер написал свою книгу давным давно, когда еще не было современных инструментов.
Re[100]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 12:46
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, samius, Вы писали:


G>>>>http://www.daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf

G>>>>Пункт 3.3.1.1
S>>>Погоди, ты мне говорил что именно определение идентити ООП запрещает опираться на поведение и состояние. Спека COM официально одобрила использование поведения и состояния для вычисления ID. Это противоречит твоей трактовке идентити ООП.
G>>Где ты там состояние увидел?
S>А как без состояния взять указатель на нужную реализацию IUnknown?
Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку.
Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.

Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.

S>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html

S>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
G>>Тем не менее она не противоречит ООП, также как immutable string не противоречит.
G>>А вот если все будет immutable, тогда совсем друга система получится.
S>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.
"Злом" и "не относящимся к ООП" не связаны между собой.

G>>>>Отлично, то есть чтобы MyIdentityEquals возвращало true требуется "глубокая" immutability. Это будет не ооп.

S>>>В чем это будет не ООП? По каким признакам?
G>>По формальным может быть даже получится ООП. Но по сути превратится в ФП.
S>Вот выделенное имеет значение.
Тогда придем к разговору о том чем ФП не соотвествует ООП и наоборот.



S>>>>>Причем тут это? QI использует состояние.

G>>>>Не использует.

S>>>
S>>>class MyIDispatchFace : public IDispatch
S>>>{
S>>>public:
S>>>     IUnknown* QI(IID iid)
S>>>     {
S>>>         case IID_IUnknown:
S>>>         ...
S>>>     }
S>>>};
S>>>

S>>>Добавь плиз набросок реализации для случая когда грань IDispatch распологается отдельно от грани IUnknown. А я посмотрю, откуда ты материализуешь результат для QI.
G>>Такого быть не может, IDispatch наследуется от IUnknown.
S>Все интерфейсы COM наследуются от IUnknown
Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.

G>>Так что с точки зрения C++ код всегда будет

G>>
G>>class MyIDispatchFace : public IDispatch
G>>{
G>>public:
G>>     IUnknown* QI(IID iid)
G>>     {
G>>         case IID_IUnknown:
G>>             return this;
G>>         ...
G>>     }
G>>};
G>>

S>Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown).
С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.

S>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".

Все так, если рассматривать C++.
Re[37]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 13:06
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, gandjustas, Вы писали:



G>>>>Фаулер опирается на заблуждение

ANS>>>Это не заблуждение, это примитивизация.
G>>Нет, это именно заблужение. До буча с мейером никто не говорил что объекты — данные+методы, обязательно вместе. Откуда это они взяли — неизвестно.

ANS>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic.


Ниче не понял.

G>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния.

ANS>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
Автор: Andrei N.Sobchuck
Дата: 23.03.07


Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз.
В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.
Re[101]: ООП головного мозга
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.11 13:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, samius, Вы писали:


G>>>Где ты там состояние увидел?

S>>А как без состояния взять указатель на нужную реализацию IUnknown?
G>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку.
G>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.

G>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.

Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)).
Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM.

Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2
pUnk != pUnk2 в общем случае.
Что бы проверить идентичность, COM требует выполнить QI(IID_IUnknown) для обоих указателей.
Так вот, pUnk2 в общем случае может не указывать туда же куда и pUnk. Соответственно, this в реализации его QI будет несовпадать с pUnk. Но у тебя есть задача согласно спеке COM в pUnk2->QI(IID_IUnknown) вернуть значение, совпадающее с pUnk.

Именно это я и попросил тебя сделать в реализации того метода QI.


S>>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html

S>>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
G>>>Тем не менее она не противоречит ООП, также как immutable string не противоречит.
G>>>А вот если все будет immutable, тогда совсем друга система получится.
S>>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.
G>"Злом" и "не относящимся к ООП" не связаны между собой.
Связаны. Иначе нафига в ООП инкапсуляция нужна?

G>>>По формальным может быть даже получится ООП. Но по сути превратится в ФП.

S>>Вот выделенное имеет значение.
G>Тогда придем к разговору о том чем ФП не соотвествует ООП и наоборот.
Надеюсь что не придем. Мы ведь обсуждаем формальные требования ООП.

S>>Все интерфейсы COM наследуются от IUnknown

G>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.
Нет, не достаточно. Речь об объектах с различными гранями.

G>>>Так что с точки зрения C++ код всегда будет

G>>>
G>>>class MyIDispatchFace : public IDispatch
G>>>{
G>>>public:
G>>>     IUnknown* QI(IID iid)
G>>>     {
G>>>         case IID_IUnknown:
G>>>             return this;
G>>>         ...
G>>>     }
G>>>};
G>>>

S>>Если бы это всегда было так, то COM-у не требовалось бы уточнять identity через QI(IID_IUnknown).
G>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.
Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.

S>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".

G>Все так, если рассматривать C++.
Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю.
Re[38]: ООП головного мозга
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 10.10.11 14:07
Оценка:
Здравствуйте, gandjustas, Вы писали:


ANS>>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic.

G>Ниче не понял.

У тебя есть состояние (одна enity с которой работают разные наборы методов (сервисов). Это тот самый случай когда identity разные, а фактический объект один и тот же.

G>>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния.

ANS>>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
Автор: Andrei N.Sobchuck
Дата: 23.03.07

G>Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз.
G>В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.

Ну, придирка не к тому, что есть методы без данных, а к тому, что одновременно есть и методы-без-данных, и данные-без-методов, и, ужас ужас, методы-без-данных манипулируют данными-без-методов.
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[87]: ООП головного мозга
От: artelk  
Дата: 10.10.11 14:18
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, artelk, Вы писали:


A>>Здравствуйте, gandjustas, Вы писали:


G>>>Здравствуйте, artelk, Вы писали:


A>>>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции

A>>>>
A>>>>bool IsIdentical(object o1, object o2)
A>>>>{
A>>>>  return false;
A>>>>}
A>>>>

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

G>>>Нет.


G>>>
G>>>var a = new object();
G>>>var b = a;
G>>>var c = new object();
G>>>Debug.Assert(IsIdentical(a,b) != IsIdentical(a,c));
G>>>


G>>>Ассерт отвалится, с такой функцией мы не можем сказать являются ли разными два объекта или это один и тот же объект. То есть мы не можем отличить объект от других.

A>>Ты пытаешься поднять себя за волосы, как Мюнхгаузен. Ты считаешь, что a в первой строке, во второй и последней ссылаются на один и тот же объект. Нет, в каждой точке программы мы имеем дело с новым объектом, согласно нашей реализации идентичности.
На замом деле, такая реализация идентичности не позволяет сослаться на объект, что противоречит определению.

G>Нет. в Ecma-335 ясно сказано что идентичные объекты те, у которых same location. a и b — same location.

А причем тут Ecma-335? Наверху описывался гипотетический язык, не C#.
Re[85]: ООП головного мозга
От: artelk  
Дата: 10.10.11 14:35
Оценка:
Здравствуйте, Sinclair, Вы писали:

A>>artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals.

A>>gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением.
A>>

A>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?

S>Да сразу же, как начнём писать.

S>
S>public class Crash
S>{
S>  public int A { get; set; }
S>  public override bool Equals(object o) {???  };
S>}
S>var a = new Crash(); a.A = 1;
S>var b = new Crash(); b.A = 2;
S>var l = new List<A>();
S>l.Add(a); l.Add(b);
S>a.A = 2;
S>l.Remove(b);
S>a.A = 1;
S>Assert(l.IndexOf(a) >= 0);
S>

S>Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился.
Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него.
В чем подвох? Решение перестанет быть ООП?
Re[86]: ООП головного мозга
От: artelk  
Дата: 10.10.11 15:00
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, Sinclair, Вы писали:


A>>>artelk> Приведи пример задачи, которую нельзя решить без использования object.ReferenceEquals.

A>>>gandjustas> Хорошо, задача: нужно реализовать object.ReferenceEquals с текущим его поведением.
A>>>

A>>>Когда может такое случиться, что мы не сможем предоставить коллекции свой equals (вычисляемый как функция состояния объекта) не выходя за рамки ООП парадигмы?

S>>Да сразу же, как начнём писать.

S>>
S>>public class Crash
S>>{
S>>  public int A { get; set; }
S>>  public override bool Equals(object o) {???  };
S>>}
S>>var a = new Crash(); a.A = 1;
S>>var b = new Crash(); b.A = 2;
S>>var l = new List<A>();
S>>l.Add(a); l.Add(b);
S>>a.A = 2;
S>>l.Remove(b);
S>>a.A = 1;
S>>Assert(l.IndexOf(a) >= 0);
S>>

S>>Приведите, пожалуйста, свою перегрузку метода Equals, не использующую сравнение ссылок. Задача — в том, чтобы ассерт выполнился.
A>Например, добавить в Crash "private readonly Guid id = Guid.NewGuid();", реализовать Equals через него.
A>В чем подвох? Решение перестанет быть ООП?
Сам себе отвечу. Да, equals так определять не комильфо — определить, что два разных объекта равны так не получится, согласен.
Очевидно, метод List<T>.Remove(T item) реализовать не получится. Можно реализовать разве что RemoveWhere(Func<T, bool> predicate), плюс у нас остается старый добрый RemoveAt(index).
Метод List<T>.Add(T item) остается как есть, т.к. уникальность по identity он не делает (в отличие от HashSet).
И как с ООП, мы его теряем при этом?
Re[102]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 15:06
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, samius, Вы писали:


G>>>>Где ты там состояние увидел?

S>>>А как без состояния взять указатель на нужную реализацию IUnknown?
G>>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку.
G>>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.

G>>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.

S>Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)).
S>Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM.
И?

S>Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2

А, понял. В COM нет приведения типов, вместо него QueryInterface. COM — бинарный стандарт, он проектировался так чтобы не быть привязанным к конкретному языку.
То что ты говоришь — плод интерференции C++ и COM. Только это не является COM.

S>pUnk != pUnk2 в общем случае.

Это будет не COM. Читай спецификацию.


S>>>>>http://www2.parc.com/csl/groups/sda/projects/reflection96/docs/sobel/rop.html

S>>>>>Здесь ROP считают отдельной парадигмой. Это подтверждает, что оно явно высовывается из рамок OOP.
G>>>>Тем не менее она не противоречит ООП, также как immutable string не противоречит.
G>>>>А вот если все будет immutable, тогда совсем друга система получится.
S>>>Одно дело рефлекшном создавать экземпляры и лазать по атрибутам. Другое — изменять приватные поля. Вот именно изменение состояний в обход инкапсуляции я считаю злом, не относящимся к ООП.
G>>"Злом" и "не относящимся к ООП" не связаны между собой.
S>Связаны. Иначе нафига в ООП инкапсуляция нужна?
Инкапсуляция поведения. Если рассматривать инкапсуляцию состояния, то она становится не нужна при immutable.


S>>>Все интерфейсы COM наследуются от IUnknown

G>>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.
S>Нет, не достаточно. Речь об объектах с различными гранями.
Это плод интерференции С++ и COM. оставаясь в COM приведение типов выполняется с помощью QueryInterface.

G>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.

S>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.
Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет.

S>>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".

G>>Все так, если рассматривать C++.
S>Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю.
Ну ты ССЗБ. Сам придумал случай, сам делай так чтобы оно было COM.
Re[39]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 15:10
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, gandjustas, Вы писали:



ANS>>>Это rule of thumb. Ситуация, когда состояние общее и шарится между разными категориями мутаторов может и имеет право на жизнь, но не в случае anemic.

G>>Ниче не понял.

ANS>У тебя есть состояние (одна enity с которой работают разные наборы методов (сервисов). Это тот самый случай когда identity разные, а фактический объект один и тот же.

Что значит "фактический объект"? Как ты понимаешь "Объект" в данном случае?

G>>>>Даже design patterns описывает классы и объекты, большинство из которых не имеет данных\состояния.

ANS>>>Если бы я хотел так придираться к словам, как ты, то сказал бы, что объект всегда имеет состояние
Автор: Andrei N.Sobchuck
Дата: 23.03.07

G>>Придираться к словам иногда очень важно. Только так можно понять смысл некоторых фраз.
G>>В данном случае методы без данных за объекты не считают по непонятной совершенно причине. При выдумывании ООП никто даже близко такого не говорил.

ANS>Ну, придирка не к тому, что есть методы без данных, а к тому, что одновременно есть и методы-без-данных, и данные-без-методов, и, ужас ужас, методы-без-данных манипулируют данными-без-методов.


А еще бывают случаи когда методы-без-данных вызывают другие методы-без-данных, которые вообще расположены на другой машине и передают им данные-без-методов, которые нормально при этом сериализуются\десериализуются и не вызывают ошибок. Причем такие случаи в современном ПО гораздо более распространены, чем данные-с-методами, которые оперируют только другими данными-с-методами.
Re[88]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 15:16
Оценка:
Здравствуйте, artelk, Вы писали:

A>На замом деле, такая реализация идентичности не позволяет сослаться на объект, что противоречит определению.

Прочитай внимательно определение, там identity не говорит об операции "сослаться" (dereferencing). Эта операция доступна для "ссылки" (не адреса в памяти). Ссылка имеет некоторое числовое значение, даже если ссылки на один объект не будут совпадать, то есть некоторое инвариантное значение ссылки, которое будет совпадать для одного объекта.
Вот теперь вопрос, всегда ли на практике ссылка (инвариантная) может служить identity?

Ты утверждал что нет.

G>>Нет. в Ecma-335 ясно сказано что идентичные объекты те, у которых same location. a и b — same location.

A>А причем тут Ecma-335? Наверху описывался гипотетический язык, не C#.
Так опиши эту гипотетическую систему, а потом функции в ней. Вот samius попытался, но у него немного не ООП получилось.
Re[85]: ООП головного мозга
От: artelk  
Дата: 10.10.11 16:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, artelk, Вы писали:


A>>Только сдается мне такому определению удовлетворит идентичность, реализованная на основе функции

A>>
A>>bool IsIdentical(object o1, object o2)
A>>{
A>>  return false;
A>>}
A>>

A>>и смысл полностью теряется, т.к. такую функцию можно реализовать вообще для чего угодно.
S>Сначала нужно проверить результат IsIdentical(a, a).
А если у нас в языке нет возможности передать значения по ссылке? В IsIdentical придут две разные копии объекта.

Давай издалека:
struct A
{
    public int X;
}

var a = new A();
a.X = 21;
a.X = a.X + a.X;
Debug.Assert(a.X == 42);

Я утверждаю, что именно идентичность, реализованная в языке, позволяет нам иметь гарантии, что в последних 3х строчках мы имеем дело с одним и тем же объектом.
Кроме того, идентичностью называется именно возможность иметь такие гарантии.

В языках со ссылочной прозрачностью идентичности не требуется.
let x = 21 * cos(0.0)
let y = x * 2 //y = 42

Инедтификаторы тут — просто alias-ы выражений (а не ссылки на созданные "объекты") и могут быть просто заинлайнены:
let y = (21 * cos(0.0)) + (21 * cos(0.0)) //y = 42


Идентичность нужна, прежде всего, для обеспечения возможности такой вещи как само состояние (а конкретно, изменяемое состояние), как понятия языка.
И именно поэтому идентичность не может быть функцией состояния — без него самого состояния быть не может.
Согласен ли ты с этим?
Re[40]: ООП головного мозга
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 10.10.11 16:05
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Что значит "фактический объект"? Как ты понимаешь "Объект" в данном случае?


Не не не. Это мы уже проходили
Автор: Andrei N.Sobchuck
Дата: 27.04.05
.
Ты всё сводишь к техническому моменту. Данные лежат в массиве? В массиве? Массив — это объект? Объект. Значит есть ОО. А потом приходят функциональщики и говорят "а зачем это всё?
Автор: Gaperton
Дата: 24.01.05
".
Хотя ОО позволяет делать тот самый "рекурсивный" дизайн, когда объекты и в верху и в низу, ты оставляя объекты внизу системы отказываешься от них на верху.
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[41]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.10.11 16:34
Оценка: +1
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, gandjustas, Вы писали:


G>>Что значит "фактический объект"? Как ты понимаешь "Объект" в данном случае?


ANS>Не не не. Это мы уже проходили
Автор: Andrei N.Sobchuck
Дата: 27.04.05
.

ANS>Ты всё сводишь к техническому моменту. Данные лежат в массиве? В массиве? Массив — это объект? Объект. Значит есть ОО. А потом приходят функциональщики и говорят "а зачем это всё?
Автор: Gaperton
Дата: 24.01.05
".

Массив — не объект.

Если смотреть на массив с точки зрения C\ассемблера, то массив — указатель непрерывный кусок памяти, то есть число. Число объектом не является (даже несмотря на SmallTalk), так как не обладает identity.

Если же мы возьмем язык программирования и создадим класс "массив", которому мы можем отправлять сообщения типа "верни элемент с индексом i", вот только массив этот может быть внутри и хеш-таблицой, и односвязным списком, и непрерывным блоком памяти. То есть некоторый "список" (упорядоченное множество) элементов.

С точки зрения низкого уровня массив не имеет identity, а с точки зрения высокого массив — деталь реализации "списка"

Если же подойти с философской точки зрения, то везде в мире нас окружают объекты: люди, компьютеры, дома, меблель. Но для ООП объекты должны обладать некоторыми свойствами. Так вот не все объекты в реальной жизни этими свойствами обладают, да и в программах тоже.

Поэтому ООП — не там где есть объекты, а там где выполняются свойства ООП.
Так вот anemic по формальным свойствам не менее ООП, а учитывая SOLID — даже более ООП, чем рич.
Вот только 15 лет назад буч с мейером сказали что ООП это данные с методами, и придумали OOAD в виде моделирования задачи, а не решения. И все им верят.


ANS>Хотя ОО позволяет делать тот самый "рекурсивный" дизайн, когда объекты и в верху и в низу, ты оставляя объекты внизу системы отказываешься от них на верху.

Еще раз: по формальным признакам anemic — не менее ООП. Хотя в случае распределенной среды выгодно забивать на identity сервисов, но это сейчас не рассматриваем. Anemic использует другой подход к созданию классов и объектов, пытаясь моделировать не задачу, а решение.
Re[103]: ООП головного мозга
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.11 18:31
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, samius, Вы писали:


G>>>>>Где ты там состояние увидел?

S>>>>А как без состояния взять указатель на нужную реализацию IUnknown?
G>>>Что значит "нужную". Каждый объект независимо от состояния всегда возвращает одну и ту же ссылку.
G>>>Причем независимо как от наблюдаемого. так и от скрытого состояния. Ты же сам говорил что если функция использует фазу луны при вычислениях, но результат остается постоянным, то значит не зависит.

G>>>Сравнивая поля объектов ты явно ставишь идентичность в зависимость от состояния.

S>>Ты что-то в COM явно не догоняешь. Объекты в COM могут быть многогранными (не знаю, какой термин используется конкретно в COM, я взял термин у Элджера (Face)).
S>>Вот ты создал объект через CreateInstance, получил IUnknown* pUnk. Что бы запросить у него IDispatch ты должен выполнить pUnk->QI(IID_IDispatch) и получить void* pDisp. В общем случае pUnk != pDisp. Но pDisp должен реализовывать методы интерфейса IDispatch, так же как и IUnknown, т.к. IDispatch расширяет IUnknown, как и все остальные интерфейсы COM.
G>И?

S>>Т.е. pDisp поддерживает вызов методов IUnknown, а значит его можно привести к IUnknown* и получить pUnk2

G>А, понял. В COM нет приведения типов, вместо него QueryInterface. COM — бинарный стандарт, он проектировался так чтобы не быть привязанным к конкретному языку.
G>То что ты говоришь — плод интерференции C++ и COM. Только это не является COM.

S>>pUnk != pUnk2 в общем случае.

G>Это будет не COM. Читай спецификацию.
Читай ты. 2.1.4, 2.1.4.1, 2.1.4.2 того документа что ты давал ссылку.
Это основа COM. То что я назвал Face-ами у них называется интерфейсами. QI- это способ навигации множественными интерфейсами объекта. Он возвращает this лишь в тривиальных случаях. И C++ тут непричем.

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

G>>>"Злом" и "не относящимся к ООП" не связаны между собой.
S>>Связаны. Иначе нафига в ООП инкапсуляция нужна?
G>Инкапсуляция поведения. Если рассматривать инкапсуляцию состояния, то она становится не нужна при immutable.
Проблема в том, что immutable становится лишь условностью, когда в руках программиста рефлекшн.


S>>>>Все интерфейсы COM наследуются от IUnknown

G>>>Ну вот, если ты реализуешь интерфейс X, то всегда реализуется IUnknown. Этого достаточно чтобы возвращать всегда одинаковую ссылку на IUnknown.
S>>Нет, не достаточно. Речь об объектах с различными гранями.
G>Это плод интерференции С++ и COM. оставаясь в COM приведение типов выполняется с помощью QueryInterface.
Не приведение типов, а навигация между интерфейсами. Нет никакого плода интерференции. То, о чем я говорю — это основа Object Reusability через aggregation (1.3.3.2, 2.4). И требования идентичности COM обеспечивают то что такие агрегаты с множеством интерфейсов являются самостоятельным объектом притом что каждый интерфейс имеет свой memory location с различными указателями.

G>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.

S>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.
G>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет.
Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния.

S>>>>Так-что что-то не так в твоем коде. Его нельзя отнести к "всегда будет так".

G>>>Все так, если рассматривать C++.
S>>Я описал случай когда return this не удовлетворит идентичности COM. Код я просил именно к этому случаю.
G>Ну ты ССЗБ. Сам придумал случай, сам делай так чтобы оно было COM.
multiple interface navigation в COM не я придумал
Re[104]: ООП головного мозга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.10.11 00:14
Оценка:
Здравствуйте, samius, Вы писали:

G>>>>С чего ты взял? COM — бинарный стандарт, он не знает про интерфейсы в .NET и наследование в C++, да и вообще про типы. Но по счастливой случайности бинарный формат на выходе компилятора MSVC++ совпадает с COM.

S>>>Не понял, причем тут интерфейсы в дотнет и наследование в C++. Речь об расширении контрактов в COM. На чем хочешь пиши, хоть на асме.
G>>Так ты сам начал такой разговор. В COM приведение типов выполняется с помощью QueryInterface, то что ты можешь в C++ получить IUnknown* из вообще любого участка памяти никакого отношения к COM не имеет.
S>Я не говорил о получении IUnknown из вообще любого участка памяти. Я чисто об multiple interface navigation, который невозможен без использования состояния.
Тогда приведи корректный с точки зрения COM способ получения разных указателей на IUnknown для одного объекта.
Это не получится также, как иметь разные ссылки на один объект в CLR. Ты по второму кругу попадаешь в одну и ту же ошибку.
Re[86]: ООП головного мозга
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.10.11 03:00
Оценка:
Здравствуйте, artelk, Вы писали:
A>А если у нас в языке нет возможности передать значения по ссылке? В IsIdentical придут две разные копии объекта.
Как бы то ни было, требования к идентичности функция не выполняет. Она таки обязана вернуть true при передаче в неё одного и того же объекта.
A>Я утверждаю, что именно идентичность, реализованная в языке, позволяет нам иметь гарантии, что в последних 3х строчках мы имеем дело с одним и тем же объектом.
А я утверждаю, что по определению идентичность в ООП требует возможности различать объекты независимо от их состояния и поведения.

A>Идентичность нужна, прежде всего, для обеспечения возможности такой вещи как само состояние (а конкретно, изменяемое состояние), как понятия языка.

A>И именно поэтому идентичность не может быть функцией состояния — без него самого состояния быть не может.
A>Согласен ли ты с этим?
Да, согласен.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.