Oberon space

General Category => Общий раздел => Тема начата: pygubanov от Декабрь 12, 2016, 02:24:07 pm

Название: Маска вместо интерфейсов и базового класса
Отправлено: pygubanov от Декабрь 12, 2016, 02:24:07 pm
Всем привет.
Задался таким вопросом существует ли в ООП "Маски" которые при наложении на объект возвращают, только то, что соответствует маске (методы, свойства...)?
Почему возник такой вопрос, если использовать наследование от интерфейса или абстрактного класса, то это накладывает на этапе проектирования ограничения на объекты.
Как я себе представляю действие маски. Допустим имеется два класса несвязанные между собой базовыми наследованием, применяя к ним маску мы получаем доступ к одинаково именованным методам и свойствам, которые соответствуют маске.
class A
{
 public string name;
 public void  Test(){}
...
}

class B
{
 public string name;
 public void  Test(){}
....
}


Накладываем маску

{
A a;
B b;
Mask1 mask;
mask = new Mask1(a);
mask.Test();
string name = mask.name;

mask = new Mask1(b);
mask.Test();
string name = mask.name;

List<A> listA;
List<B> listB;
TestForALL(MaskList(listA));
TestForALL(MaskList(listB));
}

....

void TestForALL(MaskList list)
{
 for (int i=0; i<list.Count; i++)
 {
   list[i].Test();
   string name =  list[i].name;
 }
}


Что скажите?
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: kkkk от Декабрь 12, 2016, 02:52:03 pm
Цитировать
Допустим имеется два класса несвязанные между собой базовыми наследованием, применяя к ним маску мы получаем доступ к одинаково именованным методам и свойствам, которые соответствуют маске.
Так сделано в Go. То, что Вы называете маской, в Go называется всё-таки интерфейсом. Чтобы соответствовать интерфейсу тип должен воплощать методы интерфейса, но явной связи(наследования) не требуется. Единственная разница с Вашими масками в том, что из интерфейса доступны только методы, но этого достаточно.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 12, 2016, 02:57:37 pm
А если объектег не может то, что маска хочет? Что будет?
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 12, 2016, 02:58:19 pm
Цитировать
Допустим имеется два класса несвязанные между собой базовыми наследованием, применяя к ним маску мы получаем доступ к одинаково именованным методам и свойствам, которые соответствуют маске.
Так сделано в Go. То, что Вы называете маской, в Go называется всё-таки интерфейсом. Чтобы соответствовать интерфейсу тип должен воплощать методы интерфейса, но явной связи(наследования) не требуется. Единственная разница с Вашими масками в том, что из интерфейса доступны только методы, но этого достаточно.
Насколько я понимаю, тут хочется маски конструировать в рантайме. А это не интерфейсы уже. Но это всё легко достигается через рефлекшн.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: pygubanov от Декабрь 12, 2016, 04:50:09 pm

Насколько я понимаю, тут хочется маски конструировать в рантайме. А это не интерфейсы уже. Но это всё легко достигается через рефлекшн.
[/quote]

в С# через рефлекшн это конечно можно сделать, но преимущество будет не то.

хочется не рантайм.  А даже вот такое через приведение типов Mask m = (Mask)a;
Только всё это повлечет большую вероятность сделать ошибки, а этого надо избегать (не давать технической возможности делать ошибки)
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 12, 2016, 04:53:04 pm
в С# через рефлекшн это конечно можно сделать, но преимущество будет не то.

хочется не рантайм.  А даже вот такое через приведение типов Mask m = (Mask)a;
Только всё это повлечет большую вероятность сделать ошибки, а этого надо избегать (не давать технической возможности делать ошибки)
Погоди, тебе хочетяся плюсовых концептов да хаскельных type classes что ли? Т.е. хочется штуку которая к ООП вообще отношения не имеет.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: Geniepro от Декабрь 12, 2016, 08:11:05 pm
Это же что-то типа структурной типизации. Вроде в каких-то ML-языках когда-то такое было, может и сейчас есть?

https://dzone.com/articles/duck-typing-scala-structural

Возможно, в питоне что-то такое есть, там же тоже "утиная типизация"...
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: Valery Solovey от Декабрь 12, 2016, 09:32:07 pm
Эта маска - и есть интерфейс как концепция.

А если объектег не может то, что маска хочет? Что будет?
Будет то же самое, что и при приведении объекта к типу, которому он не соответствует. Поэтому, в пару к операции приведения нужна операция проверки типа.

Но в компилируемых языках (а точнее, в трансляторах, которые сопоставляют подпрограммы и их вызовы на этапе компиляции) такой способ работать не будет: в объектах разных классов порядок методов может различаться, и разное положение методов в разных виртуальных таблицах не позволит прозрачно пользоваться простым приведением.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 12, 2016, 09:42:20 pm
Эта маска - и есть интерфейс как концепция.

А если объектег не может то, что маска хочет? Что будет?
Будет то же самое, что и при приведении объекта к типу, которому он не соответствует. Поэтому, в пару к операции приведения нужна операция проверки типа.

Но в компилируемых языках (а точнее, в трансляторах, которые сопоставляют подпрограммы и их вызовы на этапе компиляции) такой способ работать не будет: в объектах разных классов порядок методов может различаться, и разное положение методов в разных виртуальных таблицах не позволит прозрачно пользоваться простым приведением.
Какие таблицы виртуальных функций? Тут же вообще нет нигде речи ни про наследование ни, следовательно, про ООП.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: Valery Solovey от Декабрь 12, 2016, 10:50:10 pm
Какие таблицы виртуальных функций? Тут же вообще нет нигде речи ни про наследование ни, следовательно, про ООП.
Не очень понял... Я руководствовался этим:
Цитировать
существует ли в ООП "Маски" которые при наложении на объект возвращают, только то, что соответствует маске
...
два класса несвязанные между собой базовыми наследованием, применяя к ним маску мы получаем доступ к одинаково именованным методам и свойствам, которые соответствуют маске.
Или виртуальные - это исключительно абстрактные? Ну, тогда я имел в виду таблицу с указателями на реализованные методы.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: vlad от Декабрь 13, 2016, 04:52:55 pm
хочется не рантайм.  А даже вот такое через приведение типов Mask m = (Mask)a;
Только всё это повлечет большую вероятность сделать ошибки, а этого надо избегать (не давать технической возможности делать ошибки)

Мне кажется я делал что-то подобное. Может тебе подойдет такой подход:

Есть набор интерфейсов: I1, I2, ...In. Применительно к твоему случаю можно считать, что каждый интерефейс имеет всего один метод. Далее, ты декларируешь маску как набор интерфейсов:
typedef mask<I1, I3, I5> mask1;
typedef mask<I1, I3> mask2;

Далее эти маски используются на стыке подсистем:
ss1 make_subsystem1(mask1 const&);

Далее у тебя есть полная свобода откуда получить эту маску для передачи в подсистему: либо от объекта, реализующего необходимые интерфейсы, либо от другой маски, имеющей все необходимые интерфейсы. Корректность проверяется во время компиляции, работает в продакшине :)
class object1 : public I1, public I3
{
};

object1 o1;

mask2 m(o1); // OK, компилятор проверяет, что у o1 есть нужные интерфейсы
mask1 m(o1); // компилятор выдает ошибку - не хватвет интерфейса I5
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: vlad от Декабрь 13, 2016, 04:56:06 pm
Доступ к нужному интерфейсу выглядит так:
mask.get<I1>().method(); // здесь компилятор тоже все проверяет - есть такой интерфейс и у него есть такой метод
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: vlad от Декабрь 13, 2016, 05:38:22 pm
Еще хотел добавить: чисто технически на С++ можно реализовать маску как некий контейнер указателей на произольные методы произвольных объектов, которые можно вызывать со всеми необходимым гарантиями корректности типов. Но это будет сильно многословнее в использовании (как в месте декларации/инициализации такой маски так и в месте вызыва нужного метода), чем мой вариант с маской как контейнером ссылок на интерфейсы.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 14, 2016, 11:14:09 pm
Решение на модуле-2 (собираемое через gnu modula-2 compiler) работает похоже что корректно. Поэтому запустил прогон. И да, похоже comdiv выкатил новое решение которое снова самое быстрое. :-)

Через 3-4 часа будут результаты.
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: Geniepro от Декабрь 15, 2016, 05:20:15 am
Решение на модуле-2 (собираемое через gnu modula-2 compiler) работает похоже что корректно. Поэтому запустил прогон. И да, похоже comdiv выкатил новое решение которое снова самое быстрое. :-)

Через 3-4 часа будут результаты.
Чота ты это не в той теме написал ))
Название: Re: Маска вместо интерфейсов и базового класса
Отправлено: valexey_u от Декабрь 15, 2016, 10:45:45 am
Решение на модуле-2 (собираемое через gnu modula-2 compiler) работает похоже что корректно. Поэтому запустил прогон. И да, похоже comdiv выкатил новое решение которое снова самое быстрое. :-)

Через 3-4 часа будут результаты.
Чота ты это не в той теме написал ))
Ага, промахнулся.