Страницы

Поиск по вопросам

воскресенье, 26 января 2020 г.

Какие языки программирования хороши для создания кросс-платформенных desktop приложений? [закрыт]

#кроссплатформенность #desktop


        
             
                
                    
                        
                            Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы на него можно было дать ответ, основанный на фактах и цитатах, отредактировав его.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Смотрел Java. В x64 системе окошко с хелловорлдом отъедает около 20 МБ памяти, и
это число быстро растёт при создании новых объектов. Mono - достаточно посмотреть на
плеер Banshee чтобы понять что там ситуация не лучше (Музыкальный плеер отъедает ~
100 МБ памяти, при том что я всегда держу загруженный плеер мне это не нравится).
С++/Qt кажется неплохо, но на изучение придётся потратить большое кол-во усилий,
при том что не известно оправдаются ли(Вообще у Qt сейчас как я вижу не самая стабильная
ситуация, да и с плюсами в новых проектах люди стали поосторожнее)
Python/PyGTK оказался на удивление более скромным к памяти чем java, но сам язык
кажется мне каким-то невменяемым, возможно я просто не понимаю динамичскую типизацию.
Отсутствие инкапсуляции и перегрузки функций удивляет. Непонятно какое значение возвращает
какая-либо функция. Код показался не читаемым как раз из-за отсутствия скобок. Где-то
наткнулся на совет реже использовать вызовы функций, особенно в циклах т.к. это дорогая
операция в питоне. Перед глазами сразу представились огромные методы в 200+ строк.
PS Возможно я в чём-то не прав т.к. посмотрел на эти языки весьма поверхностно. Кросс-платформенность
на уровне компиляции вполне устроила бы(с неизменным кодом).    


Ответы

Ответ 1



Что лучше зависит от критериев выбора. В данном случае они такие: Время разработки и время внесения изменений (причем второе может быть важней первого для заказных приложений). Сложность приложения. Тип приложения("фотошоп", "WoW" или "клиент к твиттеру"), тиражное или заказное. С++ скорость разработки самая низкая для сложных приложений для тиражных решений требующих высокой оптимизации выполнения. Для слабого железа - GPS навигаторы, банкоматы, станки с ЧПУ, ... Java время разработки меньше чем у C++. Особенно время внесения изменений, доработок для сложных приложений когда требуется эффективность выполнения программы (перерасход памяти беспокоит только молодых программистов. Ни производителей смартфонов на Android, ни заказчиков бизнес софта это свойство JVM не волнуют. И мою жену тоже не волнует сколько отъедает музыкальный плеер), и при этом не требуется оптимизация выполнения с помощью низкоуровневых трюков или специфики ОС. Python время разработки самое низкое для простой и средней сложности приложений (для сложных - только при высокой квалификации программистов или формализованного процесса разработки) для некритичных к времени выполнения(примеры - клиент Dropbox'а, wikidpad). Для заказных, малотиражных приложений. (программы на серверах гугла и яндекса - "заказные", потому что уникальны) О времени разработки молодые программисты обычно не задумываются. А частенько в жизни - побеждает не лучшее, а - первое. Особенно при работе под заказ. О динамической типизации. Она требует самодисциплины разработки, чего обычно нет у молодых программистов, и они сами себе "злые буратины" быстро превращающие код в полный хаос. Она требует обязательного и сурового применения TDD или подобных методик. Интерпретатор/компилятор ЯП с динамической типизацией никогда не сможет выполнять/генерировать код той же эффективности выполнения что с статической типизацией. К вопросу - нравится/не нравится какой-то язык программирования. Во-первых, часто "не нравится" это - "не знал, не знаю, и знать не хочу" Во-вторых, когда после нескольких законченных и работающих программ остается "не нравится" то действительно стоит подумать о смене языка программирования. Разработка на любимом языке программирования - очень важный мотиватор для уменьшения времени разработки и улучшении ее качества. (О себе - профессионально(то есть за деньги) писал на plain С, Java, Python)

Ответ 2



Отвечу про Python. Отсутствие инкапсуляции и перегрузки функций удивляет. Инкапсуляция в питоне, хоть и весьма условная, но есть. Если метод начинается с __, то интерпретатор автоматически добавляет к имени префикс _%current_class% и, соответственно, в другом классе такой метод уже не будет виден. Private Methods: """ >>> obj = bar() >>> obj.__test() Traceback (most recent call last): ... AttributeError: 'bar' object has no attribute '__test' >>> obj.test2() Traceback (most recent call last): ... AttributeError: 'super' object has no attribute '_bar__test' >>> obj._foo__test() Hello >>> obj._foo__test > """ import doctest class foo(): def __test(self): print('Hello') class bar(foo): def test2(self): super().__test() doctest.testmod(optionflags=doctest.ELLIPSIS) Таким образом достигается инкапсуляция атрибутов класса. Конечно-же, все еще можно обратится к такому методу по полному имени. Однако, для примера, и в C# можно обратиться к приватным методам через рефлексию, но это вовсе не значит, что эти методы публичные. Для создания абстрактных классов используется специальный метакласс c декораторами. """ >>> obj = bar() >>> obj.test() Hello >>> obj = baz() Traceback (most recent call last): ... TypeError: Can't instantiate abstract class baz with abstract methods test """ import abc import doctest class foo(metaclass=abc.ABCMeta): @abc.abstractmethod def test(self): print('Hello') class bar(foo): def test(self): super().test() class baz(foo): pass doctest.testmod() Аналогичным образом реализуются и интерфейсы. Что-же касается перегрузок функций, то в динамическом языке, где методы могут принимать переменное число параметров и значения по умолчанию - это не возможно, да и совершенно не нужно. Пример: """ >>> foo(1, 2, 3, 4, 5, arg1=1, arg2=2, bar=False) (1, 2, (3, 4, 5), False, {'arg1': 1, 'arg2': 2}) """ import doctest def foo(first, second, *args, bar=True, **kwargs): print( (first, second, args, bar, kwargs) ) doctest.testmod() Непонятно какое значение возвращает какая-либо функция Да, этот недостаток присущ, наверное, всем динамическим языкам. Однако, в оправдание питона могу сказать, что эта проблема частично решается при помощи аннотаций, полноценного IDE и хорошего документирования функций. Более того, при помощи аннотаций, метаклассов и декораторов не сложно реализовать и статическую типизацию :) Т.е. примерно следующее: """ >>> foo().bar([1, 2, 3]) Traceback (most recent call last): ... TypeError: 'param' is 'list', but the expected type is 'int' >>> foo().bar(1) Traceback (most recent call last): ... TypeError: function return is 'str', but the expected type is 'bool' """ class foo(metaclass=StrongTyping): def bar(param: int) -> bool: return 'some text' Разумеется, что бы пример работал, нужно еще реализовать метакласс StrongTyping. Код показался не читаемым как раз из-за отсутствия скобок. Вероятно, это дело привычки. Отсутствие скобок обязывает программиста следить за отступами и использовать единый символ табуляции, что уже, на мой взгляд, не мало. Что же касается визуального разделения методов, то тут помогаю IDE, которые отделяют их горизонтальными линиями. Где-то наткнулся на совет реже использовать вызовы функций, особенно в циклах т.к. это дорогая операция в питоне. Перед глазами сразу представились огромные методы в 200+ строк. На мой взгляд, гибкость питона и такие возможности, как генераторы выражений наоборот позволяют писать очень компактные и лаконичные конструкции. Там где для строго-типизированных языков требуются куча циклов и условных конструкций, в питоне решается одной строчкой. UPD. Какие преимущества у динамической типизации? Имхо, именно в динамичности. Где еще можно написать нечто подобное: """ >>> op = ImportantClass() >>> op.foo(1) >>> ImportantClass.debug(True) >>> op.foo(2) Called (<__main__.ImportantClass object at 0x...>, 2) {} None """ import doctest import functools def logging(func): """ Декоратор функции, который логирует все вызовы """ @functools.wraps(func) def wrapper(*args, **kwargs): ret = func(*args, **kwargs) print('Called ', func, args, kwargs, ret) return ret # одна из особенностей питона - это то, что все является объектами # добавляем атрибут к функции wrapper.original = func return wrapper def debugging(cls): """ Декоратор класса, добавляет метод debug(enable) """ @classmethod def debug(cls, enable=True): attr = '__call__' if enable else 'original' call = lambda f: logging(f) if enable else f.original # в цикле подменяются все функции на logging(f), либо на оригинальные, # которые хранятся в декораторе for func in [call(f) for f in cls.__dict__.values() if hasattr(f, attr)]: setattr(cls, func.__name__, func) # добавляем новый метод для декорируемого класс # именно для класса, декоратор вызывается только один раз cls.debug = debug return cls @debugging class ImportantClass(): def foo(self, *args, **kwargs): pass # do something important def bar(self, *args, **kwargs): pass # also do something doctest.testmod(optionflags=doctest.ELLIPSIS) Декораторы logging и debugging можно вынести в отдельный модуль и применять для любых классов. При этом при выключенной отладке накладных расходов практически не будет, т.к. методы именно заменяеются другими методоми, а не оборачиваются. С другой стороны именно эта динамичность может служить источником ошибок, по этому приходится использовать ее осторожно и не забывать про тестирование. Кстати,на самом деле считается, что питон имеет одновременно и строгую, и динамическую типизацию. Т.н. код "1" + 1 выбросит исключение TypeError.

Ответ 3



Qt сама по себе не так сложна, если знакомы с С++. Зато возможности мощнейшие. Кросплатформенность тотальная! Ценю Qt еще и за то, что компоновка внешнего вида объектов происходит почти автоматом - не получается аляпистых кривых окон (как это часто любят делать программеры делфи). Для любой ОС внешний вид приложения будет идентичен - можно не опасаясь писать под виндой приложение которое будет потом скомпилировано и под Linux, и оно будет выглядеть одинаково и там и там. Мощнейший набор классов на все случаи жизни - мультимедиа, графика, текстовые редакторы, базы данных и т.д. Стабильность и поддержка очень крупной компанией. Регулярные релизы. Наличие свободной версии и версии для мобильных устройств. Сложность изучения языка и самого набора библиотек окупается многократно.

Ответ 4



Свой сверхвысокоуровневый DSL (Domain Specific Language, заточенный под ваши задачи) + автогенерация кода для (полусотни) целевых платформ х (PC *2 /win,lin/ *2 (x32,x64), Mac, Android *2 /4.x, backport-затычки 2.x/, iPhone, смарт-часы, облака х количество СУБД/хранилищ данных каждая со своими заморочками х Java, С#, JavaScript и еще десяток ходовых ЯП потому что понадобилась какая-то уникальная библиотека или работа приложения в специфическом окружении, или заказчик ограничил т.к. у него есть спецы для поддержки знающие что-то одно. По универсальности/эффективности и доступности вотпрямщщас: связка Python и С++, и нативные библиотеки GUI, интерфейса к БД итд, завернутые в классы с одним интерфейсом (для каждого вида -- GUI, БД,..).

Комментариев нет:

Отправить комментарий