Re[9]: Ответ
От: IT Россия linq2db.com
Дата: 26.01.04 01:35
Оценка: 108 (10) +2 :)
Здравствуйте, Геннадий Васильев, Вы писали:

IT>>Небольшие изменения тут, небольшие там и вот перед нами каша из логики и вспомогательного кода.

ГВ>Ну, Игорь, это уже отдаёт пионерством: "эта дорога неверна, мы срочно побежим другой". А чтобы не было каши надо чаще думать, чем работать. Помогает, проверено.

Думать и работать — это аргументы в пользу бедных, будешь эту лапшу своему начальству вешать. Расскажешь ему, что вот там на RSDN есть такой дурачёк IT, нифига в этой жизни не понимает, а вот я, Геннадий Васильев, фишку очень даже секу
В техническом же форуме всё это называется одним ёмким словом — демагогия.

ГВ>А если без ёрничанья, то перспектива получения каши если не из БЛ+вспомогатльный код, то уж внутри вспомогательного кода или внутри самой БЛ — по любому остаётся.


Okey, хоть ты и не любишь песнь про большие проекты, но всё же, позволь, я тебе её спою, т.к. из всей нашей предыдущей дискуссии, я делаю вполне очевидный вывод, что ты слабо представляешь себе что это такое.

Для начала давай разберёмся, что такое большой проект. Если ты думаешь, что это объём написанного кода, то это правда только отчасти. Это всё равно что определять сексуальную ориентацию человека по вторичным половым признакам. Так вот, размер проекта вовсе не измеряется числом строк, он измеряется числом амбиций, прямопропорционально зависящим от количества девелоперов помноженное на их амбициозность. Если учесть, что на серьёзные проекты приглашают серьёзное количество серьёзных ребят, то можешь себе представить что это такое. Например, представь что бы получилось, если бы кому-нибудь взбрело в голову поднять такой проект силами Top100 RSDN.ru

У каждого из нас свои предпочтения, свой опыт и свои накатанные решения. Они все правильные, но разные. Сегодня может оказаться весомее мнение того, кто красноречивее, завтра того, у кого больше орденов, послезавтра окажется, что лучше было бы делать немного по-другому. А потом у PM'ов созреет новое видение функционирования продукта, маркетинг обнаружит новую нишу на рынке и тут найдётся кто-то, кто предложит ещё более подходящее в данной ситуации архитектурное решение. А проект тем временем идёт, люди пишут код, QA не сидит без дела. И тут ты в не самый подходящий момент заявляешь, что надо бы сделать небольшой рефакторинг во всех классах бизнеслогики. Всего-то делов на 3 часа и все изменения ты сделаешь сам. Правда на эти 3 часа лучше всем пойти покурить, т.к. тебе понадобится весь проект. Допустим средний рейт каждого из 50 девелоперов на этом проекте равен $150/h, то $150 * 3h * 50 = $22500. Столько стоит трёх-часовой простой на таком проекте. Что бы этого избежать используется более мягкий переход, в коде начинают одновременно соседствовать два-три решения, появляются рудименты и атавизмы предыдущих архитектур. Код становится всё более и более запутанным.

Бороться с этим бесполезно. Так же бесполезно как и с тем, что в политику идут не совсем чистоплотные товарищи и очень часто выигрывают. Человеческий фактор, ничего не поделаешь Рассуждать о правильном дизайне мы все мастаки, более того, каждый из нас может похвастаться удачными реализациями удачных решений в небольших проектах. Но большой проект — это часто наука психология + теория компромиссов. Единственный способ поднять такой проект — это не бороться со всем этим бардаком, а суметь его (бардак) организовать (не в смысле устроить, а в смысле взять под контроль). Это умение построить не наиболее удачный дизайн с точки зрения какой-либо привычной характеристики типа быстродействие, масштабируемость, переносимость, а сделать его индифферентным к будущим изменениям, которые неизбежно будут возникать, причём периодичеки.

AOP — это один из путей в светлое будущее. Прежде всего потому, что позволяет разнести, в общем-то, слабо связанные друг с другом сущности, полностью отжать бизнес логику от сквозного кода. С одной стороны, чем короче код бизнес объектов, тем дешевле заказчику обойдётся проект. Продположим, каждый бизнес метод имеет в среднем по 10 строчек, ты сумел убрать одну, экономия 10%. На 10 лимонах это уже 1 миллион. С другой, разрабатывать, реюзать, отлаживать, модифицировать и сопровождать такой код легче, а значит быстрее и дешевле. Где может сбойнуть следующий код:

int Sum(int a, int b)
{
    return a + b;
}


Только в логике. А этот?

HRESULT SomeClass::getSomeValue(LONG *retVal, LONG a, LONG b)
{
    COM_CALL_TRACE_TMDEF(TraceMode<Logged>, SomeClass, getSomeValue)

    *retVal = a + b;

    return S_OK;
}


Ошибка может быть в вызове макроса (кстати, почитай что о макросах думает Страуструп), в самой логике, в коде возврата. Т.е. твой код потенциально в три раза менее надёжный. Теперь помнож это на те амбиции, которыми определяется размер проекта и в результате ты вылетишь с него со свистом, как вылетают те многие, которые всего этого не понимают.

Поэтому, отвечая на твой пост:

ГВ>

А если без ёрничанья, то перспектива получения каши если не из БЛ+вспомогатльный код, то уж внутри вспомогательного кода или внутри самой БЛ — по любому остаётся.


Дело не в наличии каши как таковой, дело в её размерах. Каша в БЛ — это каша в БЛ, каша в сквозном коде — это каша в сквозном коде. Если ты их соединяешь вместе, то ты их не складываешь, ты их помножаешь. Согласен, что в маленьком проекте это вполне допустимо, практически без разницы, но в большом... увы.

Хорошая архитектура в данном смысле — это не та архитектура, которая красиво смотрится в коде, это та, которую не видно вообще. А AOP — это как раз один из путей для нас увидеть всё это счастье ещё в этой жизни
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Ответ
От: IT Россия linq2db.com
Дата: 26.01.04 03:08
Оценка: 11 (1)
Здравствуйте, vdimas, Вы писали:

V>В моей практике я никогда не создавал бизнес объекты (БО) напрямую — они всегда создаются некоей фабрикой (или другим БО, выступающим в ее роли) Т.е. запросили сессию, у нее — некий БО, у того следующий и т.д.

V>Вся логика построена на открытых абстрактных (полностью, либо частично, или даже вовсе не абстрактных, но весьма полиморфных) классах.

Вполне жизненное решение используемое в том же COM и в его апофигозе имплементации — ATL

Недостатки абстрактных фабрик классов тоже хорошо известны:

1. Плохая расширяемость. На каждый новый тип объекта нужно писать новую фабрику.
2. Исользование синглетона для доступа к фабрикам, что значительно сужает область реиспользования создаваемых классов.
3. Отсутствие гарантии в том, что объект будет создан именно через фабрику. Даже твои абстрактные классы можно отнаследовать и спокойно создать напрямую.

В остальном отработанный и широко используемый подход.

V>3. .Net — очень много способов как сделать...


Кстати. О фабриках и синглетонах в .NET. AOP в действии

using System;
using System.Runtime.Remoting.Proxies;

[AttributeUsage(AttributeTargets.Class)]
public class MyClassFactoryAttribute : ProxyAttribute
{
    public override MarshalByRefObject CreateInstance(Type type)
    {
        return base.CreateInstance(typeof(MyRealClass));
    }
}

[MyClassFactory]
public class MyClass : ContextBoundObject
{
}

class MyRealClass : MyClass
{
}

class Test
{
    static void Main()
    {
        MyClass mc = new MyClass();

        Console.WriteLine(mc.GetType().Name);
    }
}


Работает шо железная железяка. TP/RP не создаются, так что с быстродейсвием проблем нет . Все 3 приведённые мной выше пункта при определённой сноровке легко устраняются. Правда появляются другие проблемы

Синглетон делается аналогично.

V>Ну а теперь вернемся в "человеческое" ООП.

V>Предложенная задача — неожиданная потребность начать мониторинг вообще всех вызовов — явно из разряда особенных (надуманных). Решение подобной задачи надо или проектировать вместе с фреймворком, или потом дорабатывать вообще все и ругать себя за скудоумие. Ибо ООП предполагает затрату некоей мыслительной энергии на начальных этапах проектирования.

Тему скудоумия и демагогии мы с ГВ уже обсудили
Автор: IT
Дата: 26.01.04
, лучше давай не будет продолжать

V>Тема крайне интересная, и хотелось бы от IT услышать хоть один достойный пример, где АОП имело бы преимущество перед ООП. Хуки не предлагать , в реальных системах хуки делаются путем хаков (Win32). Интересно услышать задачу, относящуюся к целевым бизнес-объектам, а не к вспомогательным/системным вещам. (системного рода задачки на С++ весьма весело решаются, и никто не придерживается строгого ООП, если речь идет о чем-то весьма системном, типа представлении стека как списка параметров, в одной из своих библиотек на С++ я именно так и делал и даже больше, ибо возможность произвольной реинтерпретации произвольного участка памяти в С++ есть, хоть это и опускает нас на уровень древнего С... кстати, многое из Remouting в .Net именно на таком уровне и сделано, весьма это далеко от АОП и ООП)


Можешь сходить по той же ссылке. Разницу между большими и маленькими проектами я объяснил Проблемы в них примерно так же как и проблемы с детьми. Маленькие дети — маленькие проблемы, большие дети — большие проблемы. Причём проблемы в разном возрасте могут быть одни и теже, но их масштабы резко отличаются.

V>И еще, самое главное:

V>Если не трудно, развития ради, интересно посмотреть на код и оценить трудоемкость подхода IT в решении его собственной задачки. ГВ предложил одну строчку кода на все интересующие методы, трудоемкость в этом случае ясна и понятна. IT, давай решение на АОЯП — справедливости ради, а то пока не ясно как все это сравнивать

В моём текущем проекте эти задачи решаются MS'овским тимом с помощью интерсепторов: RealProxy, синки, контексты и прочая фигня. Я этим совершенно не озабочен и не пишу ни одной строчки в своём коде кроме атрибутов, управлющих транзакциями (типа как в COM+). Производительность вполне приемлемая, т.к. всё это висит на ремоутинге. Но сказать что я от этого решения пребываю в поросячем восторге не могу. Для этого конкретного проекта вполне оптимальное решение, но оно ограничено применением ремоутинга. Как вполне резонно заметил naje, если будут требования быстродействия, то либо придётся всё это хозяйство отключать, либо искать другое решения. Может твоё сойдёт, может ГВ.
Для написания бизнес сущностей (не серверных объектов) и маппинга используется Rsdn.Framework.Data с поддержкой абстрактных классов. Сокращение объёма тупого кода примерно на две трети. Но тоже не всё так гладко как хотелось бы.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Ответ
От: mikа Stock#
Дата: 26.01.04 10:11
Оценка:
Здравствуйте, IT, Вы писали:

IT>Кстати. О фабриках и синглетонах в .NET. AOP в действии


Я бы сказал в бездействии.

IT>

........

IT>class Test
IT>{
IT>    static void Main()
IT>    {
IT>        MyClass mc = new MyClass();

IT>        Console.WriteLine(mc.GetType().Name);
IT>    }
IT>}
IT>


IT>Работает шо железная железяка. TP/RP не создаются, так что с быстродейсвием проблем нет . Все 3 приведённые мной выше пункта при определённой сноровке легко устраняются.


Не создаеться? А что выведет вот эта строчка?

Console.WriteLine(System.Runtime.Remoting.RemotingServices.IsTransparentProxy(mc));


Вообщем ты не прав. Но даже не в этом, а том, что без связки TP/RP у тебя практически не будет АОП.

IT>Правда появляются другие проблемы


Игорь, давай так. В игру угадайка лучше не стоит играть. Тем более, что люди предлагают тебе решение на C++, что значит не знают, как может работать Remoting на Нете.


IT>Синглетон делается аналогично.


Вот только синглетон то и делаеться такими способами. И более ничего.
Re[10]: Ответ
От: Batiskaf Израиль http://www.mult.ru/
Дата: 26.01.04 10:16
Оценка:
Здравствуйте, IT, Вы писали:

IT>
IT>using System;
IT>using System.Runtime.Remoting.Proxies;

IT>[AttributeUsage(AttributeTargets.Class)]
IT>public class MyClassFactoryAttribute : ProxyAttribute
IT>{
IT>    public override MarshalByRefObject CreateInstance(Type type)
IT>    {
IT>        return base.CreateInstance(typeof(MyRealClass));
IT>    }
IT>}

IT>[MyClassFactory]
IT>public class MyClass : ContextBoundObject
IT>{
IT>}

IT>class MyRealClass : MyClass
IT>{
IT>}

IT>class Test
IT>{
IT>    static void Main()
IT>    {
IT>        MyClass mc = new MyClass();

IT>        Console.WriteLine(mc.GetType().Name);
IT>    }
IT>}
IT>


Идеей твоей Игорь, я честно сказать не пронялся, в плюсах есть точно такие же декларативные средства, что ты тут показываешь.
Допустим есть такая ситуация:


struct MyClassBase
{

};

typedef    MyClassBase    MyClass;

int main(...)
{
    MyClass* mc= new MyClass();
}


Завтра я меняю всего несколько строк:


template<typename Base>
struct    MyRealClass: public    Base
{

};

typedef    MyRealClass<MyClassBase>    MyClass;

int main(...)
{
    MyClass* mc= new MyClass();
}


Ну а завтра мне еще и это нужно навесить:


template<typename Base>
struct    MyRealClassWithAdittionalStrategy : public Base
{

};

typedef    MyRealClassWithAdditionalStrategy<MyRealClass<MyClassBase> >     MyClass;

int main(...)
{
    MyClass* mc= new MyClass();
}


И обошлись без ContextBoundObject... Может я ошибаюсь, но преимущества АОП в .Net в том, что я могу обувать свои типы в атрибуты динамически, на этапе выполнения? Нужно ли это на этапе выполнения, это уже другой вопрос
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[14]: Ответ
От: mikа Stock#
Дата: 26.01.04 10:29
Оценка:
Здравствуйте, AndrewVK, Вы писали:

M>>Почему же. ТР помогает только стартовать ремотингу свои АОП-видную инфраструктуру.


AVK>Так то ремоутинг, а мы ведь о чистом АОП говорим.


А почему ты думаешь, что чистый АОП должен обязательно ассоциироваться с Нетовскими понятиями. Или у нас Нет уже панацея?

AVK>А ему ничего, окромя сладкой парочки TP/RP не нужно.


Ну вот тут приводили различные паттерны, которые обходятся без эти двух.

M>> В С++ нет ТР. Это ведь не значит, что там не может быть АОП.


AVK>Может, но либо фиговое, либо путем изменения языка (обычно это реализуется препроцессором специальным).


Это так на Нете реализовано. Не стоит думать, что оно везде так.

M>>Если CAO — то да, а если SAO, то можно что-нибудь сделать с Activator.


M>> Согласить, высказывание

M>>

M>>ремоутинг нужен для передачи объектных сообщений через канал

M>>идет перпендикулярно.

AVK>Не соглашусь. Вполне соответствует одно другому. Прокся были созданы для работы ремоутинга, но из этого никак не следует что ремоутинг нужен для перехвата вызовов.


Ты писал

механика проксей предназначена не для перехвата вызовов, а для работы ремоутинга.


Я ответил

Именно для перехвата вызовов она и предназначена.


Я утверждаю, что механика проксей предназначена для перехвата вызовов.

AVK>Блин, Мика, почитай что такое ExecuteMessage и что он делает


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

M>>Сужаем круг требований. Так глядишь дойдем до того, что это можно было бы предвидеть на этапе проектирования


AVK>Нет, не сойдемся. Невозможно предвидеть все возможные требования, на эту тему я даже спорить не буду.


А я это и не утверджаю. Я говорю, что чем меньше требований, тем лучше мы их продумает на начальном этапе. Отсюда повышается вероятность того, что мы сможет продумать последующие модорнизации системы.

AVK>>>Это да, это как раз и было нужно.


AVK>Т.е. в итоге механика дотнета позволяет строить АО-решения эффективными только для удаленных вызовов.


Именно. Но давай еще раз по порядку. Клиент передал серверу объект CBO. Сервер должен вызвать по крайней мере один из методов этого объекта (хотя бы транспортная инфраструктура это делает). Получается, что никакого удаленного вызова и не будет.

AVK>Это не имело отношения к той задачке о которой речь.


Да я про твою уже спросил.

AVK>Та задачка была решена написанием банальных проксей, но это не значит что это лучшее решение, просто использовать ремоутинг для трассировки внутрипроцессных вызовов не лучшее решение.


Ага. Наконец-то, сказал то, что я Игорю вдалбливаю уже 10 топиков назад.
Re[15]: Ответ
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.01.04 12:00
Оценка:
Здравствуйте, mikа, Вы писали:

AVK>>Так то ремоутинг, а мы ведь о чистом АОП говорим.


M>А почему ты думаешь, что чистый АОП должен обязательно ассоциироваться с Нетовскими понятиями.


А почему ты думаешь что я так думаю? Я так не думаю. Просто без написания препроцессора единственная разумная возможность АОП это TP/RP.

M>Ну вот тут приводили различные паттерны, которые обходятся без эти двух.


Насколько я помню изначально я говорил об особенностях реализации АОП в дотнете.

M>>> В С++ нет ТР. Это ведь не значит, что там не может быть АОП.


AVK>>Может, но либо фиговое, либо путем изменения языка (обычно это реализуется препроцессором специальным).


M>Это так на Нете реализовано.


Нет, на нете реализовано фиговое. Через препроцессор это уже R# .

M>Не стоит думать, что оно везде так.


Ну хорошо, как ты реализуешь честный АОП на С++ без препроцессора?

M>>>Сужаем круг требований. Так глядишь дойдем до того, что это можно было бы предвидеть на этапе проектирования


AVK>>Нет, не сойдемся. Невозможно предвидеть все возможные требования, на эту тему я даже спорить не буду.


M>А я это и не утверджаю. Я говорю, что чем меньше требований, тем лучше мы их продумает на начальном этапе. Отсюда повышается вероятность того, что мы сможет продумать последующие модорнизации системы.


Повышается, но не до 100% и даже не до 10%, как показывает практика. АОП позволяет в случае обнаружения непредусмотренного обойтись значительно меньшей кровью.

AVK>>Т.е. в итоге механика дотнета позволяет строить АО-решения эффективными только для удаленных вызовов.


M>Именно. Но давай еще раз по порядку. Клиент передал серверу объект CBO. Сервер должен вызвать по крайней мере один из методов этого объекта (хотя бы транспортная инфраструктура это делает). Получается, что никакого удаленного вызова и не будет.


Но вся цепочка форматтеров и транспортных синков отработает по полной. Вот в этом и задница.

AVK>>Та задачка была решена написанием банальных проксей, но это не значит что это лучшее решение, просто использовать ремоутинг для трассировки внутрипроцессных вызовов не лучшее решение.


M>Ага. Наконец-то, сказал то, что я Игорю вдалбливаю уже 10 топиков назад.


Дык Игорь то не об АОП на основе TP/RP говорит, а об нормальном АОП. Вот нормальный АОП очень даже прокатил бы.
... << RSDN@Home 1.1.3 beta 1 >>
AVK Blog
Re[10]: Ответ
От: mikа Stock#
Дата: 26.01.04 12:29
Оценка: 47 (3)
Здравствуйте, IT, Вы писали:

IT>
IT>using System;
IT>using System.Runtime.Remoting.Proxies;

IT>[AttributeUsage(AttributeTargets.Class)]
IT>public class MyClassFactoryAttribute : ProxyAttribute
IT>{
IT>    public override MarshalByRefObject CreateInstance(Type type)
IT>    {
IT>             return (MarshalByRefObject)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(MyRealClass));
IT>
IT>             // тут создаеться прокся. Ай-яй-яй :)) 
IT>            //return base.CreateInstance(typeof(MyRealClass));
IT>    }
IT>}

IT>[MyClassFactory]
IT>public class MyClass : ContextBoundObject
IT>{
IT>}

IT>class MyRealClass : MyClass
IT>{
IT>}

IT>class Test
IT>{
IT>    static void Main()
IT>    {
IT>        MyClass mc = new MyClass();

IT>        Console.WriteLine(mc.GetType().Name);
IT>    }
IT>}
IT>


IT>Работает шо железная железяка. TP/RP не создаются, так что с быстродейсвием проблем нет .


А чтобы создать без ТР нужно использовать посмотри исправлени в коде.

Кстати, код работоспособен. Только ужасно тормознутый
Re[16]: Ответ
От: mikа Stock#
Дата: 26.01.04 12:44
Оценка:
Здравствуйте, AndrewVK, Вы писали:

M>>Это так на Нете реализовано.


AVK>Нет, на нете реализовано фиговое. Через препроцессор это уже R# .


Только вот он не реализован

M>>Не стоит думать, что оно везде так.


AVK>Ну хорошо, как ты реализуешь честный АОП на С++ без препроцессора?


А зачем там реализовывать? Там уже все есть, только без препроцессинга. Взять бы хотя бы COM+. Если чисты СОМ, то смотреть ICallFrame, ICallInterceptor, IPolicyMaker, CoGetInterceptor.

M>>Именно. Но давай еще раз по порядку. Клиент передал серверу объект CBO. Сервер должен вызвать по крайней мере один из методов этого объекта (хотя бы транспортная инфраструктура это делает). Получается, что никакого удаленного вызова и не будет.


AVK>Но вся цепочка форматтеров и транспортных синков отработает по полной. Вот в этом и задница.


Вряд ли форматеты и провайдеры тут отработают. Скорее всего только те синки, которые кроссконтекстное общение осуществляют.

AVK>Дык Игорь то не об АОП на основе TP/RP говорит, а об нормальном АОП. Вот нормальный АОП очень даже прокатил бы.


Игорь, в своем первом сообщении упомянул RealProxy. Так что ни о каком чистом АОП и речи не шло. Это я его продвигаю, так как на С++ проксей не сущесвует.
Re[17]: Ответ
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.01.04 12:50
Оценка:
Здравствуйте, mikа, Вы писали:

M>А зачем там реализовывать? Там уже все есть, только без препроцессинга.


В С++?

M>Взять бы хотя бы COM+.


Это не С++, это конкретная ОО-технология. Думаю не надо объяснять что он везде применим.

M>Если чисты СОМ, то смотреть ICallFrame, ICallInterceptor, IPolicyMaker, CoGetInterceptor.


Это все равно не С++.

M>>>Именно. Но давай еще раз по порядку. Клиент передал серверу объект CBO. Сервер должен вызвать по крайней мере один из методов этого объекта (хотя бы транспортная инфраструктура это делает). Получается, что никакого удаленного вызова и не будет.

AVK>>Но вся цепочка форматтеров и транспортных синков отработает по полной. Вот в этом и задница.

M>Вряд ли форматеты и провайдеры тут отработают. Скорее всего только те синки, которые кроссконтекстное общение осуществляют.


Отработают, не сомневайся. Думаешь для чего нужен CrossContextChannel?
... << RSDN@Home 1.1.3 beta 1 >>
AVK Blog
Re[11]: Ответ
От: IT Россия linq2db.com
Дата: 26.01.04 13:03
Оценка:
Здравствуйте, mikа, Вы писали:

M>А чтобы создать без ТР нужно использовать посмотри исправлени в коде.


M>Кстати, код работоспособен. Только ужасно тормознутый


А блин, точно. Опять quick solution.
Что-то я видел на эту тему, правда давно это было, надо будет опять в Роторе покопаться.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Ответ
От: IT Россия linq2db.com
Дата: 26.01.04 13:18
Оценка: +1
Здравствуйте, Batiskaf, Вы писали:

B>Идеей твоей Игорь, я честно сказать не пронялся, в плюсах есть точно такие же декларативные средства, что ты тут показываешь.


Так мне никто не мешает вызывать MyClassBase напрямую без typedef. В этом вся проблема
Тогда уж лучше абстрактные классы vdimas.

B>И обошлись без ContextBoundObject... Может я ошибаюсь, но преимущества АОП в .Net в том, что я могу обувать свои типы в атрибуты динамически, на этапе выполнения? Нужно ли это на этапе выполнения, это уже другой вопрос


AOP в .NET находится в зачаточном состоянии. И хотя мне тут некоторые пытаются приписать популяризацию имплементации AOP в .NET с помощью RealProxy, это не так. Настоящий AOP без проддержки компилятором или хотя бы препроцессором не возможен. Ни на C#, ни на C++. Иначе мы бы его все уже давным давно успешно использовали. Всё что здесь предлагается — это использование тех или иных паттернов, что само по себе не плохо, но вовсе не является AOP.
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Ответ
От: mikа Stock#
Дата: 26.01.04 13:25
Оценка: 42 (1)
Здравствуйте, AndrewVK, Вы писали:

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


M>>А зачем там реализовывать? Там уже все есть, только без препроцессинга.


AVK>В С++?


Ага

M>>Взять бы хотя бы COM+.


AVK>Это не С++, это конкретная ОО-технология. Думаю не надо объяснять что он везде применим.


Ну дык и применяйте. А вы все да TP да RP.

M>>Если чисты СОМ, то смотреть ICallFrame, ICallInterceptor, IPolicyMaker, CoGetInterceptor.


AVK>Это все равно не С++.


Я могу через С++ с этим работать? Могу. Больше мне ничего не надо.

AVK>Отработают, не сомневайся. Думаешь для чего нужен CrossContextChannel?


Думаю, вот для этого
CrossContextChannel.SyncProcessMessage(message)
{
  Identity serverIdentity = InternalSink.GetServerIdentity(message);
  Context context = serverIdentity.ServerContext;

  ContextTransitionFrame frame = new ContextTransitionFrame();

  Thread.CurrentThread.EnterContext(сontext, ref frame);
  сontext.GetServerContextChain().SyncProcessMessage(message);
  Thread.CurrentThread.ReturnToContext(ref frame);
}


Тоесть, ничего кроме как для переключения контекстов он не нужен.
Re[19]: Ответ
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.01.04 13:34
Оценка:
Здравствуйте, mikа, Вы писали:

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


M>Думаю, вот для этого

M>
M>CrossContextChannel.SyncProcessMessage(message)
M>{
M>  Identity serverIdentity = InternalSink.GetServerIdentity(message);
M>  Context context = serverIdentity.ServerContext;

M>  ContextTransitionFrame frame = new ContextTransitionFrame();

M>  Thread.CurrentThread.EnterContext(сontext, ref frame);
M>  сontext.GetServerContextChain().SyncProcessMessage(message);
M>  Thread.CurrentThread.ReturnToContext(ref frame);
M>}
M>


M>Тоесть, ничего кроме как для переключения контекстов он не нужен.


См. выделенное.
... << RSDN@Home 1.1.3 beta 2 >>
AVK Blog
Re[20]: Ответ
От: mikа Stock#
Дата: 26.01.04 14:03
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


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


M>>Думаю, вот для этого

M>>
M>>CrossContextChannel.SyncProcessMessage(message)
M>>{
M>>  Identity serverIdentity = InternalSink.GetServerIdentity(message);
M>>  Context context = serverIdentity.ServerContext;

M>>  ContextTransitionFrame frame = new ContextTransitionFrame();

M>>  Thread.CurrentThread.EnterContext(сontext, ref frame);
AVK>M>  сontext.GetServerContextChain().SyncProcessMessage(message);
M>>  Thread.CurrentThread.ReturnToContext(ref frame);
M>>}
M>>


M>>Тоесть, ничего кроме как для переключения контекстов он не нужен.


AVK>См. выделенное.


И что? Неверим наслово?


Context.GetServerContextChain()
{
  return new ServerContextTerminatorSink();
}

ServerContextTerminatorSink.SyncProcessMessage(message)
{
  IMessageSink sink = InternalSink.GetServerIdentity(message).GetServerObjectChain(out obj);
  return sink.SyncProcessMessage(message);
}

ServerIdentity.GetServerObjectChain()
{
  IMessageSink sink = new ServerObjectTerminatorSink(serverObj);
}

ServerObjectTerminatorSink.SyncProcessMessage
{
      IMessage iMessage2;

      IMessage iMessage1 = InternalSink.ValidateMessage(msg);
      if (iMessage1 != null)
      {
        return iMessage1;
      }
      IMethodCallMessage iMethodCallMessage = msg is IMethodCallMessage;
      LogicalCallContext logicalCallContext1 = null;
      bool flag = false;
      try
      {
        object local1 = _server;
        VerifyIsOkToCallMethod(local1, iMethodCallMessage);
        LogicalCallContext logicalCallContext2 = null;
        if (iMethodCallMessage != null)
        {
          logicalCallContext2 = iMethodCallMessage.LogicalCallContext;
        }
        else
        {
          logicalCallContext2 = (LogicalCallContext)msg.Properties["__CallContext"];
        }
        logicalCallContext1 = CallContext.SetLogicalCallContext(logicalCallContext2);
        flag = true;
        logicalCallContext2.PropagateIncomingHeadersToCallContext(msg);
        PreserveThreadPrincipalIfNecessary(logicalCallContext2, logicalCallContext1);
        if (IsOKToStackBlt(iMethodCallMessage, local1) && ((Message)iMethodCallMessage).Dispatch(local1, fExecuteInContext))
        {
          iMessage2 = new StackBasedReturnMessage();
          ((StackBasedReturnMessage)iMessage2).InitFields((Message)iMethodCallMessage);
          LogicalCallContext logicalCallContext3 = CallContext.GetLogicalCallContext();
          logicalCallContext3.PropagateOutgoingHeadersToMessage(iMessage2);
          ((StackBasedReturnMessage)iMessage2).SetLogicalCallContext(logicalCallContext3);
        }
        else
        {
          MethodBase methodBase = GetMethodBase(iMethodCallMessage);
          object[] locals1 = null;
          object local2 = null;
          RemotingMethodCachedData remotingMethodCachedData = InternalRemotingServices.GetReflectionCachedData(methodBase);
          object[] locals2 = Message.CoerceArgs(iMethodCallMessage, remotingMethodCachedData.Parameters);
          local2 = PrivateProcessMessage(methodBase, locals2, local1, methodPtr, fExecuteInContext, out locals1);
          CopyNonByrefOutArgsFromOriginalArgs(remotingMethodCachedData, locals2, ref locals1);
          LogicalCallContext logicalCallContext4 = CallContext.GetLogicalCallContext();
          iMessage2 = new ReturnMessage(local2, locals1, (locals1 != null) ? (int)locals1.Length : 0, logicalCallContext4, iMethodCallMessage);
          logicalCallContext4.PropagateOutgoingHeadersToMessage(iMessage2);
        }
        CallContext.SetLogicalCallContext(logicalCallContext1);
      }
      catch (Exception e)
      {
        iMessage2 = new ReturnMessage(e, iMethodCallMessage);
        ((ReturnMessage)iMessage2).SetLogicalCallContext(iMethodCallMessage.LogicalCallContext);
        if (flag)
        {
          CallContext.SetLogicalCallContext(logicalCallContext1);
        }
      }
      return iMessage2;
}


Вообщем, это в статье все есть у Тимофея. Как видишь, нигде нет сериализации
Re[12]: Ответ
От: mikа Stock#
Дата: 26.01.04 14:05
Оценка:
Здравствуйте, IT, Вы писали:

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


M>>А чтобы создать без ТР нужно использовать посмотри исправлени в коде.


M>>Кстати, код работоспособен. Только ужасно тормознутый


IT>А блин, точно. Опять quick solution.


"Поспешишь — людей насмешишь". Русский поговорки забыл?

IT>Что-то я видел на эту тему, правда давно это было, надо будет опять в Роторе покопаться.


Что именно, как без TP? Дык я же привел
Re[12]: Ответ
От: mikа Stock#
Дата: 26.01.04 14:10
Оценка:
Здравствуйте, IT, Вы писали:

IT>AOP в .NET находится в зачаточном состоянии. И хотя мне тут некоторые пытаются приписать популяризацию имплементации AOP в .NET с помощью RealProxy, это не так. Настоящий AOP без проддержки компилятором или хотя бы препроцессором не возможен. Ни на C#, ни на C++. Иначе мы бы его все уже давным давно успешно использовали. Всё что здесь предлагается — это использование тех или иных паттернов, что само по себе не плохо, но вовсе не является AOP.


Более того, АОП на Нете, основанный на контекстам ужасно глюченный. Как тому пример, куча вопросов, "как перехватить вызов из одного и того же контекста, или разные контексты". Контексты кажутся такими пушыстями только тогда, когда ты ими не занимаешься вплотную. Как только дело до практики, все оказывается не все так гладко...

Так что, вердикт таков. Берем банду, учим паттерны, проектируем
Re[12]: Ответ
От: Batiskaf Израиль http://www.mult.ru/
Дата: 26.01.04 14:16
Оценка:
Здравствуйте, IT, Вы писали:

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


B>>Идеей твоей Игорь, я честно сказать не пронялся, в плюсах есть точно такие же декларативные средства, что ты тут показываешь.


IT>Так мне никто не мешает вызывать MyClassBase напрямую без typedef. В этом вся проблема

IT>Тогда уж лучше абстрактные классы vdimas.

Согласен, но это уже вопрос воспитания. Кому то проще наследоваться от ContextBoundObject и заколачивать в него гвоздями все необходимые атрибуты, я же предпочитаю оформить инклюд файл, в котором находятся одни typedef's, с комментариями и рекомендациями как это все использовать, тем более что документировать приходится как мне так и тебе в одинаковой мере. Внешне все выглядит по разному, но результат все тот же

B>>И обошлись без ContextBoundObject... Может я ошибаюсь, но преимущества АОП в .Net в том, что я могу обувать свои типы в атрибуты динамически, на этапе выполнения? Нужно ли это на этапе выполнения, это уже другой вопрос


IT>AOP в .NET находится в зачаточном состоянии. И хотя мне тут некоторые пытаются приписать популяризацию имплементации AOP в .NET с помощью RealProxy, это не так. Настоящий AOP без проддержки компилятором или хотя бы препроцессором не возможен. Ни на C#, ни на C++. Иначе мы бы его все уже давным давно успешно использовали. Всё что здесь предлагается — это использование тех или иных паттернов, что само по себе не плохо, но вовсе не является AOP.

Еще несколько лет назад я бы кинулся в драку защищать свой любимый С++, но со временем эта категоричность проходит, думаю у тебя тоже это случится, тридцатка уже стукнула или еще нет?
Вобщем какое может быть отношение неискушенных программеров к АОП идеологии? На мой взгляд тут нет места сопоставлениям, AOP vs. OOP и так далее. Это две разные парадигмы, которые друг друга дополняют, но не заменяют. Базовый ООП является незаменимой частью дизайна архитектуры, интерфейсы и виртуальные методы сегодня еще никто не отменил. Вместе с этим, в современном программинге нечего делать без продвинутых средств реализации, каковыми и является к примеру АОП. То есть эти средства помогают более простыми и экономичными способами имплементировать все тот же правильный дизайн, ведь выделение сквозной функциональности в одном месте это в первую очередь правильный дизайн, АОП предлагает лишь более простой метод придерживаться этого дизайна. В С++ таким средством являются шаблоны, вот одна из последних тем на это счет, многое было сказано в этом топике и не хочется повторяться: http://www.rsdn.ru/Forum/Message.aspx?mid=516933
Автор: AndrewJD
Дата: 23.01.04
. Никто же не решится экспортировать море темплейт классов в клиентский код, равно как в случае с аспектами, пользователю твоей компоненты нет необходимости импортировать определения всех аспектных атрибутов, его интересует бинарный протокол взаимодействия с компонентой, то есть какой то конечный тип, возможно даже скрытый за фабрикой. В случае же если он решил наследоваться, что бы переопределять некоторую функциональность, то это уже не совсем клиентский код, по этому ему прийдется подключить все атрибуты или составные темплейтные части этой компоненты для дальнейшего наращивания функциональности модуля. А какой язык дает при этом все эти возможности, это уже дело привычки и образования — я например дорожу плюсовыми приемами, хотя возможности библиотек джавы или .Нет очень впечатляющие, но код ведь буду писать я а не библиотека, и хотелось бы код этот все таки писать а не копировать из файла в файл.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[13]: Ответ
От: IT Россия linq2db.com
Дата: 26.01.04 15:27
Оценка:
Здравствуйте, mikа, Вы писали:

IT>>А блин, точно. Опять quick solution.


M>"Поспешишь — людей насмешишь".


Дык о тож

M>Русский поговорки забыл?


Ещё помню. Например такие:

— Не суди и не судим будешь.
— Как аукнется так и откликнется.



IT>>Что-то я видел на эту тему, правда давно это было, надо будет опять в Роторе покопаться.


M>Что именно, как без TP? Дык я же привел


Я не про это. Было что-типа CreateUninitializedObject
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Ответ
От: Merle Австрия http://rsdn.ru
Дата: 26.01.04 15:35
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>Согласен, но это уже вопрос воспитания.

Воспитание, конечно, воспитанием, но соломку подстелить никогда лишним не бывает.
Вообщем здесь как обычно, лучше переспать, чем недоесть...

B> Кому то проще наследоваться от ContextBoundObject и заколачивать в него гвоздями все необходимые атрибуты

Это уже вопрос конкретной реализации (а именно Net, каковая все-таки далековата от идеала).
Как-то надо все-таки определиться, мы обсуждаем Аспекты "в принципе" или Аспекты в Net, а то mika все на RP с CBO съезжает.

B>>>И обошлись без ContextBoundObject... Может я ошибаюсь, но преимущества АОП в .Net в том, что я могу обувать свои типы в атрибуты динамически, на этапе выполнения? Нужно ли это на этапе выполнения, это уже другой вопрос

Пока преимуществ AOP в Net не много... Я, откровенно говоря, только-только в это въезжаю, и уже хочется большего, но сама идея мне нравится.

B>Еще несколько лет назад я бы кинулся в драку защищать свой любимый С++, но со временем эта категоричность проходит, думаю у тебя тоже это случится, тридцатка уже стукнула или еще нет?


2IT Вот Игорь, воспитывал, воспитывал Мику, а сейчас тебя большие дядьки разуму научать будут...


B>Вобщем какое может быть отношение неискушенных программеров к АОП идеологии? На мой взгляд тут нет места сопоставлениям, AOP vs. OOP и так далее. Это две разные парадигмы, которые друг друга дополняют, но не заменяют. Базовый ООП является незаменимой частью дизайна архитектуры, интерфейсы и виртуальные методы сегодня еще никто не отменил. Вместе с этим, в современном программинге нечего делать без продвинутых средств реализации, каковыми и является к примеру АОП.

[+]
Вах, правильно говорищ! Собственна об том и речь, ясен хобот, что от OOP никто отказываться не собирается и поэтому не совсем ясно об чем спор.
И не совсем ясно с чем спорил ГВ, в своем изначальном постинге. Я так и не понял, он против АОП "в принцие" или нет? И каковы его аргументы если да?
Впрочем один я кажется помню, неконтролируемое вмешательство в логику поведения объекта извне, я прав?

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

Корректно ли говорить о "более правильном" или "менее правильном" дизайне? АОП предполагает все-таки большую гибкость, я бы даже сказал более удачное соотношение "гибкость/сложность кода", и в этом смысле дизайн с AOP более правильный.
Мы уже победили, просто это еще не так заметно...
Re[14]: Ответ
От: mikа Stock#
Дата: 26.01.04 15:40
Оценка:
Здравствуйте, IT, Вы писали:

M>>"Поспешишь — людей насмешишь".


IT>- Не суди и не судим будешь.

IT>- Как аукнется так и откликнется.

IT>)


ИТ бояться — на RSDN не ходить.

IT>Я не про это. Было что-типа CreateUninitializedObject


И каков принцип не помнишь? Может аналог FormatterServices.GetUninitializedObject, только напрямую через internal методы.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.