Цитата:А по концепции - ты что думаешь?
Опять было много букв, каждый участник говорил о своем, некоторые мнения менялись от поста к посту, и четкого резюме о концепции так и не нашел.
Может, просто пропустил.
Итак, давайте начнем от печки.
В-первую очередь хочу заметить, что 1С++ появился не как очередной вариант академического языка для исследования глубинных проблем ООП и постановки экспериментов, а механизм для решения ПРАКТИЧЕСКИХ задач, стоящих перед разработчиком програм на платформе V77, труднорешаемых или плохосопровождаемых стандартными средствами платформы. Но базирующийся на самой платформе, с присущими ей недостками, которые надо принять как данность. И потому менять коренным образом ранее существующее поведение суть проявление неуважения к пользователям 1С++, написавшим на ее основе горы кода.
Во-вторых, идеи с флагами/опциями меня всегда честно говоря коробят. Потому что современем они выливаются в "здесь играем, здесь не играем, а здесь рыбу заворачивали", что вносит совершенную сумятицу в головы как пользователей, так и разработчиков, пытающихся развивать систему далее.
Итак, перед нами стоит дилемма. С одной стороны, хочется оставить поведение написаного кода таким же, как ранее, с другой - иметь возможность там где это нужно, использовать поведение, трактуемое как правильное в свете
последних решений ЦК КП принципов ООП.
Поэтому попробую предложить такой принцип решения: там где нам нужно новое поведение, мы должны и писать по-новому.
Рассмотрим имеющуюся проблему подробнее:
Итак, обсуждаем мы как я понял
Сам(Контекст).ВызовМетода();
(Со свойствами я пока еще даже связываться боюсь).
Сейчас:
При написании такой конструкции мы получаем вот что - взять объект класса, (когда самого себя, а когда какого-то неизвестно наследника), и найти среди составляющих его подобъектов первый, имеющий метод с совпадающим именем и вызвать этот метод этого объекта. При этом поиск идет снизу-верх слева-направо, начиная от конечного (того, который был создан в СоздатьОбъект) объекта.
Плюсы:
- организация вызова из метода базового объекта методов его объектов-наследников (виртуальность).
- легкость реализации "подмешивания"
Минусы:
- Нет средств указать вариант поиска метода, и в результате при совпадении ключей(имен) методов - вызов метода не того подобъекта, которого планировалось.
Что хотим:
При вызове методов гарантированно обращаться только к методам либо своих предков, либо своих прямых потомков.
Плюсы:
- организация вызова из метода базового объекта методов его объектов-наследников (виртуальность).
- Большая безопасность в использовании классов и изолированность реализаций друг от друга.
Минусы:
- не сделать подмешивания.
- многий ранее написанный код по такой схеме не заработает.
Плохо ли текущее поведение, хорошо ли, правильно, неправильно, менять его мы не можем. Не имеем права даже, если мы уважаем пользователей компоненты. Ведь наверняка существуют ПРАКТИЧЕСКИЕ РАБОТАЮЩИЕ решения, основанные на этом поведении.
Рассмотрим вариант с
Сам(Контекст).ТекущийКласс()
То есть метод получить в методе объекта "настоящую" ссылку на самого себя, вместо ссылки на конечный класс.
Справедливости ради отмечу, что в первых версиях 1С++ (oxy.dll), Сам(Контекст) так и работал.
Плюсы:
- При вызове методов мы гарантированно обращаемся к методам планируемых объектов.
Минусы:
- Нет возможности виртуального вызова.
Этот минус сводит всё на нет.
ЭТО ВСЕ ПРЕАМБУЛА и словесный понос.
Теперь по делу.
КОНКРЕТНЫЕ АНИТИКРИЗИСНЫЕ ПРЕДЛОЖЕНИЯ.
Упираемся мы в реализацию алгоритма поиска метода по имени. Иногда нам нужен поиск, как сейчас есть, а иногда - "правильный" поиск.
Алгоритм поиска задается объектом, от которого начинается поиск, и учитывая, что никаких флагов городить мы не хотим, один объект имеет один алгоритм поиска. Следовательно, либо нам надо для поиска использовать другой объект, либо как-то менять семантику вызова метода, что-бы задействовать другой алгоритм для того-же объекта.
Решение по первому пути: объект-прокси.
что-то типа
Сам(Контекст).ПолучитьПравильныйОбъект().ВызовМетода();
ПолучитьПравильныйОбъект() - возвращает объект-прокси, знающий о конечном классе, текущем контексте вызова, и осуществляющий "правильный" поиск метода и перенаправление обращений к методам.
Решение по второму пути:
ВызовМетода();
// либо
ИмяКласса__класс__ВызовМетода();
то есть прямой вызов метода, разрешаемый еще на этапе компиляции.
Сложнее с синтакс-контролем, зато дикое увеличение перформанса (за счет того, что поиск метода делается ОДИН раз при компиляции, а не каждый раз при вызове)
Думаем, господа.