Я бы даже и ничего не писал, но вдруг кто поверит. Поизучай на досуге прям первый абзац вот отсюда: https://core.telegram.org Я знакомому уже даж болванку клиента на этой "бинарной" либе написал....
И ситуация когда класс наследует интерфейс и его же экземпляр получает в конструктор мне кажется странной.
Это класс, который может быть как полноценным независимым хранилищем, так и ссылкой на ветку в уже существующем.
# независимое хранилище
s = Settings()
# Ссылка на ветку my.internal.object в другом хранилище
sub = s.sub_cfg('my.internal.object')
В первом случае объект сам манипулирует данными, во втором делегирует все действия по цепочке владельцев оригинальному хранилищу. Это сделано для того, чтобы в разных объектах ветви могли пересекаться. К примеру некий "UsersArray" работает с веткой "users", каждый отдельный "User" с ветками внутри нее, а сессия все это хранит целиком. Любые изменения вносятся в единое место. Скорее всего это уже 100 раз реализовано и, возможно, более "правильно". Я это писал в первый день, разбираясь с rtti питона т.к. было интересно.
Вы вообще не поняли ни о чем статья, ни для чего весь написанный код. Скорее всего, увидев первое же слово, которое Вы посчитали оскорблением, остальное не читали вообще, либо сквозь кровавую пелену агрессии. Пролистайте чуть выше, я уже в комментарии пояснил, что цели оскорбить кого-то у меня не было.
Если по делу, то у меня не было цели "уйти от пулинга". Это не реализуемо в принципе. Моя цель была избавить пользователя даже от мысли что он есть. Код пользователя в моем примере - это ТОЛЬКО файл main.py до строчки: botSession = BotSession(dp, Logic)
Учитывая остальное сообщение: это как? Это либа для реализации какой-то логики. Как это применимо "от своего аккаунта"? Что именно вы хотите сделать?
но не от бота , а от своего акка, со свои логином паролем. можно ли такое сделать?
Для работы с телеграмом есть 2 возможности: создать бота, который делает какие-то действия автоматически и создать клиента телеграма (т.е. аналог того клиента, которым Вы пользуетесь). Во втором случае, если делать что-то узко-специализированное свое, то да, можно сделать софт, который будет реализовывать клиента с автоматическим подключением именно Вашего телефона, и выполнять какие-то действия от Вашего имени. Если не секрет: зачем?
Ясно. В этих примерах функции с вложенными функциями, что я использовал как своего рода private. Кроме BotChat.waitProcess, в которой просто вложенность для отладочного логирования в виде:
D:\MYTESTS\LinearBotLib\bot.py[930]::ask( ask ) {
D:\MYTESTS\LinearBotLib\bot.py[895]::popup( popup ) {
new msg 3642 text Which version do you want to test?
SM: add KBD waiter <bot.Waiter object at 0x000000F1E8F923E0>
CH: add waiter[0, m: False] : <bot.Waiter object at 0x000000F1E8F923E0>
CH: waiter added[1]
D:\MYTESTS\LinearBotLib\bot.py[303]::_OnPopupMessage( msg, 3642 ) {
M: del waiter
CH: del waiter 1 m: False w: <bot.Waiter object at 0x000000F1E8F923E0>
CH: waiter deleted 0
PM: add waiter
CH: add waiter[0, m: True] : <bot.ModalWaiter object at 0x000000F1E8F923E0>
CH: waiter added[1]
waiting modal True
D:\MYTESTS\LinearBotLib\bot.py[472]::waitProcess( logic, True ) {
WP waiters 1
PM: msg OK: <bot_types.BotKeyboardResult object at 0x000000F1E8F91780>
thisMsg
WP 0 modal True rc True
notify_complete
WP ret 0
}
PM: lrc: <bot_types.BotKeyboardResult object at 0x000000F1E8F91780>
}
D:\MYTESTS\LinearBotLib\bot.py[768]::delete( msg, <bot.BotMessage object at 0x000000F1E8F92050> ) {
del= 3642
}
}
}
Если выкинуть вложенность, то радон становится почти счастлив:
D:\MYTESTS\LinearBotLib>radon cc . -s -n C
bot.py
M 468:4 BotChat.waitProcess - C (12)
M 573:4 BotChat.logicStart - C (11)
bot_imessage.py
M 135:4 BotIMessage._display - C (15)
main.py
F 26:0 logic_MENU_Form - C (12)
F 149:0 logic_MENU_Animation - C (12)
settings.py
F 540:0 pSINGLE - C (13)
Вообще, разумеется, разодрать ее на куски для удовлетворения радона, конечно, можно. Просто я обычно в коде исхожу из следующего, раздирать функции надо если: функция сильно не влезает на экран, имеет длинную сложную логику, длинный куски кода в ветках логики. В данном случае, функция у меня помещается на экран, а если "сфолдить" ее 3 независимые части, то будет вообще 4 строчки (как это видно в IDEA).
async def waitProcess(self, message: Message_t = None, data: types.CallbackQuery = None):
"""Process received data or message thru waiters queue"""
if not message and not data: return False
with PROC('logic', self.logicWorking):
# start/restart bot logic
if message and message.text[0] == '/': ...
# bot logic is down
if not self.logicWorking: ...
# have no bot logic, nothing to do
if not self.logicWorking: return
# dispatch events
LOG('WP', 'waiters', len(self.waiters))
if len(self.waiters): ...
На мой вкус не заслуживает упрощения. Это я не ради спора, просто поясняю.
Зачем заставлять пользователя писать эти while True блоки, и давать ему возможность делать несогласованные части? Это всё от пользователя можно спрятать внутри библиотеки.
Вы вообще смысла моего кода не поняли. Смысл как раз в том, что пользователь общается с функционалом бота полностью в линейном режиме, как если бы он использовал консоль для ввода input-ом, и выводом print-ом. Никакие дополнительные классы не нужны. await chat.menu() - это уже "класс" меню. Законченный. В этой строчке он отрисует свой интерфейс в телеграме, дождется реакции пользователя и вернет то, что он там выбрал. Сюда же. Пользователя никто циклы писать не заставляет - он может реализовывать свою логику как ему угодно, хоть создавая классы, хоть делая циклы. Весь main.py - это сплошной код "пользователя". О телеграме, его протоколе, способах взаимодействия с ним и особенностях пользователь не обязан знать практически ничего. Для реализации всего что ему надо, по сути, достаточно BotChat.say, BotChat.menu, BotChat.ask и BotChat.delete. Для чуть более сложных "интерфейсов" еще и BotIMessage. По сути все.
В статье великий мастер божественного языка снизошёл для того, чтобы посмотреть языки простых смертных.
Откуда такой сарказм? Впрочем, я наверное догадываюсь, Вы восприняли выражение "птичий" как оскорбление? Дико извиняюсь, автопилот. Просто это выражение мне стало привычным очень много лет назад. Оно не несет никакой негативной нагрузки и является своеобразным "техническим термином", обозначающим не компилируемый язык, как правило узко-нишевый. В 80х, когда начали активно развиваться скриптовые языки, в том числе мы писали их сами, часто звучало: "Как ты это сделал?" - "Написал свой птичий язык". Это просто было кратчайшее пояснение. В общем, как-то так. Еще раз извиняюсь, если оскорбил.
По остальному тексту многое непонятно. Что такое "цикломатическая сложность" я прочитал, но не уверен что понял к какой именно части относится претензия. Вы не могли бы ткнуть пальцем?
Класc ISettings я использовал не как прокси (хотя он именно это), а в попытке хоть как-то разделить реализацию и описание т.к. я так и не понял какими методами это делается. Описаний в питоне нет (собственно я знаю только паскаль и С с ними), поэтому мне приходилось либо тащить весь код в 1 файл, либо это не собиралось из-за циклических зависимостей.
Претензию про main.py я тоже не понял. Этот файл - единый сборник примеров использования не особо связанных друг с другом. Можно было бы написать с десяток разных файлов с раздельными примерами, в этом проблема? Мне показалось, что будет проще запустить одного бота и сразу посмотреть все (+-) что может либа, чем запускать кучу тестов.
Про количество кода это была шутка. Жаль что опять оказалась, видимо, оскорблением. Хотя все претя писать объект класса - это раздражало. Я еще не использовал языков, в которых были бы объекты, но в их методах нужно было бы всегда явно его писать.
Спасибо за отзыв. С кейсом переменных понятно. В разных средах требования и стандарты разные. Я привык по другому и, на мой взгляд роли особой это в данном случае не играет. А по остальным пунктам, если можно, подробнее. Интересует: что за лишние абстракции и уровни вложенности. О чем речь? Если можно, то с примером как оно "должно быть". Интересно.
Если класс описал ты в файле м1, а другой класс в файле м2, а затем через интерфейс их объединил это не разделение?
Подразумевается вто в м1 и м2 реализации интерфейсов?
Да такой подход к разделению возможен. Оптимален в бесконечно малом числе случаев, а остальные делятся на 2 варианта: либо количество оверхера будет превышать кодирование, либо это вообще не выполнимо т.к. в реализации нужно оперировать prtected-ными члемами базы.
Учитывая все это я и написал что невозможно. Не в теории. На практике.
То, что в инспекторе объектов отображается на второй закладке - это просто проперти с типом "указатель на функцию", не более того. Уточню, т.к. есть у меня подозрения в непонимании: указатель на функцию именно члена класса. Любого класса. Хоть формы, хоть любого другого. Дизайнер создает такие функции "обработчики" автоматически в том что редактирует (оно как бы и логично) - в форме. Но никто не мешает их иметь вообще где угодно. Хоть заведи синглетон для с функциями обработчиками событий вообще всех компонентов приложения.
Если вопрос был в том, что "можно ли сказать дизайнеру, что функции создавать в другом месте", то скорее нет чем да, но нужно покопаться в интерфесах для плагинов дизайнера, может и можно. Но никто не мешает задавать обработчики вручную, в коде. У меня так %в 30 гуя обрабатывается.
ПС: Разумеется, нужно помнить что указатель не на функцию класса, а на функцию объекта класса. Ибо __closure. Надеюсь это очевидно.
Не все раз в неделю пишут новую курсовую с нуля. В своем тексте я подразумеваю разработчиков, делающих долгосрочные проекты. Средство, которое они используют может развиваться, но не меняться. Разницу понимаете?
Неправильно я сформулировал. Не какая-то специфика, а набор факторов. Накидаю бессистемно, может понятнее станет.
Софт, который я пишу, в конечном итоге, в сетапе, состоит из 50 библиотек общего плана (dll/bpl), 54 экзешников и 25 плагинов (bpl) к разным частям. Где-то %20 от числа библиотек можно, наверное, выкинуть заменив штатными средствами того же шарпа, касающихся работы с электронной почтой и бащами данных. Остольного все равно очень много.
Софт эксплуатируется неподготовленными людьми и один из важных критериев - это "стандартность". Т.е. он должен выглядеть и управляться так же как стандартный виндовый софт. Т.е. всякие решения с плиточными интерфейсами и прочей альтернативщиной сразу идут лесом. Т.е. в С# у меня выбор только из WinForms. Возможно можно как-то извернуться и в WFP, но я не уверен.
Для иллюстрации разных аспектов написано около 60 собственных компонентов. Где-то половину из них можно, наверное, будет выкинуть найдя аналогичный по функциональности штатный аналог шарпа, или довольно быстро реализовать новый. Из оставшегося штук 5 являются довольно эксклюзивными штуками, существенными по коду. Полных аналогов я не видел. Т.е. придется довольно много реализовывать с нуля, чтобы получить аналогичные средства отображения.
VCL предоставляет механизм "легких" контролов, имея свои собственные деревья объектов, ктоторые не мапятся в виндовые контролы. В результате даже очень нагруженный интерфейс может на практическе иметь единственный HWND - контейнера. В WinForms, если я правильно читаю описание Contol, все интерфейсные элементы - это прямые враперы виндовых контролов. Ранее, работа с сотнями объектов у одного родителя приводила к жутким тормозам. Как дело обстоит сейчас я не знаю, но мест где у меня создается МНОГО интерфейсных объектов есть у меня.
Большая часть моего софта - это клиенты для моего же сервера, общающиеся с ним по бинарному протоколу по IP стремными сокетами. Чтобы дописывать что-ибо к существующей системе придется реализовывать этот интерфейс на шарпе. Бинома ньютона тут, конечно, нет, но это делает полностью бессмысленным "дописать что-то новое на шарпе" т.к. без средств связи оно будет бесполезно.
В итоге. Для того чтобы делать что-то интерфейсное на шарпе мне необходимо реализовать существенный объем собственных контролов, работать это будет виндовыми средствами (т.е. возможна ситуация, когда аналогичный существующему гуй будет работать хуже).
Что я получу, переведя код в шарп? Если не учитывать времени, которое потребуется на овладение этим инструментом на том же уровне, на каком я владею используемыми сейчас, и времени, которое потребуется на собственно кодирование и тестирование, я получу... всего 2 преимущества:
Надежду на то, что WinForms просуществует в поддержке дольше чем поддержка 32 битного кода виндой. Т.е. микрософт завтра может сказать "мы WinForms дропаем" и я поимею дикие проблемы. Писать же на древнем билдере я могу до тех пор, пока 32 битные приложения будут запускаться на винде.
Возможность использовать стабильные средства для работы с интернет. Не то чтобы это было бы мне нужно прямо сейчас, но сам факт, что можно использовать гарантированно работающее, штатное средство вместо подъема http для реализации REST или WebSockets на каком-нить Mangoose - это несомненный плюс.
Что я получу в "минусах", если переведу софт на шарп:
Значительно более сложный и трудоемкий процесс по созданию новых интерфейсных частей и поддержке существующих. Я экспериментировал с шарпом, конечно, не много, но пришел к выводу, что скорость разработки интерфейсов на нем не сравнима со скоростью с VCL. Это в винформс, с WPF ситуация еще хуже.
Мизерность готовой кодовой базы. Все-таки я изобретаю не все на свете велосипеды и часть кода у меня используется из различных сторонних библиотек. Даже если отфильтровать только то, что мой 5й билдер способен собирать, то количество готового кода для Delphi превышает весь доступный код для шарпа, наверное, на порядки. Это может закончится тем, что мне понадобится реализовывать каку-то сложныю хрень, типа рантайм дизайнера компонентов или текстового редактора. Чего делать бы не хотелось.
Некоторые сложности и странности доступных срадств. К примеру, OLE - это число виндовая технология от микрософт, но ее штатная поддержка в шарпе отсутствует. Если в том же вижуал васике я могу написать практически только название класса с гуидом и все кишки автоматически подтянуться сами и класс можно использовать сразу же как нативный, то в шарпе для этого придется постараться. В частности OLE я использую для работы с OPC. У меня есть и сервер и клиент. Реализация этого на шарпе быдет существенно сложнее того что я делаю сейчас. Второе что использую - это прямая работа с ком-портами для работы с оборудованием, к примеру GSM модемами. Возможно, в шарпе с этим не будет проблем, а может и возникнут. Во всяком случае ничего сложнее поделок на эту тему на шарпе я не находил.
Вопрос был в другом: зачем они вообще нужны в описанной мной задаче и как они позволят разделить код физически, если предположить (на практике так оно и есть), что логически он не разделим.
Ничего не понял. Зачем какие-то свойства из интерфейсов, кто их будет использовать? Как можно создать финальный класс без реализации? В каких других файлах и длл-ах?
Поясню что я имел в виду. Я пишу наследника какого-нить TWinControl. Мне его нужно использовать напрямую, т.е. создавать объекты такого класса. Как мне помогут какие-то интерфейсы разделить код реализации этого класса на несколько файлов?
Вот к примеру Resharper - богатое на фичи расширение к Visual Studio
Спасибо. В какой версии он уже есть максимально функциональный? Сам вижуал мне применить негде, но для теста интересно было бы посмотреть.
Вам там какой фичи не хватает, чтоб было ближе к "уровню java" ?
Мне лично всего хватает. Львиную долю сорсов я набиваю вообще в редакторе FARа. Если же говорить о том, что мне понравилось при писании на том же Kotlin - это:
контекстная подстановка конструкций. Если я написал if и закрыл скобку, то при наборе "е" я получаю "else"; находясь в скопе класса по "pu" public и не наоборот. И т.д.
по мере ввода моментально получаю список того, что возможно использовать в этом месте, отсортированный по локальности. Т.е. сначала локальные переменные, потом классовые, предков, привязок и т.д.
в списке подстановки находится только то, что можно применить. Если в месте использования нужна функция, то будут только функции, которые возвращают то, что нужно в месте использования, если нужен енум определенного типа, то будут только его элементы и т.д.
Это конечно больше таракан явы, в которой нет хелпа, но часто очень сильно помогает javadoc, который вспывает когда ты ходишь по списку предложений. Как найти что-то новое, так то, что ты забыл как называется или что именно точно делает.
В результате работы такого средства, часто, набор кода заключается в наборе разделителей, пары первых букв и нажатие пробела (или enter у кого как настроено).
Во-первых, в львиной доли ПО время ужодит не на работу, а на ожидание. Девайсов, инпута и т.д. Во-вторых, плохо написанная программа без gc почти всегда будет работать менее оптимально чем плохо написанная программа с gc. Язык неважен. Все "не нативные" языки были придуманы для того, чтобы понизить порог ими владения. Т.е. снизить требования к квалификации разработчика. С ростом производительности компов это стрельнуло в обратную сторону: всю работу, котора раньше требовала большей квалификации теперь может выполнять человек с заметно меньшей. Как следствие, снизилась потребность в квалифицированных разработчиках, их перестали готовить, мест приложения их сил стало меньше - они почти вымерли. Я это к тому, что в большинстве случаев, сравнивая "среднюю по больнице" программу написанную на языке без gc и с ним, нам придется сравнивать именно плохо написанные программы. Это сильно нивелирует разницу между этими средствами.
Я бы даже и ничего не писал, но вдруг кто поверит.
Поизучай на досуге прям первый абзац вот отсюда: https://core.telegram.org
Я знакомому уже даж болванку клиента на этой "бинарной" либе написал....
Это класс, который может быть как полноценным независимым хранилищем, так и ссылкой на ветку в уже существующем.
В первом случае объект сам манипулирует данными, во втором делегирует все действия по цепочке владельцев оригинальному хранилищу.
Это сделано для того, чтобы в разных объектах ветви могли пересекаться.
К примеру некий "UsersArray" работает с веткой "users", каждый отдельный "User" с ветками внутри нее, а сессия все это хранит целиком.
Любые изменения вносятся в единое место.
Скорее всего это уже 100 раз реализовано и, возможно, более "правильно".
Я это писал в первый день, разбираясь с rtti питона т.к. было интересно.
Вы вообще не поняли ни о чем статья, ни для чего весь написанный код.
Скорее всего, увидев первое же слово, которое Вы посчитали оскорблением, остальное не читали вообще, либо сквозь кровавую пелену агрессии.
Пролистайте чуть выше, я уже в комментарии пояснил, что цели оскорбить кого-то у меня не было.
Если по делу, то у меня не было цели "уйти от пулинга". Это не реализуемо в принципе.
Моя цель была избавить пользователя даже от мысли что он есть.
Код пользователя в моем примере - это ТОЛЬКО файл main.py до строчки:
botSession = BotSession(dp, Logic)
Первый абзац - это неправда.
С вторым спорить не могу.
Учитывая остальное сообщение: это как?
Это либа для реализации какой-то логики.
Как это применимо "от своего аккаунта"? Что именно вы хотите сделать?
Для работы с телеграмом есть 2 возможности: создать бота, который делает какие-то действия автоматически и создать клиента телеграма (т.е. аналог того клиента, которым Вы пользуетесь).
Во втором случае, если делать что-то узко-специализированное свое, то да, можно сделать софт, который будет реализовывать клиента с автоматическим подключением именно Вашего телефона, и выполнять какие-то действия от Вашего имени.
Если не секрет: зачем?
Ясно.
В этих примерах функции с вложенными функциями, что я использовал как своего рода private.
Кроме BotChat.waitProcess, в которой просто вложенность для отладочного логирования в виде:
Если выкинуть вложенность, то радон становится почти счастлив:
Вообще, разумеется, разодрать ее на куски для удовлетворения радона, конечно, можно.
Просто я обычно в коде исхожу из следующего, раздирать функции надо если: функция сильно не влезает на экран, имеет длинную сложную логику, длинный куски кода в ветках логики.
В данном случае, функция у меня помещается на экран, а если "сфолдить" ее 3 независимые части, то будет вообще 4 строчки (как это видно в IDEA).
На мой вкус не заслуживает упрощения.
Это я не ради спора, просто поясняю.
Вы вообще смысла моего кода не поняли.
Смысл как раз в том, что пользователь общается с функционалом бота полностью в линейном режиме, как если бы он использовал консоль для ввода input-ом, и выводом print-ом.
Никакие дополнительные классы не нужны.
await chat.menu()
- это уже "класс" меню. Законченный. В этой строчке он отрисует свой интерфейс в телеграме, дождется реакции пользователя и вернет то, что он там выбрал. Сюда же.Пользователя никто циклы писать не заставляет - он может реализовывать свою логику как ему угодно, хоть создавая классы, хоть делая циклы.
Весь main.py - это сплошной код "пользователя".
О телеграме, его протоколе, способах взаимодействия с ним и особенностях пользователь не обязан знать практически ничего.
Для реализации всего что ему надо, по сути, достаточно
BotChat.say
,BotChat.menu
,BotChat.ask
иBotChat.delete
. Для чуть более сложных "интерфейсов" еще и BotIMessage. По сути все.Откуда такой сарказм?
Впрочем, я наверное догадываюсь, Вы восприняли выражение "птичий" как оскорбление?
Дико извиняюсь, автопилот.
Просто это выражение мне стало привычным очень много лет назад. Оно не несет никакой негативной нагрузки и является своеобразным "техническим термином", обозначающим не компилируемый язык, как правило узко-нишевый. В 80х, когда начали активно развиваться скриптовые языки, в том числе мы писали их сами, часто звучало: "Как ты это сделал?" - "Написал свой птичий язык". Это просто было кратчайшее пояснение.
В общем, как-то так.
Еще раз извиняюсь, если оскорбил.
По остальному тексту многое непонятно.
Что такое "цикломатическая сложность" я прочитал, но не уверен что понял к какой именно части относится претензия. Вы не могли бы ткнуть пальцем?
Класc ISettings я использовал не как прокси (хотя он именно это), а в попытке хоть как-то разделить реализацию и описание т.к. я так и не понял какими методами это делается. Описаний в питоне нет (собственно я знаю только паскаль и С с ними), поэтому мне приходилось либо тащить весь код в 1 файл, либо это не собиралось из-за циклических зависимостей.
Претензию про main.py я тоже не понял.
Этот файл - единый сборник примеров использования не особо связанных друг с другом.
Можно было бы написать с десяток разных файлов с раздельными примерами, в этом проблема?
Мне показалось, что будет проще запустить одного бота и сразу посмотреть все (+-) что может либа, чем запускать кучу тестов.
Про количество кода это была шутка.
Жаль что опять оказалась, видимо, оскорблением.
Хотя все претя писать объект класса - это раздражало. Я еще не использовал языков, в которых были бы объекты, но в их методах нужно было бы всегда явно его писать.
Спасибо за отзыв.
С кейсом переменных понятно. В разных средах требования и стандарты разные. Я привык по другому и, на мой взгляд роли особой это в данном случае не играет.
А по остальным пунктам, если можно, подробнее.
Интересует: что за лишние абстракции и уровни вложенности. О чем речь?
Если можно, то с примером как оно "должно быть".
Интересно.
Подразумевается вто в м1 и м2 реализации интерфейсов?
Да такой подход к разделению возможен. Оптимален в бесконечно малом числе случаев, а остальные делятся на 2 варианта: либо количество оверхера будет превышать кодирование, либо это вообще не выполнимо т.к. в реализации нужно оперировать prtected-ными члемами базы.
Учитывая все это я и написал что невозможно. Не в теории. На практике.
Нет у компонентов событий. В QT есть, в VCL нет.
То, что в инспекторе объектов отображается на второй закладке - это просто проперти с типом "указатель на функцию", не более того. Уточню, т.к. есть у меня подозрения в непонимании: указатель на функцию именно члена класса. Любого класса. Хоть формы, хоть любого другого. Дизайнер создает такие функции "обработчики" автоматически в том что редактирует (оно как бы и логично) - в форме. Но никто не мешает их иметь вообще где угодно. Хоть заведи синглетон для с функциями обработчиками событий вообще всех компонентов приложения.
Если вопрос был в том, что "можно ли сказать дизайнеру, что функции создавать в другом месте", то скорее нет чем да, но нужно покопаться в интерфесах для плагинов дизайнера, может и можно. Но никто не мешает задавать обработчики вручную, в коде. У меня так %в 30 гуя обрабатывается.
ПС: Разумеется, нужно помнить что указатель не на функцию класса, а на функцию объекта класса. Ибо __closure. Надеюсь это очевидно.
Ну там поддержка стандарта не совсем, конечно. Но либа крутая. Стоит правда дороже всей RADStudio в 2 раза. Хотя возможно где-то это и оправдано.
Разумеется плюсом.
Не все раз в неделю пишут новую курсовую с нуля. В своем тексте я подразумеваю разработчиков, делающих долгосрочные проекты. Средство, которое они используют может развиваться, но не меняться. Разницу понимаете?
Неправильно я сформулировал. Не какая-то специфика, а набор факторов. Накидаю бессистемно, может понятнее станет.
Софт, который я пишу, в конечном итоге, в сетапе, состоит из 50 библиотек общего плана (dll/bpl), 54 экзешников и 25 плагинов (bpl) к разным частям. Где-то %20 от числа библиотек можно, наверное, выкинуть заменив штатными средствами того же шарпа, касающихся работы с электронной почтой и бащами данных. Остольного все равно очень много.
Софт эксплуатируется неподготовленными людьми и один из важных критериев - это "стандартность". Т.е. он должен выглядеть и управляться так же как стандартный виндовый софт. Т.е. всякие решения с плиточными интерфейсами и прочей альтернативщиной сразу идут лесом. Т.е. в С# у меня выбор только из WinForms. Возможно можно как-то извернуться и в WFP, но я не уверен.
Для иллюстрации разных аспектов написано около 60 собственных компонентов. Где-то половину из них можно, наверное, будет выкинуть найдя аналогичный по функциональности штатный аналог шарпа, или довольно быстро реализовать новый. Из оставшегося штук 5 являются довольно эксклюзивными штуками, существенными по коду. Полных аналогов я не видел. Т.е. придется довольно много реализовывать с нуля, чтобы получить аналогичные средства отображения.
VCL предоставляет механизм "легких" контролов, имея свои собственные деревья объектов, ктоторые не мапятся в виндовые контролы. В результате даже очень нагруженный интерфейс может на практическе иметь единственный HWND - контейнера. В WinForms, если я правильно читаю описание Contol, все интерфейсные элементы - это прямые враперы виндовых контролов. Ранее, работа с сотнями объектов у одного родителя приводила к жутким тормозам. Как дело обстоит сейчас я не знаю, но мест где у меня создается МНОГО интерфейсных объектов есть у меня.
Большая часть моего софта - это клиенты для моего же сервера, общающиеся с ним по бинарному протоколу по IP стремными сокетами. Чтобы дописывать что-ибо к существующей системе придется реализовывать этот интерфейс на шарпе. Бинома ньютона тут, конечно, нет, но это делает полностью бессмысленным "дописать что-то новое на шарпе" т.к. без средств связи оно будет бесполезно.
В итоге. Для того чтобы делать что-то интерфейсное на шарпе мне необходимо реализовать существенный объем собственных контролов, работать это будет виндовыми средствами (т.е. возможна ситуация, когда аналогичный существующему гуй будет работать хуже).
Что я получу, переведя код в шарп? Если не учитывать времени, которое потребуется на овладение этим инструментом на том же уровне, на каком я владею используемыми сейчас, и времени, которое потребуется на собственно кодирование и тестирование, я получу... всего 2 преимущества:
Надежду на то, что WinForms просуществует в поддержке дольше чем поддержка 32 битного кода виндой. Т.е. микрософт завтра может сказать "мы WinForms дропаем" и я поимею дикие проблемы. Писать же на древнем билдере я могу до тех пор, пока 32 битные приложения будут запускаться на винде.
Возможность использовать стабильные средства для работы с интернет. Не то чтобы это было бы мне нужно прямо сейчас, но сам факт, что можно использовать гарантированно работающее, штатное средство вместо подъема http для реализации REST или WebSockets на каком-нить Mangoose - это несомненный плюс.
Что я получу в "минусах", если переведу софт на шарп:
Значительно более сложный и трудоемкий процесс по созданию новых интерфейсных частей и поддержке существующих. Я экспериментировал с шарпом, конечно, не много, но пришел к выводу, что скорость разработки интерфейсов на нем не сравнима со скоростью с VCL. Это в винформс, с WPF ситуация еще хуже.
Мизерность готовой кодовой базы. Все-таки я изобретаю не все на свете велосипеды и часть кода у меня используется из различных сторонних библиотек. Даже если отфильтровать только то, что мой 5й билдер способен собирать, то количество готового кода для Delphi превышает весь доступный код для шарпа, наверное, на порядки. Это может закончится тем, что мне понадобится реализовывать каку-то сложныю хрень, типа рантайм дизайнера компонентов или текстового редактора. Чего делать бы не хотелось.
Некоторые сложности и странности доступных срадств. К примеру, OLE - это число виндовая технология от микрософт, но ее штатная поддержка в шарпе отсутствует. Если в том же вижуал васике я могу написать практически только название класса с гуидом и все кишки автоматически подтянуться сами и класс можно использовать сразу же как нативный, то в шарпе для этого придется постараться. В частности OLE я использую для работы с OPC. У меня есть и сервер и клиент. Реализация этого на шарпе быдет существенно сложнее того что я делаю сейчас. Второе что использую - это прямая работа с ком-портами для работы с оборудованием, к примеру GSM модемами. Возможно, в шарпе с этим не будет проблем, а может и возникнут. Во всяком случае ничего сложнее поделок на эту тему на шарпе я не находил.
В общем как-то так. Стало понятнее?
Пример чего?
Я знаком с концепцией интерфейсов :)
Вопрос был в другом: зачем они вообще нужны в описанной мной задаче и как они позволят разделить код физически, если предположить (на практике так оно и есть), что логически он не разделим.
Ничего не понял. Зачем какие-то свойства из интерфейсов, кто их будет использовать? Как можно создать финальный класс без реализации? В каких других файлах и длл-ах?
Поясню что я имел в виду. Я пишу наследника какого-нить TWinControl. Мне его нужно использовать напрямую, т.е. создавать объекты такого класса. Как мне помогут какие-то интерфейсы разделить код реализации этого класса на несколько файлов?
Спасибо. В какой версии он уже есть максимально функциональный? Сам вижуал мне применить негде, но для теста интересно было бы посмотреть.
Мне лично всего хватает. Львиную долю сорсов я набиваю вообще в редакторе FARа. Если же говорить о том, что мне понравилось при писании на том же Kotlin - это:
контекстная подстановка конструкций. Если я написал if и закрыл скобку, то при наборе "е" я получаю "else"; находясь в скопе класса по "pu" public и не наоборот. И т.д.
по мере ввода моментально получаю список того, что возможно использовать в этом месте, отсортированный по локальности. Т.е. сначала локальные переменные, потом классовые, предков, привязок и т.д.
в списке подстановки находится только то, что можно применить. Если в месте использования нужна функция, то будут только функции, которые возвращают то, что нужно в месте использования, если нужен енум определенного типа, то будут только его элементы и т.д.
Это конечно больше таракан явы, в которой нет хелпа, но часто очень сильно помогает javadoc, который вспывает когда ты ходишь по списку предложений. Как найти что-то новое, так то, что ты забыл как называется или что именно точно делает.
В результате работы такого средства, часто, набор кода заключается в наборе разделителей, пары первых букв и нажатие пробела (или enter у кого как настроено).
Не совсем и не всегда это так.
Во-первых, в львиной доли ПО время ужодит не на работу, а на ожидание. Девайсов, инпута и т.д. Во-вторых, плохо написанная программа без gc почти всегда будет работать менее оптимально чем плохо написанная программа с gc. Язык неважен. Все "не нативные" языки были придуманы для того, чтобы понизить порог ими владения. Т.е. снизить требования к квалификации разработчика. С ростом производительности компов это стрельнуло в обратную сторону: всю работу, котора раньше требовала большей квалификации теперь может выполнять человек с заметно меньшей. Как следствие, снизилась потребность в квалифицированных разработчиках, их перестали готовить, мест приложения их сил стало меньше - они почти вымерли. Я это к тому, что в большинстве случаев, сравнивая "среднюю по больнице" программу написанную на языке без gc и с ним, нам придется сравнивать именно плохо написанные программы. Это сильно нивелирует разницу между этими средствами.
В 5й или 6й. Не помню точно какая там была в 86-87 году.