Имя: Пароль:
1C
 
1C Messenger для отправки сообщений, файлов и обмена данными между пользователям
,
0 Serginio1
 
15.12.15
16:12
Выложил статью http://catalog.mista.ru/public/434771/  файлы лежат здесь
http://catalog.mista.ru/public/238584/

Данная разработка позволяет пользователям 1С обмениваться сообщениями, файлами (до 3 мб). Запрашивать данные у клиента как Вэб или HTTP сервисах.
Основано на технологиях ASP.Net SignaR который использует WebSockets и т.д. для двунаправленного обмена данными. Используется обертка над классами .Net

В  свое  время  делал  клиента  для  Whats  App,  и  многие  приемы  взяты  оттуда.  Но  постоянно  они  что-то  меняют.  Плюс  нельзя  отправлять  любые  файлы,  использовать  клиента  как  web  сервис  и т.д.

Это продолжение v8: v8: Использование сборок .NET в 1С 7.x и 8.x
и Динамическая компиляция для использования .Net событий в 1С
Но уже с реальным примером. Может кого и заинтересует
1 bse
 
15.12.15
16:22
пользователи должны работать а не сообщениями обмениваться
2 vhl
 
15.12.15
16:23
(0) смайлов нет? В топку!
3 Serginio1
 
15.12.15
16:33
(1) Часто нужно автоматически передавать сообщения об оновлении и тд с сервера
(2) Смайлы можно сделать. Все в твоих руках.
4 vhl
 
15.12.15
16:49
(3) винду тоже можно заново написать, только зачем?
5 Serginio1
 
15.12.15
16:50
(4) Не пиши
6 Serginio1
 
15.12.15
16:53
(4) Это не совсем мессенджер. Его можно использовать для получения данных например для мобильного от программы 1С подготовленными данными и передачей данных с мобильного клиента. Вариантов куча. Все зависит от задачи
7 Serginio1
 
15.12.15
17:34
да надо в пятницу выкладывать
8 anatoly
 
15.12.15
17:49
а чем это отличается от ДО ?
9 Serginio1
 
15.12.15
17:55
Что такое ДО?
10 anatoly
 
15.12.15
17:56
(9) ДокументоОборот
11 Timon1405
 
15.12.15
17:57
(10) +Там есть встроенная внутренняя почта с адресной книгой, подгружаемой из аутлука, и вложениями
12 Serginio1
 
15.12.15
17:58
(10) Тем как ДО отличается от скайпа,твитера, вэб сервисов, пуш уведомлений
13 anatoly
 
15.12.15
18:04
(12) кхм... ДО как раз через ВС можно с чем угодно синтегрировать, +куча доп.фич.
а просто отправлять/принимать почту (с вложениями) - дык все типовые давно умеют.
ваш то мессенджер чем лучше?
14 anatoly
 
15.12.15
18:07
+ (13) я просто в статье вижу сразу кучу кода, но не вижу главного в самом начале - КАКИЕ ПРЕИМУЩЕСТВА?
15 Serginio1
 
15.12.15
18:07
(13) Это не только мессенджер. Ты можешь программно запросить данные у другого клиента используя его как вэб сервер, можно отключать всех без постоянного чтения констант экономя ресурсы итд
16 Serginio1
 
15.12.15
18:09
(14) А вообще переписываться через почту это еще то извращение. Предпочитаю Скайп
17 Serginio1
 
15.12.15
18:12
(14) Можно отправлять данные на мобильные телефоны. Я побаловался с Xamarin под Андроид. Работает, но еще сыровато
18 Serginio1
 
15.12.15
18:36
Ну вот и последователи появились http://www.forum.mista.ru/index.php
19 Serginio1
 
16.12.15
15:57
Интересно какими разработками можно заинтересовать людей?
Кстати http://www.forum.mista.ru/index.php очень здорово оформлена
20 Гёдза
 
17.12.15
10:20
(19) Любыми. Правильный вопрос КАК?
21 Serginio1
 
17.12.15
10:38
(20) Например в 14 человек видит только кучу кода. И для него почта это все. И зачем люди придумали кучу мессенджеров,
Вэб, HTTP сервисов?
В данной разработке, я показал только как можно использовать дуплексный обмен данными. А вот нужную реализацию нужно развивать от существующих задач.
22 Гёдза
 
17.12.15
10:45
(21) Тебе бы курс по написанию тех статей пройти
23 Serginio1
 
17.12.15
11:06
(22) ну так как в 19 я не смогу. Нет у меня художественного видения.
24 bzs015
 
17.12.15
11:08
Было в других программах 1С -  ЭДО, а стало ДО?
25 los_hooliganos
 
17.12.15
11:13
(19) Что там за ссылка?
26 Serginio1
 
17.12.15
11:13
(24) Это не ко мне. Я в 9 тоже не понял.

Кстати в картинке к статье есть интересное сообщение. Никто на него не обратил внимания
27 Serginio1
 
17.12.15
11:14
(25) Прошу прощения http://catalog.mista.ru/public/434345/
28 Serginio1
 
18.12.15
14:58
Делая эту разработку подумалось, а почему бы 1С не предусмотреть подписку на серверные события. Например для SQL можно подписаться на события изменения таблиц.
SqlCacheDependency

https://msdn.microsoft.com/library/system.web.caching.sqlcachedependency(v=vs.100).aspx

http://habrahabr.ru/post/240269/

Аналогично, можно создать подписку на серверные события которые можно определять самим используя аналог SignalR типа Push уведомлений при изменении редко изменяющихся значени

http://metanit.com/sharp/mvc5/16.5.php


Можно держать постоянные данные на клиенте, что бы не ползать за данными на сервер итд.
29 Гёдза
 
18.12.15
15:06
(28) У 1с нет таблиц ))) есть объекты
30 Гёдза
 
18.12.15
15:06
а подписки на изменения объектов есть )))
31 Serginio1
 
18.12.15
15:11
(30) То есть я из другой сессии могу подписаться на изменение, Можно посмотреть как. А то сейчас больше на 7.7.
Видно отстал от жизни.
32 Serginio1
 
18.12.15
15:35
Не знаю, как для кого, а для меня была бы удобная штука. Хотя и эту разработку для этого можно и прикрутить
33 Гёдза
 
18.12.15
15:37
Я вот одного не могу понять почему ты так упорно и так БЕЗГРАМОТНО пытаешь продвигать свою программу?
34 Гёдза
 
18.12.15
15:38
В этом ты похожь на Г1С с его статистическим подходом
35 Serginio1
 
18.12.15
15:43
(34) В данном случае пока разговор о пуш уведомлениях.
Вопрос какую из многих я безграмотно продвигаю?
Я делюсь опытом, если, что непонятно спрашивай.
36 Злопчинский
 
18.12.15
16:00
(31) а вот это мне очень интересно! хочу простым и безгеморройным образом иметь в текущей сесиии "уведомления" об изменении разных типов объектов, вплоть например документов одного типа но с определенным набором ключевых реквизитов.

Сами уведомления по сессиям далали уже давно, например на NetaInet пример Садовникова
37 Злопчинский
 
18.12.15
16:00
и если что - я про клюшки
38 Serginio1
 
18.12.15
16:04
(36) Чуть позже сделаю обработку и для 7.7
Там несложно нужно применить врап.СоздатьОберткуДляСобытий77(NetОбъект);

Здесь http://catalog.mista.ru/public/417830/ подробно написано.
39 Serginio1
 
18.12.15
16:07
Но для документов нужно немного допиливать. Какие данные отправлять клиенту.

Можно типа
Событие Изменения,
Тип
Вид
Элемент
40 Злопчинский
 
18.12.15
17:21
(39) По сути это типа "подписка на событие" - это может быть изменение чего угодно - и документа и справочника и регистра
41 Злопчинский
 
18.12.15
17:26
(38) Коллегна, вы не понимаете.

Представьте - я каменщик, кладу кирипичи. я знаю как класть кирипичи, что нужен раствор, что дом надо строить из влагостойких кирпичей, а печь из огнеупорных. Я прошу у вас кирпичей - а вы мну начинаете рассказывать про процессы геологоразведки и добычи глины и т.д. ;-)

Можно для "тупых" как-то попроще = вот кирпичи, они для того-то, класть так-то. Продираться через все это интересное мегаописание процесса добычи глины и изготовления кирпичей - ну не с руки, понятно что там где-то есть слева за углом штабелем и сами кирпичи, но есть шанс чтоя не дойду налево за угол, сопьюсь по дороге.. ;-)
42 Serginio1
 
18.12.15
17:58
Я понимаю. Но для того что бы класть кирпичи ты должен разбираться в кирпичах.
То есть какие данные ты хочешь передавать и получать
43 Злопчинский
 
18.12.15
18:10
(42) это понятно. я к тому, что (условно) в результате будет некая "ВК" и описание ее "методов". а что там внутри что во что обернуто - совешенно пофиг. Могу быть не прав, но вот такая конструкция
врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
имхо вылом мозга.
мне как программеру ВАЖНО знать что что-то является чем то оберктой? да еще переносить эти сущности/названия на объекты/методы ВК..? как-то попроще хочется, без излишней зауми. На примере взять тот же формекс - куча возможностей, но просто и понятно (Альф - великий чилавек!)

http://catalog.mista.ru/blogs/data/0000564/images/small/alf010.jpg

http://catalog.mista.ru/blogs/data/0000564/images/small/alf014.jpg

http://catalog.mista.ru/blogs/data/0000564/images/small/OZK.jpg
44 Serginio1
 
18.12.15
19:35
Ты можешь не вдаваясь в врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);

Напиши какие данные ты хочешь передавать.
На выходе получишь Метод с параметрами и  ОбработкаВнешнегоСобыти и наименованием события и с данными в объекте.

Например, что тебе непонятно в таком коде

Перемврап,ОберткаСобытий;

Функция СоздатьОбертку(ОбертываемыйОбъект)

// В NetObjetToIDispatch.dllреализованклассВКpublicclassGlobalContext1C :IInitDone, ILanguageExtender

//для получения глобального контекста при вызове

// publicvoid Init([MarshalAs(UnmanagedType.IDispatch)]
//     object connection)
//    {
//        глобальныйКонтекст = connection;
//        Marshal.GetIUnknownForObject(глобальныйКонтекст);
//  }


    ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C");
    объект = СоздатьОбъект("AddIn.GlobalContext1C");
    ГлобальныйКонтекст= объект.ГлобальныйКонтекст;

    ОберткаСобытий= врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
КонецФункции // СоздатьОбертку



// Свойства ОберткаСобытий.ПоследняяОшибка
//Событие:String Имя События в котором произошло исключение
//Данные:object Параметры события
//ИсключениеСобытия:Exception Ошибка произошедшая при вызове события
Функция ОшибкаСобытия()
    ПоследняяОшибка=ОберткаСобытий.ПоследняяОшибка;
    Сообщить("Не обработано событие "+ПоследняяОшибка.Событие);
    Сообщить(Врап.ВСтроку(Шаблон("[ОберткаСобытий." + ПоследняяОшибка.Событие+ "]")));
    Сообщить("Ошибка");
    Сообщить(врап.ВСтроку(ПоследняяОшибка.Исключение))
КонецФункции
//  Свойства ОберткаСобытий.Changed
// sender:System.Object
// e:System.IO.FileSystemEventArgs

Функция Changed()
    Сообщить("Changed "+Врап.ВСтроку(ОберткаСобытий.Changed));
КонецФункции

//  Свойства ОберткаСобытий.Created
// sender:System.Object
// e:System.IO.FileSystemEventArgs

Функция Created()
    Сообщить("Created "+Врап.ВСтроку(ОберткаСобытий.Created));
КонецФункции

//  Свойства ОберткаСобытий.Deleted
// sender:System.Object
// e:System.IO.FileSystemEventArgs

Функция Deleted()
    Сообщить("Deleted "+Врап.ВСтроку(ОберткаСобытий.Deleted));
КонецФункции

//  Свойства ОберткаСобытий.Error
// sender:System.Object
// e:System.IO.ErrorEventArgs

Функция Error()
    Сообщить("Error "+Врап.ВСтроку(ОберткаСобытий.Error));
КонецФункции

//  Свойства ОберткаСобытий.Renamed
// sender:System.Object
// e:System.IO.RenamedEventArgs

Функция Renamed()
    Сообщить("Renamed "+Врап.ВСтроку(ОберткаСобытий.Renamed));
КонецФункции

//  Свойства ОберткаСобытий.Disposed
// sender:System.Object
// e:System.EventArgs

Функция Disposed()
    Сообщить("Disposed "+Врап.ВСтроку(ОберткаСобытий.Disposed));
КонецФункции




Процедура ПриОткрытии()
    врап=СоздатьОбъект("NetObjectToIDispatch45");

КонецПроцедуры // ПриОткрытии
//======================================================================
Процедура ОбработкаВнешнегоСобытия(Источник, ИмяСобытия, Данные)
    Если Источник = "System_IO_FileSystemWatcher" Тогда

        Шаблон("[" + ИмяСобытия+ "()]");
    КонецЕсли;
КонецПроцедуры // ОбработкаВнешнегоСобытия
45 Serginio1
 
18.12.15
19:39
При этом весь этот код генерится автоматически. Тебе только нужно прописать свой код в событиях
46 Serginio1
 
18.12.15
20:03
47 Злопчинский
 
18.12.15
20:43
(46) нет, не скачал, потому как не занимаюсь ни Net, ни компилияцией, тем более динамической, ни прикручиваением внешних всяких фишек к 1С (не умею/не мое)

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

Самый минимум который нужен:
1. факт изменения справочника "Номенклатура" (с ссылкой на конкретный элемент) в т.ч. при удалениях, снятиях удаления, перемещения из группы в группу (смена владельца) - в т.ч. оповещение должно приходить и при интерактивных действиях пользователя в соседних сессиях и при программных (если скопом в транзакции изменено множество элементов - както получить такой список).
2. аналогично п.1 - для Справочник.Единицы (Подчинен номенклатуре, в т.ч при смене владельца)
3. изменение Документ.ЗаявкаПокупателя  - в т.ч. проведение, распроведение, удаление, снятие удаления, сдвиг по оси времени
4. факт изменения ГраницыПоследовательности
- для начала можно тренирнуться на этом.
если конечно это реально.
то есть грубо говоря я хочу иметь подписку практически на каждый чих в соседней сесии, который влечет за собой изменения данных...
48 Serginio1
 
18.12.15
20:53
Ты можешь его иметь. От меня нужна только функция которая отправляет оповещения и обертка с событиями которая будет вызывать внешнее событие.
Ты мне должен назвать сигнатуру метода. Параметры этой функции будут доступны при оповещении.
А так скачай и посмотри примеры на 1С 7.7
49 Злопчинский
 
18.12.15
21:03
(48) "Ты мне должен назвать сигнатуру метода."
- я вот тут не понял, это что такое..? откуда я ее возьму чтобы тебе дать?
50 Serginio1
 
18.12.15
21:11
А я рткуда возьму, что тебе надо&
Например
ОтправитьСообщениеОбИзменении(ЗначениеВСтрокуВнутр(ИзмененныйОбъект))

Соответственно при оповещении


//  ОберткаСобытий.Changed :System.String


Функция Changed()
    Сообщить("Changed "+Врап.ВСтроку(ОберткаСобытий.Changed));

Объект=ЗначениеИзСтрокиВнутр(ОберткаСобытий.Changed);
ну и дальше твои действия
КонецФункции


//======================================================================
Процедура ОбработкаВнешнегоСобытия(Источник, ИмяСобытия, Данные)
    Если Источник = "КлассОбработчикСобытия" Тогда

        Шаблон("[" + ИмяСобытия+ "()]");
    КонецЕсли;
КонецПроцедуры// ОбработкаВнешнегоСобытия
51 Serginio1
 
19.12.15
00:20
Например сейчас есть отправка команд

public async Task ВычислитьВыражение(string Кому, string Команда, string ДанныеСтр)
        {
            var Данные = UTF8Encoding.UTF8.GetBytes(ДанныеСтр);
            await ВычислитьВыражение(Кому,Команда,Данные).ConfigureAwait(false);
}

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

Что выберешь, то и сделаю
52 Злопчинский
 
19.12.15
01:14
(50)  а ОтправитьСообщениеОбИзменении - это тоже будет твоя функция? Ее код какой примерно?
53 Serginio1
 
19.12.15
08:49
(52) Аналогично (51) Ты почитай статью и ссылки. Там ничего сложного нет.

public async Task ВычислитьВыражение(string Кому,string Команда,byte[] Данные)
        {
            bool ДанныеСжаты;
            byte[]  данные =  ПолучитьДанныеДляОтправки(Данные, out ДанныеСжаты);
          //  EvaluteCommand(string Кому, string command, byte[] Data, bool isCompressed)
           await myHub.Invoke("EvaluteCommand", Кому,Команда, данные, ДанныеСжаты).ConfigureAwait(false);
        }
54 Serginio1
 
19.12.15
08:55
Например отправить сообщение выглядит так

public async Task ОтправитьСообщение(string Сообщение, string Кому)
        {
            await myHub.Invoke("SendEcho", Сообщение, Кому).ConfigureAwait(false);
        }

Ты главное определись какие данные хочешь отправлять
55 Serginio1
 
19.12.15
09:04
byte[] ПолучитьДанныеДляОтправки(byte[] Данные, out bool ДанныеСжаты)
        {
            var данные = Данные;
            ДанныеСжаты = false;
            var сжатыеДанные = СжатьДанные(Данные);
            if (сжатыеДанные.Length < данные.Length)
            {
                данные = сжатыеДанные;
                ДанныеСжаты = true;
            }
            return данные;
        }
56 Serginio1
 
19.12.15
10:19
То есть ты можешь сказать какая сигнатура метода тебе нужна и я её реализую.
57 Злопчинский
 
19.12.15
13:16
(56) я не понимаю что такое "сигнатура метода"
и
"ОтправитьСообщениеОбИзменении" - это что за функция - она вызывает методы твоей ВК? Примерный код ее какой?
58 Злопчинский
 
19.12.15
13:17
(53) не хочу принципиально идти глину искать в тайге
59 Serginio1
 
19.12.15
13:53
Ну ты лентяй https://www.google.ru/search?as_sitesearch=forum.mista.ru&q=Serginio1+Des&gws_rd=ssl#newwindow=1&q=сигнатура+метода

Сигнатура метода это параметры и их тип
(58) А стоит почитать. Программисту все понятно.

ОтправитьСообщениеОбИзменении это предложенная мною тебе метод который принимает 1 параметр типа строка.
60 Serginio1
 
19.12.15
13:55
61 Serginio1
 
19.12.15
13:56
(58) Когда ты хочешь применить технологию, стоит понять как она работает
62 Злопчинский
 
19.12.15
14:19
(61) нафейхоа? моя задача как шоферюги выбрать наилучший путь чтобы груз с меньшими издержками довезти куда надо. Для этого не начинаю разбираться в технологиях укладки асфальта и внутренностях двигателя. Я ж не на багги еду который сам сварил...
63 Злопчинский
 
19.12.15
14:20
(59) не хочу читать, ибо я не программист. потому что программисты пишуть такую хрень, которая работает но работать с ней невозможно нормально.
64 Злопчинский
 
19.12.15
14:26
давай тогда попроще. с маленького.
дай мне фигнюшку, с помощью которой я могу получать в текущей сессии инфу об изменении (пофиг о каком, просто факт изменения) элемента(ов) справочник.номенклатуры.

что где делать?

1. то что при старте системы надо подгрузит ВК - я понял ;-)
2. ?
65 Serginio1
 
19.12.15
14:59
(64) Ну скачай 46. Там есть пример динамической компиляции на примере изменения директории. По сути передача изменений та же суть. Только требует IIS
66 Serginio1
 
19.12.15
15:02
Не обращай внимание на динамической компиляции. Просто подключение к событиям как в 8ке ПодключитьОбработчик
67 Злопчинский
 
19.12.15
15:03
(65) не буду пок аничего качать. меня пугают ваши слова. "динамическая копиляция" - нафига он амне - девелоперу?
и IIS у меня нет.
68 Злопчинский
 
19.12.15
15:04
(66) не могу. там много словов. я в них путаюсь.
69 Serginio1
 
19.12.15
15:25
IIS есть на любом Win. Просто для вэб сокетов нужно от Win 8 и выше. http://professorweb.ru/my/ASP_NET/sites/level3/3_1.php

Для того, что бы помотреть как работает подключение к событиям IIS не требуется/
А подключение к событиям элементарно

ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C");
    объект = СоздатьОбъект("AddIn.GlobalContext1C");
    ГлобальныйКонтекст= объект.ГлобальныйКонтекст;

    ОберткаСобытий= врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
70 Злопчинский
 
19.12.15
15:27
ОбертываемыйОбъект - есть что?
71 Злопчинский
 
19.12.15
15:27
первые три строки - вроде понятно...
72 Serginio1
 
19.12.15
15:36
(71) Ну вот видишь. Возьмем для примера, то, что не хочешь скачать.

Начнем с начала

Процедура ПриОткрытии()
// Врап это объект для обертки нетовских Классов, объектов
    врап=СоздатьОбъект("NetObjectToIDispatch45");
    врап.УстЭтоСемерка();
КонецПроцедуры // ПриОткрытии
//======================================================================
73 Serginio1
 
19.12.15
15:39
// FileSystemWatcher это нетовский объект следящий за изменением директории
watcher= врап.СоздатьОбъект("System.IO.FileSystemWatcher, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

// Устанавливаем необходимые реквизиты где следим, и за чем следим

    Директория=Каталог;
    watcher.Path = Директория;
    true=врап.ChangeType("System.Boolean","true");
    false=врап.ChangeType("System.Boolean","false");
    watcher.Filter = "*.*";
    
    ДелегатИЛИ=ПолучитьМетод();
    NotifyFilters=врап.ПолучитьТип("System.IO.NotifyFilters");
    рез=Или2(NotifyFilters.LastAccess,Или2(NotifyFilters.LastWrite,Или2(NotifyFilters.FileName,NotifyFilters.DirectoryName)));
    
//    Сообщить(Врап.ВСтроку(рез));
    watcher.NotifyFilter=рез;
    watcher.IncludeSubdirectories = true;
    
    watcher.EnableRaisingEvents = true;
    
    СоздатьОбертку(watcher);
74 Злопчинский
 
19.12.15
15:45
(73) ну допустим в целом понятно, хотя дохрена неодинэсных букв с которыми разобраться еще надо. но мне-то для моей задачи - отследить изменеие спрачоника.номенклатура - нафейхоа это?
75 Злопчинский
 
19.12.15
15:46
из полезного только - ПриОткрытии()
76 Serginio1
 
19.12.15
15:54
(74) Это не важно. Есть некоторые свойства которые ты должен установить. Описание всех свойств и методов можешь посмотреть здесь https://msdn.microsoft.com/ru-ru/library/system.io.filesystemwatcher(v=vs.110).aspx


Теперь к твоей задаче.
При изменении ты должен вызвать метод с парамтрами, которые будут разосланы вмем подписчикам. А вот , что нужно передавать ты должен решать сам
77 Serginio1
 
19.12.15
16:40
Ну еще вариант, это подписка на события к Ms SQL
http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach
78 Serginio1
 
19.12.15
23:56
Есть два подхода.
1. Вызывать оповещение при записи, ОбработкаПроведения
2. Использовать оповещение Sql сервера и оповещать из того же Asp.Net
https://msdn.microsoft.com/ru-ru/library/system.data.sqlclient.sqldependency(v=vs.110).aspx
79 Злопчинский
 
20.12.15
00:07
(78)  ну... База файловая
80 Serginio1
 
20.12.15
00:58
(78) Значит вариант 1
81 Serginio1
 
20.12.15
09:14
(79) Можно упростить, так как семерка только в локальной сети, можно использовать TCP/IP
http://www.codeproject.com/Articles/596287/Broadcasting-Events-with-a-Duplex-WCF-Service
82 Serginio1
 
21.12.15
11:17
(79) Ну, что решил ...
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший