Комментарии 713
Меня тоже реально бесит что работаешь за ноутбуком или ПК и для того, чтобы «полноценно» пользоваться каким-то приложением с него (да пускай тем же самым Инстаграммом) нужно на ПК поставить эмулятор Андроид.

Но ещё больше бесит, когда продукты, которые по своей сути должны являться mobile first не имеют нормального приложения на телефоне, а только планируют его сделать, особенно когда этот продукт для менеджера «в полях».
Если говорим про Instagram, можно ещё вспомнить то, что нет нормальной версии для Ipad.
Для инстаграма есть в целом нормальное PWA для просмотра сторис и фото.
Иногда почему-то не пускает без регистрации, а иногда пускает, логика не очень ясна (аккаунты публичные открывал).
Я тоже замечал и по своему опыту, и по опросам знакомых, что в вебе Инста отличается по фичам у разных пользователей. Предполагаю, что это А/Б тестирование с оцениванием конверсий и монетизации в зависимости от доступных фич.
Уважаемые Хабраммисты! :)
Меня одного бесит промотка статьи при открытии? Скачет все хрен знает как и куда. Зачем? На крайняк добавьте настройку, «проматывать при открытии». Уверен, 99% отключат шнягу эту. А то грузится статья с каментами, уже половину прочел, вдруг скачок вверх. Бред какой-то.
Всех бесит. Но как же без прибитого заголовка, который съедает и так маленькое вертикальное пространство? Не, оно так не работает, нужно обязательно накрутить фигни, подменять стандартную реализацию браузера, которая прекрасно работает, своей кривой и ломать весь экспириенс.
Призовите разрабов Хабра вместо меня пожалуйста, я по памяти ники не наберу.
Закреплённую менюшку сделали относительно недавно и вроде пофиксили все баги с ней, пока убирать не планируем. Я каждый день провожу на сайте много времени и уже привык к ней; точнее так: лично я потоками не пользуюсь (тк захожу в посты из другого места), но вот кнопки в правой части (и меню профиля) — постоянно. Если же проблема о чём-то другом (что-то дёргается при загрузке), то тут нужны конкретные примеры и дополнительная инфа, чтобы я мог донести её до разработчиков (лучше в личку).
С моей стороны вопросы только к её наличию. На небольших экранах места и так не хватает, а здесь ещё и бесполезная полоса. Очень не хватает кнопки «открепить панель», которая бы запоминала своё состояние для браузера (или для пользователя).
В то время, как почти везде перейти в начало страницы до этих же кнопок — одно/два нажатия.
и вроде пофиксили все баги с ней

Как тут уже написали, самый главный баг в её наличии. Плюс теперь страница весело прокручивается туда-сюда, пока не отработают скрипты, замещающие стандартные механизмы браузера по прокрутке к анкору.
Пожалуйста, не нужно ломать стандартные функции браузера и эмулировать их на JS, это никогда нормально не работает. Сделайте галочку вернуть как было «Отключить прикрепление шапки», которая заодно отключит все эти скрипты и оставит адресную строку в покое.

А чего стоит вдоль и поперек перепиленная джаваскриптом textarea для набора комментария… Даже на моем i7 буквы при наборе комментария появляются с заметным отставанием при небольшой скорости набора. А если набирать быстро, то часть букв пропадет, а другая часть встанет не на свое место.Вот этот текст я был вынужден редактировать несколько раз из-за пропадания и перемешивания букв.
А на айпаде набрать ответ вообще невозможно из-за жутких тормозов в десятки секунд.
Но это же все неважно, правда, Boomburum ?

У меня(i5) так было на одной из пред идущих версий Хрома, потом всё же исправили. Но было везде где можно вводить текст, особенно заметно при стирании символов.
Чтобы тупил ввод конкретно на Хабре, такого не помню.
А вы Хромом пользуетесь? Просто у меня на ноутбуке с ФФ, Celeron'ом 1007U и 4Гб памяти такого не было ни разу.
Про инстаграм стоит вспомнить, что он не позволяет пользоваться веб версия, а навязывает поставить приложение.
Единственно я не залогинен, мб это пропадает после логина?
Можно, но коряво.
1. открывать ссылки правой кнопкой мыши «открыть в новой вкладке»
2. надоедливое окно с регистрацией, которое закрывает весь экран можно парой кликов убрать в firefox в режиме инспектора. Просто ткнуть в него и удалить из дерева. Дальше можно про него забыть.
Веб версией после реги вполне позволяет…
А как же заглушка на истории? Или она тоже на стороне юзера делается?
Про заглушку не понял. Там он пишет требование залогиниться на весь экран, но оно убирается п.2 Инст, как и все сайты, которые используют подобную тактику, тупо закрывает всё не блокируя как-то дополнительно работу. Если удалить закрывающий элемент — дальше всё работает. В теории это можно даже сделать через баннерорезку, но я не пробовал. Слишком редко это надо.
У меня скролл не работает даже после блокирования требования логина. Хотя убирал adblock`ом, может в этом дело.
Тут я не понял, в чём прикол. Иногда работает, иногда — нет. Возможно я разный элемент удаляю (не особо целюсь). Скролл всегда работает кнопками вверх/вниз/pdup/pgdn
Тут скорее всего только юзерстили, я не смотрел, но обычно такие модалки вешают класс на body с запретом скролла.
Запрета там точно нет. Он работает.
Как я понимаю — они просто закрыты блоком весь экран и на этом успокоились. Просто возможно там остаётся иногда поверх него ещё какой-то блок, который клики перекрывает. Но почему это работает через раз и почему работают кнопки непонятно. Времени сейчас посмотреть нет :(

Что, и пост можно сделать? Видео залить, например? Это же дико неудобно, коллега делаешь видео в Premiere, закидываешь на телефон и только с него постишь. И ещё и отложенную запись просто так сделать нельзя…


В общем, автор был прав — это приложение ориентировано на тех, кто делится селфи.


Просто он недооценил коммерческое количество таких людей, ине учёл, что профессиональная аудитория как раз сумеет подстроиться ко всему.


Точно так же люди массово пользуются WhatsApp вместо Telegram, хотя там нельзя даже сообщение отредактировать, и ещё десяток полезных функций отсутствует. Зато он понятнее.

Меня тоже реально бесит что работаешь за ноутбуком или ПК и для того, чтобы «полноценно» пользоваться каким-то приложением с него (да пускай тем же самым Инстаграммом) нужно на ПК поставить эмулятор Андроид.
Вас бы меньше это бесило, если бы на компьютере был бы предустановлен эмулятор андроид, позволяющий прозрачно запускать любые приложения из гугл-плей скажем? То есть качнул и запустил — без доп. плясок с бубном, но технически это был бы «инстаграм в эмуляторе», а не нативное приложение.
Вопрос не риторический, ответ правда интересен, особенно если подробный.
Нет.
Делаете продукт — делайте для него нормальную веб-версию, по тому что браузер можно открыть на любой кофеварке.
Я не буду от каждого сервиса приложение ставить чтобы посмотреть что у вас там.

Интересно значит когда вэб браузерами ломали user experience в нормальных приложениях вы были за это а как браузеры прошли на свалку так против? ;)
Когда-то были удобные приложение "толстые клиенты" в которых были нормальные сочетания клавиш, последовательность выбора объектов, подогнанные расположение элементов (чтобы нужная информация была рядом), удобное редактирование, отсутствие потерь информации из-за нажатия f5 (или просто протухания сессии ;) ). Но нет модой стал web anywhere :) а теперь просто следующий шаг.
И ладно когда это Инстаграм, который изначально для плиток с камерой и их владельцев, так нет сейчас у нас справочные ресурсы под телефон с кнопками в пол экрана и свёрнуты и по умолчанию комментариями :)

Когда-то были удобные приложение «толстые клиенты» в которых были нормальные сочетания клавиш

Я, кстати, потому из аппаратных гипервизоров держусь за xen — у него есть отдельный клиент. А esxi и прочие proxmox уже только в браузере.
У ESXi всё же есть десктопный клиент – VMware vSphere Client. Да и Workstation с Fusion тоже ограниченно могут управлять виртуальными машинами.
В последних версиях ESXi уже нет десктопного клиента. Только через вэб.
Там где-то в районе версии 6.5 всё отвалилось окончательно.
Какое-то время можно было использовать клиент от шестёрки, но с одним из апдейтов эта возможность пропала и остался только веб.
Ну в общем да, были за это, потому что, еще раз, браузер есть везде, а приложения — старые ли толстые, новые ли не такие толстые — нет.
Интересно значит когда вэб браузерами ломали user experience в нормальных приложениях вы были за это а как браузеры прошли на свалку так против? ;)
Смотря о каких приложениях идет речь.
Тяжелые проф. приложения типа графических редакторов, IDE, офисных пакетов должны быть полноценными приложениями с полноценным интерфейсом — так было и так есть.
А вот всякая информационная мелочевка с парой кнопок интерфейса прекрасно работает в браузере и не требует отдельного софта. Помнится в начале 2000-х у меня была куча всяких информационных приложений: карта города, справочник лекарств, и т.п. — сейчас все подобное доступно в Веб.
Пожалуйста, Figma — де-факто сейчас основной графический редактор в веб-разработке.
И ничего в этом хорошего. Загружается достаточно долго даже на быстром интернете, всё хранит у себя на сервере.
У локальной базы данных и стороннего он-лайн сервиса несколько разные сценарии использования. Сейчас оно в Вэб доступно, а завтра вы в самолёте с ноутбуком летите.
Я не буду от каждого сервиса приложение ставить чтобы посмотреть что у вас там.
Спасибо. Неожиданный ответ.
Нам как старым десктопщикам привычнее как раз когда на десктопе можно поставить отдельную прогу для отдельной задачи. К онлайн мсоффису не привыкли до сих пор — пользуемся десктопным, долгое время на форумах предпочитали сидеть через оффлайн клиент — сейчас они просто вымерли все, до сих пор оффлайновым десктопным почтовым клиентом пользуемся и так далее.
Офисом человек пользуется регулярно и достаточно разнообразно, а есть задачи которые надо сделать разово и забыть о них, вот тут веб однозначно в плюсе.
а есть задачи которые надо сделать разово и забыть о них, вот тут веб однозначно в плюсе.


Время от времени попадаются ноуты (в основном — девичьи), на которых открыто неподдающееся никакому учету количество окон (не вкладок :) примерно трех разных браузеров (или всех, что есть на компе) — это как раз и есть «сделать разово» — но не забыть :)
Самое интересное — владельцы ноутов как-то ориентируются в этом лабиринте и ухитряются находить нужное.
Но вот установка обновлений с последующей перезагрузкой — для них настоящая боль :)

(ноуты никогда не выключаются, владельцы этой кнопкой не пользуются: открыл/закрыл и все дела :)

В нормальных десктопных программах используется концепция «открыл — поработал — сохранил и закрыл». В браузерах с этим есть определенные проблемы, что и приводит к описанным выше результатам.

Закладки людьми не используются, так как процесс создания закладки обычно сложнее процесса сохранения обычного документа.
Нажать на звездочку в адресной строке это сложнее нажатия иконки дискеты?
Нажать на звездочку в адресной строке это сложнее нажатия иконки дискеты?


Да.

image

Пункт Папка: по дефолту — «Другие закладки»
Попытка сменить папку выводит на систему навигации по папкам, заметно отличающуюся от простой навигации по папкам файловой системы ОС.
image
В результате у обычного пользователя возникают проблемы, приводящие к тому, что либо пользователь не может найти сделанную им закладку, либо все закладки сваливаются в одну кучу в папку «Другие закладки».

А попытка создать иерархию (с перемещением закладок туда-сюда) становится делом нетривиальным и весьма утомительным.
Плюс далеко не все пользователи слышали о функции облачной синхронизации данных в браузере — и тем более — умеют ей пользоваться.

И плюс плюс — пользователи пользуются несколькими разными браузерами на одном компьютере одновременно.

В результате имеем умножение сущностей сверх необходимого, и любая программа типа OneNote становится намного удобнее системы закладок в браузерах.
Я один перетаскиваю вкладку на панель закладок, которая вся в заранее созданных папках? Одно простое действие, а по Ctrl+D действительно какой-то геморрой, да и в FF это окно появилось сравнительно недавно.
Большинству обычных пользователей дерево папок неудобно. Более того, для многих из них само разбиение на папки уже чрезмерно. Более того, для некоторых само разбиение на две сущности — вкладки/закладки уже излишне.
Вот у меня в основном дерево плоское. Конечно, все папки на панели закладок для браузера находятся в папке «Панель закладок», то есть это второй уровень, но для меня он первый и легко доступный.
А про большинство… Не знаю что с ним делать. Курсы компьютерной грамотности похоже мало помогают, тут нужен особый склад ума.
Я один перетаскиваю вкладку на панель закладок, которая вся в заранее созданных папках?


Все с этого начинают :) Я — не исключение.
Но потом возникают ситуации, когда компьютеры меняются по несколько раз в день.
Компьютеры с разными браузерами.
Чужие компьютеры, на которых что-то устанавливать и настраивать в собственных интересах нельзя.
В такой ситуации синхронизация вкладок через облако браузера теряет всякий смысл.
Намного проще зайти в уже упомянутый OneNote через тот же браузер и получить доступ ко всей своей коллекции ссылок (которая может быть весьма обширной- 16 блокнотов по темам, по десятку-полтора разделов в каждом блокноте, по сотне страниц в каждом разделе, десятки ссылок на каждой странице :)

А обычные пользователи пасуют уже при виде альтернативы в лице трех вариантов (см картинку выше):
«Другие закладки»
«Панель закладок»
«Меню закладок»
И еще один пункт «Другие закладки» (уже внутри пункта «Другие закладки» :)

Все, такого количества близких по смыслу вариантов — уже вполне достаточно для хаоса в голове обычного пользователя
Но потом возникают ситуации, когда компьютеры меняются по несколько раз в день.
Компьютеры с разными браузерами.
Чужие компьютеры, на которых что-то устанавливать и настраивать в собственных интересах нельзя.

Зачем всё это? Сколько ни читаю про подобные случаи, ни разу не сталкивался.
Сколько ни читаю про подобные случаи, ни разу не сталкивался.


Преподаватель проводит занятия в компьютерных классах.
Одна пара у него в корпусе А, вторая, на другом факультете — в корпусе Б. Затем он едет проводить занятия в колледже — корпус В. При этом, в зависимости от расписания, компьютерные классы даже в пределах одного корпуса меняются.

В такой ситуации даже флешку в эти компы вставлять нельзя, это как в борделе… нет, это хуже чем в борделе — там хоть проверяют состояние здоровья время от времени…

Про командировки-конференции и прочее и речи нет.
Я бы не стал на таких ПК входить в какой либо аккаунт.


Я тоже предпочитаю использовать Continuum (не помню, в какой именно теме я вчера давал описание его использования, может быть и в этой)
Но не всегда есть время на подключение/отключение.

Поэтому используется специальная учетная запись, заточенная сугубо под конкретные задачи.
А в чём проблема с браузерами? В хроме, лисе, яндексе сохраняются вкладки после закрытия-открытия. В крайнем случае: История/закладки — восстановить сессию.

Если вы, например, закрыли, открыли (пока есть активный пункт восстановить сессию), снова закрыли (случайно) — оно не появится, сессия потеряна. В Firefox по крайней мере именно так.


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

Да, часто такое видел, что на домашних компах браузер открыт круглосуточно, чтобы открытые вкладки не пропадали. Странно, что разработчики браузеров это проблему игнорируют.
Сохранение вкладок при закрытии часто отключено по умолчанию
Это раз, а два — многие просто боятся, что что-то пойдет не так, когда надо нажимать кнопку «восстановить предыдущую сессию» — сам несколько раз не туда тыкал и потом огребал за это )
У меня вот ни разу проблем с этой кнопкой не былою Не понимаю вообще, зачем эту страницу выводить. Просто нужно восстанавливать предыдущие вкладки по дефолту.
У меня вот ни разу проблем с этой кнопкой не было
Ошибка выжившего )

Не понимаю вообще, зачем эту страницу выводить. Просто нужно восстанавливать предыдущие вкладки по дефолту
Вот лично я не люблю восстанавливать предыдущую сессию, потому что стараюсь держать открытыми только нужные именно сейчас вкладки.
Ну так есть настройка «Восстанавливать предыдущую сессию», почему бы не послушать её. Если я хочу восстанавливать предыдущую сессию при ручном перезапуске, то я в 100% случаев выберу его после креша. Вот для пользователей, которым при ручном перезапуске не нужно восстанавливать вкладки, и можно показать такое окно после креша, и то не факт, что будет удобно начинать с чистого листа после каждого падения браузера.
в chrome Ctrl+Shift+T восстанавливает последнюю группу вкладок — работает хорошо… если всё закрылось — надо нажать несколько раз, очень удобно
Для FF есть прекрасная штука — Tab Session Manager. По дефолту сохраняет сессию при закрытии окна или всего браузера, включая выгруженные вкладки, да плюс ко всему работает c Tree style tab и сохраняет иерархию деревьев вкладок
Онлайновый офис довольно ущербный в плане функций и совместимости. В нём у кучи документов едет форматирование.
Почта — тут уже кому как. В своё время, когда почта шла большим потоком, был большим поклонником the bat с его системой фильтров. Сейчас же количество почты резко уменьшилось, потому вполне хватает и веб-интерфейса с нормальным поиском.
Использовать OnlyOffice вместо GDocs и Office365 не пробовали? (у них свой рендеринг и вроде как очень старались форматирование MS Office повторить).
А почта — у Gmail/GSuite не такая уж плохая система фильтров… настраиваемая через веб-клиент а не мобильные приложения. У всяких Zimbra оно тоже есть.
Нет. У меня облако вандрайв, потому идти в одно облако для того, чтобы редактировать файлы в другом, смысла не вижу.
Тем более, что у меня есть оффлайновые приложения — так что облачным офисом вообще смысла пользоваться нет в повседневной жизни. Очень изредка с чужого компьютера запускается.
Интересно, как много людей преодолеют планку лени и заполнят форму из 5 полей, чтобы попробовать 180-дневный триал?
Я только это увидел — сразу закрыл и вернулся к google docs, хотя он меня и не полностью устраивает.
Тут вопрос больше в том, сколько людей согласятся уйти от бесплатного гугла или MS на платное решение.
Заполнить форму — не проблема, регистрация на гугле тоже не одно поле заполнить.
Регистрация на гугле у подавляющего числа современных пользователей Инета и смартфонов (как объединение множеств) — и так есть.
А заполнять длиннющую (по нынешним временам) форму, чтобы просто попробовать какой-то сервис — данафигэтоникуданеупёрлось!
Многие пользователи смартфонов не помнят свой пароль от гуглоаккаунта, а почта у них на mail.ru
Если вообще есть.
Я ± как-раз из таких.
Но пароли помнятся в каком-то менеджере паролей в минте и дальше уже хром с этим сам разбирается.
Поэтому войти под гугл (вк или где там я ещё зареген) аккаунт ещё проще: даже пароль не надо помнить.

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

Тьма онлайн-сервисов, где регистрация или не нужна или можно войти под аккаунтом других распространённых веб-сервисов.
Я, вон, даже на али покупаю под… не помню… ВК-аккаунтом что-ли.

А то каждый интернет магазин на SPA, торгующий спиннерами будет требовать уникальную, именно для себя регистрацию — смешно даже…
можно войти под аккаунтом других распространённых веб-сервисов.

Почему-то у меня во всех случаях, когда я пытаюсь войти под аккаунтом фэйсбука или гугла, оттуда дёргают только почту, а остальные данные требуют ввести дополнительно.
Так выбора особого нет.
И, на самом деле, я предпочитаю отдельный логин для каждого сайта держать. Потому что соцсеть обойдётся без дополнительной информации обо мне.
Потому что соцсеть обойдётся без дополнительной информации обо мне.

Дополнительная информация еще не так страшно, а вот остаться без аккаунтов везде, потому что забанили/удалили/закрылся основной сервис, через который авторизация была, такая себе перспектива.

Просто. Заходите на двач и общаетесь, качаете картинки, видеоролики без смс и регистрации.

Двач, конечно, сервис (форум такой?), но это не сервис в том контексте, в котором я использовал данное слово.
Я человек неискушённый в эдишинах всяких.
На стартовой странице уяснил, что штука платная, но есть триал на 180 дней.
ОК — ткнул «Попробовать в облаке» — увидел длинную форму — закрыл.

К вопросу о дезигнерах интерфейсов.
ну если так подходить к вопросу, то да. А если опустится на один экран вниз есть десктопные версии бесплатные.
Опять же — видно, что дизайнеры хотели донести до пользователя в первую очередь.

Это не дезингеры интерфейсов виноваты… это маркетологи хотят собрать с вас максимум инфы.


Босс придумал некую "анкету контагента" из 240 полей, включая чекбоксы. Потенциальный контрагент должен заполнить вот это всё только ради того, чтобы "попобовать" поработать с Газпромом в области ремонта спецтехники. Воевал-воевал с ним, да все бесполезно: бигдату босс хочет...


Так что вполне может статься, что вы еще не встечали по-настоящему длинных форм :)

А её хоть честно заполняли? Или это была бигдата по значениям ГПСЧ.

Заполняют на 4%...12% судя по статистике.
В результате и людям неудобства доставили, и данные не собрали.

А, так там можно не до конца заполнять. Тогда да, забросят.

Да, удалось часть "очень-важных-и-нужных" полей сделать необязательными.

Попытка отредактировать вордовый документ с track changes и комментариями вне MS Office разрушит этот документ с вероятностью 99%.
А это не такой оедкий кейс, и для аналитика, и для юриста.
Gmail и прочие: нормальных таблиц не вставишь, копипаст из Ворда не сделаешь.

Попробовал онлиофис на тему совместимости.
Вот последний файл, который мне присылали для заполнения:

OnlyOffice: banshee.ms/public/screenshots/2020-07-30_072645.jpg — плющит, накладывая таблицы друг на друга.
ГуглОфис: banshee.ms/public/screenshots/2020-07-30_072925.jpg — наоборот, разносит на две страницы.
Office365 онлайновый: banshee.ms/public/screenshots/2020-07-30_073110.jpg — тоже разносит, как в гугле.
А вот так оно должно выглядеть: banshee.ms/public/screenshots/2020-07-30_073206.jpg (оффлайновый офис).

Лучшие результаты показывает оффлайновая либра — там только верхняя табличка чуть вправо уезжает, но это довольно легко исправляется.
Вот потому онлайновые офисные пакеты полноценного документооборота слабо подходят, если уж даже MS не может нормальную совместимость онлайн и оффлайн версий обеспечить.
Этот же документ в либре 6.5 выглядит так же как в Офис365, 1:1. Так что это в первую очередь проблема конкретного документа сверстанного непонятно кем и непонятно как. LibreOffice Online открывает в вебе документ 1:1 оффлайновой версии.
это в первую очередь проблема конкретного документа сверстанного непонятно кем и непонятно как.

Нет, это не проблема документа. Это моя проблема. Ибо автор документа скажет «на моей стороне всё нормально», а прогибать большой МТС под маленького меня — без шансов.

Вот если вы сами большой, то маленьких окружающих можете прогибать хоть под либру, хоть под гуглодоки, хоть под лексикон досовский.
Нет, это не проблема документа. Это моя проблема. Ибо автор документа скажет «на моей стороне всё нормально», а прогибать большой МТС под маленького меня — без шансов.

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

Я бы сказал что это проблема индустрии в целом и лени пользователей в частности. Учиться пользоваться офисом никто не хочет, а отправлять сотрудников на обучение дорого. Зачем, если и так все работает?
с юрлицами все зависит от наличия в штате хороших юристов, ну или одного хорошего юриста

Юристы первые, кто просит MS Office им купить, чтобы не возиться с форматированием. Плюс ещё они любят всякие истории редактирования и выноски ставить, а это между либрой и MSO ещё хуже переносится, чем таблички.

Думаю человек имел в виду другое. есть необходимые отдельные приложения. калькулятор, фонарик, браузер, офис, плеер и т.д, а дальше пошел треш. Хочешь инсту — приложение, мордокнигу — приложение, контакт — приложение, хабр — приложение, 4pda — приложение, алиэкспресс — приложение. Т.е вместо того, чтобы открыть это все в браузере и спокойно скролить и делиться ссылками мне предлагают ставить стопитсот приложений, которые каждая жрет как не в себя, так и хочет от меня всех подряд прав. Вот это все неимоверно калит.

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

Да-да, через мобильное приложение сбера подписать и отправить платёжку с суммой выше какого-то порога нельзя — сбер, типа, запрещает такое делать с мобильных устройств, типа security блюдут.
OK, закрываем сберприложение, следом открываем браузер на этом же телефоне, заходим в веб-интерфейс сбера и теперь платёжки можно подписывать на любые суммы! Але! Вы чего там в сбере накурились? :D
И это всё еще при том, что в сбер-приложение встроен анальный зонд имени кашпировского вирусы, типа, отлавливать, а браузеру доверяем слепо!

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

Можно просто с телефона при помощи СМС перевести деньги на этот же счёт, а с него куда угодно. И это не отключается никак.
Да вроде отключается


Или вместе с ним отключится и смс информирование о состоянии счёта?
Не знаю что вместе с ним отключится, но от смс с суммой на номер 900 это не спасает, насколько я знаю.
Услуга называется «мобильный банк». Она как раз посредством СМС работает. При отключении не работают команды на 900. Не путать с интернет-банком.
и ничего не уходит.

Пошлите «100» на номер «900», посмотрите, как не уходит.

Но, кстати, да, пока пополняет и в ответ приходит «С 31.08 оплатить свой телефон через СМС-запрос можно будет, если подключена опция «СМС-платежи»».
Если отправить платёж на другой номер, то никакого ответа нет.
Если отправить USSD пополнение другого номера, то получаем ответ «Операция не выполнена. Для проведения ПЛАТЕЖА подключите опцию «СМС-платежи»».
Так что работает частично.Но через три дня заработает как надо.
Но через три дня заработает как надо.

Окей, хоть это починили. А то лет 5 была дыра в безопасности.
Впрочем, я не удивлюсь, если СМС платежи включены по умолчанию и будут включатся например при перевыпуске карты.
Выключили для всех. Новосозданные карты и перевыпущенные идут уже с отключенными смс платежами.
На старой(трёхлетней), так же отключены без уведомления, хотя я не запрашивал, но раз пользовался.
Ну, знаете, как автор статьи высказался, нынче неприлично много чего завязано на телефоне, поэтому, имея вашу симку, можно вообще много чего сделать (восстановить пароль от гугло-аккаунта, запостить гадости в твиттер, перевести деньги с (почти) всех счетов). Но вопрос в том, насколько это вообще реальный кейс, когда у другого человека внезапно окажется ваша симка? Да, помню, были кейсы, когда мошенники в отделении без паспорта «восстанавливали» симку и делали что хотят, но все-таки это исключение
но все-таки это исключение

Скорее правило. Вообще, нельзя на симку ничего завязывать. Увы, гугаккаунт при заходе с другого IP начинает вымогать номер, и, если никакой номер не привязан, то принимает любой. Всё для вашей безопасности ((( И даже не знаю, куда об этом написать.
Увы, гугаккаунт при заходе с другого IP начинает вымогать номер, и, если никакой номер не привязан, то принимает любой


У меня для этого есть специальная сим-карта, только для Гугла.
(и еще одна — для Микрософта :)
Хорошее, конечно, решение, но уж больно геморрное. Лучше бы гугл принимал мой 16-ти значный пароль и не выкаблучивался с псевдозащитой.
Хорошее, конечно, решение, но уж больно геморрное


Ничуть: двухсимочный смарт и мобильная точка доступа.
Точка доступа маленькая и легкая, плюс для меня необходимая.
(Плюс отдельная сменная карта для всех явных будущих спамеров :)
Ну, с двумя симками скрытие от гугла так себе.


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

Хотя у меня есть большие сомнения, что можно скрыть гугл от гугла в принципе — есть куча других факторов, кроме номера телефона.
Именно, в какой-то момент мир повернул не туда и вместо того, чтобы нормально жить с паролями решил, что нам нужны смены паролей, 2FA и прочая лабуда :(
«нормально жить с паролями»

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


А это бесполезно.
Все равно человек пойдет по пути наименьшего сопротивления и, в конечном счете, выберет наименее трудозатратный вариант- либо простой пароль, либо бумажка на мониторе/файл с паролями на компе, либо один пароль для всех ресурсов.

Проверено многократно.
И конечно же учить пользователей паролям никто не стал
А еще есть простой вариант, почему-то многим неочевидный.

Пользователь оценил риск инцидента и ожидаемый ущерб, признал его ничтожным, и использовал пароль «qwe123».

Но увы — аффтыри сервиса они же умнее — только strong password для форума с котиками! 16 знаков, прописные и строчные, цифры и спецсимволы, проверка по словарям, смена раз в месяц — Пентагон плачет в уголку :-)

Вот от паролей и ушли.
Вот от паролей и ушли.

Но ведь этим тоже занимаются админы этих форумов. Да и ничто не мешает им требовать сложный пароль вместе со вторым фактором. Котики в безопасности!
Сложные пароли теперь не в тренде. В эпоху победившего OAuth2 — зачем? Пусть гугол с фейсбуком парятся, мы сразу считаем что все ОК.

Адимин параноик? Мы вам послали по вашему номеру телефона одноразовый код — введите в формочку пожалуйста!

Это удобно.

И заодно спасает админов от ботов :-)
Отвратительно… Особенно когда очередной алгоритм проверки пароля на очередном форуме с котиками требует условно «от 12 символов», когда твой «пароля для форумов»\«алгоритм генерации паролей для форумов» всего 10. Приходится добавлять «123» в конец, как будто от этого сильно безопаснее становится.

В Альфа- банке у меня при восстановлении утерянной симки перестало работать приложение.Они отслеживают номер симки, что на мой взгляд очень даже правильно… Злоумышленник при замене симки не сможет войти в мобильное приложение, потому что на новой симке номер будет другой… Позвонил оператору, объяснил ситуацию, ответил на кучу вопросов, и все заработало...

насколько это вообще реальный кейс, когда у другого человека внезапно окажется ваша симка?

А какие вообще проблемы? У многих сейчас на симке стоит пароль? А если нет, то её достаточно вытащить из аппарата и делать что угодно, даже если сам смартфон запаролен по самое не хочу.
А если нет, то её достаточно вытащить из аппарата


А кто позволит вытаскивать симку из своего телефона?
Это очень заметная процедура, на глазах не сделаешь.

При этом я давно уже не замечал, что бы народ своими телефонами разбрасывался, сорри, люди даже в сортир идут с телефоном.

Потому как на телефоны сейчас много завязано — в том числе и сугубо личного, что понятно уже даже самым беспечным.

Сейчас смарт уже как связка ключей, и отношение тоже соответствующее.
А кто позволит вытаскивать симку из своего телефона?

А кто запретит вот тому гопнику с кирпичом, или вору, который уже украл устройство? А утеря? А ревнующий родственник?
Не, не работает оно так. Симка уязвимый фактор и не должен использоваться для авторизации или аутентификации.
А кто запретит вот тому гопнику с кирпичом, или вору, который уже украл устройство? А утеря?


При утере или краже, а так же и при грабеже- пострадавший всегда может блокировать свою сим-карту, либо у провайдера мобильной связи, либо на ресурсе, где используется этот номер.

Исключением является случай «сняли с бесчувственного тела, наконец — с трупа!» (с).
Но трупу уже в принципе все равно.
а так же и при грабеже

Вы забыли кражу. Банально подрезали в метро, узнать можно и дома спустя час.
Вы забыли кражу.


См. выше: «При утере или краже»

узнать можно и дома спустя час


после чего можно заблокировать карту.
Не говоря уже о том, что сам смарт блокируется.

+ Извлеченная карта сама по себе не даст достаточного количества информации, если телефон был украден у случайного человека.
Пароль на симке? Примерно ни у кого?

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


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

Его вывезли за город и запытали до смерти — узнавали пин-код.
Если это нормальные приложения — я только за. На кой черт мне ваш веб сдался если я могу иметь нормальные приложения под рукой?
Думаю человек имел в виду другое. есть необходимые отдельные приложения. калькулятор, фонарик, браузер, офис, плеер и т.д, а дальше пошел треш. Хочешь инсту — приложение, мордокнигу — приложение, контакт — приложение, хабр — приложение, 4pda — приложение, алиэкспресс — приложение.
Это не другое по сути, это просто другая оценка того же самого.
Лично для нас это не треш, а наоборот неплохо, когда отдельные функции реализуются отдельным десктоп-приложением.
Та же почта. До сих пор предпочитаем десктоп-клиент, хотя все современные люди используют почту в браузере. Брокерское приложение — можно в браузере, но поставили десктопное. Для некоторых форумов до сих пор приложения используем десктопные, а не браузер. В вордпресс из ворда постим, а не с браузера.
Мы не говорим что это правильный подход, просто ну вот так вот — мы не перестроились на использование браузера, кто-то не перестроился на использование мобилы — каждому своё, ничего плохого в этом нет.
Плюс если так посмотреть, фактически браузер здесь выступает как условная виртуальная машина для запуска приложений. Поэтому…
у меня принципиально не стоит приложение фейсбук на телефоне. Потому как я туда хожу в основном в режиме рид онли. И мне совсем не интересно получать 20 пуш-нотификейшенов в день, типа: «смотри какую мы нашли красивую фотку котиков очень полезную информацию, как раз для тебя».
МНОГО приложений для телефона имеют главную цель: показать как можно больше рекламы. В браузерах с этим давно разобрались с помощью ад-блокеров, поэтому злые маркетологи придумали отдельные приложения :)
На мобильных устройствах у приложений один плюс всё же есть: между ними гораздо удобнее переключаться, чем между вкладками в броузере, если речь идёт об Android. И для запуска необходимо всего одно касание, а не сначала запустить броузер, потом вбить адрес.
Другой вопрос, что если бы вместо Android была бы мобильная OS-броузер, у которой нет различия между приложениями и вкладками, то может быть, это было бы и лучше.
Так была возможность выводить в меню приложений ссылки на сайты. Но кому это нужно, когда можно сделать приложение и собирать через него на порядок больше информации?
Да, предлагают все поставить свои моб. приложения, а потом, бац и места в памяти нет. Ещё и CPU грузят, но это хоть отключаемо.
Ну, чисто гипотетически, да, меня это бесило бы меньше, хотя не исключаю того, что все-таки бесило бы. На деле всё зависит от того, как именно это реализовано. Условные Вайбер и Ватсапп для компьютера вроде прикольно, но вот у того же Ватсапа есть веб-версия, которую я могу запустить в том числе в анонимной вкладке на чужом компьютере, а у вайбера нет. Значит Ватсапп для меня удобнее в целом, хотя не телефоне мне нравится вайбер (субъективно). И в браузер Опера они (Ватсап и Инстаграм) встроены, значит мне логичней на него с Вайбера переходить.

Как пример (полагаю, что удачный) могу привести так называемые браузерные игры «Троецарствие» и «Танки онлайн». В первую давно играл, во второю иногда играю. В них можно играть в браузере, но не всегда удобно и иногда тормозит, но можно, зависит от мощности ПК и ширины канала. Официальный клиент игры это по сути браузер, но заточенный под один сайт (одно приложение). В целом вроде бы неплохо. У Битрикс24 так же новый клиент выглядит. Но у тех же Танков онлайн новая версия клиента это по сути эмулятор телефонной версии на ПК. Скачал, запустил, но лично мне не нравится визуально (за 7 лет игры привык к другому виду «гаража», «настроек» и т.п.).
А мне вот удобнее вайбер, который я могу запустить на компьютере и выключить телефон. А про ваззап постоянно слушаю нытье менеджеров, у которых он на компьютерах отваливается, стоит телефону связь с интернетом потерять.
в этом плане он тоже для меня более удобен, особенно когда раньше на работе был такой телефон, который просто «не тянул» вайбер и ватсап одновременно. Сейчас уже таких проблем вроде бы как и нет, но пробовали менеджерам так «активировать» вайбер, он тоже достаточно часто слетает.

Есть кейс ещё интереснее, называется "плохое качество мобильной связи в конкретном месте"...

Это «плата» за то, что десктопный клиент у ваззапа — это просто вебклиент в отдельной от основного браузера обёртке. Вообще, сегодня куча «десктопного» софта так выглядит.

А так — большинству как-то пофиг на шифрование, если оно удобству использования мешает. Тем более, что я слышал про то, что в ваззапе нормального клиента пилят. Правда это было в прошлом году ещё, так что либо забросили, либо одно из двух.
Десктопный, как и вебовый «клиент» WhatsApp — это вообще не клиент, а удалённая консоль для мобильного клиента. Отсюда и необходимость последнего быть на связи, и (опосредованно) нежелание разрабатывать нативное приложение.

А такой консольный подход — да, из-за желания сэкономить на e2e шифровании.
Глючный и почти не рабочий пк клиент у ватсапа заставили меня перейт на телегу. Потому что, когда тебе необходимо кому-то скинуть документ с ПК какому-нибудь человеку без электронной почты, с ватсапом начинается чехарда с необходимостью загрузки файла на телефон. А на телелеге есть относительно нормальный пк-клиент, через который можно кинуть файл другому человеку.
У наших передача файла по ваззапу выглядит как «отправил по почте на телефонный почтовый аккаунт — переслал по ваззапу». Ну и получение, соответственно, «получил по ваззапу — переслал на рабочую почту».
ну вот примерно так и есть, всегда приходится исопльзовать какое-то транзитное средство и потом еще искать в какую папку был скачен файл на телефоне
вацап в браузере прекрасно раскидывает файлы без необходимости загружать их на телефон

И даже не с интернетом, а с той локалкой, в которой сидит комп.

Я так глубоко не копал, не пользуюсь.
Просто стоны слышу периодически.

В ТО вроде бы до сих пор флеш-версия рабочая, её можно через standalone player запустить. Как игрок с семилетним стажем вы, вероятно, про это знаете.

Меня бы бесило. Меня вообще бесят виртуальные машины, удаленные рабочие столы и прочее, потому что там не мое родное настроенное окружение, а черт знает что. И если приложение с предустановленным андроидом захочет авторизоваться в гугле, оно не откроет мой десктопный браузер, где я уже авторизовался. Ну, это возможно, но потребует поддержки со стороны гостевой ОС. И сколько еще точек взаимодействия придется проработать? И вот из кучи таких мелочей складывается адское неудобство.

Меня бы устроило, если бы этот «эмулятор» работал по типу Wine — имитируя не телефон, а именно андроид как окружение. Примерно как anbox сейчас делает, но чтобы не выполнять инструкцию из 18 пунктов для установки opengapps :-)

А уж ели в каком-то разумном виде заработает хотя бы часть гуглосервисов — то это будет вполне себе победа, запустил полдесятка андроидо-приложений, каждое в своем окошке одновременно — лепота…

И подозреваю, куда-то в эту сторону мы в итоге и придем.
В эту сторону пришла Chrome OS. Достаточно неплохо получилось. Браузер + приложения android + приложения linux в одной связке.

Даже жалко, что лайтовое железо, которое тащит по 10 часов не чихая Хром с кучей вкладок, связку эту по факту не тянет. В итоге нужен хромбук, но с железом полноценного лаптопа. И тут уже проще влепить убунту и перестать натягивать сову на глобус. Ну или разделить на два девайса — вот тут хром, вот тут хрень.

Старая железяка с Core M3-6y30 держит на себе такие вещи вполне терпимо. В силу проблем с батареей/экраном/usb решил заменить на Lenovo Chromebook Duet, могу через пару недель рассказать, что получится.
А у влепленной убунту будет минус — не столь удобная интеграция с приложениями android. Шашлык от KDE так и не появился, да и Anbox далеко не идеал. Ну и планшетного интерфейса нормального не будет.
У Duet ARM-процессор, с линукс-приложениями в кростини может неловко получиться. Ну т.е. они там конечно есть, но не все.
А что не так с линуксом под ARM? Ну, если мы не говорим про wine — для запуска x86 приложений будет нужен hangover.
А ведь MS хотела в эту сторону Project Astoria habr.com/ru/post/257127 — серьезное упрощение портирования андроид приложений на Windows. Но закрыто.

>Примерно как anbox сейчас делает
И как оно сейчас? Я его тыкал, когда вышел, ничего толком не работало.
Примерно как anbox сейчас делает

И как оно сейчас?
Все так же запутанно и требует большого бубна. Первый запуск все так же крышесносящ — о том как называются два демона на вики не пишут, но прилагают картинку о том что они существуют :-)

Правда появились отдельные «выжившие», которые скриптуют установку тех же opengapps… но не только лишь всякий может долйти до этого шага.
Что потом, после opengapps? Много ли программ работает? Работает ли синхронизация? Уведомления?
Я не пробовал заменять телефон ноутбуком :-)

Мне для своего кода надо было, а штатный эмулятор бесит неимоверно. Можно было конечно использовать реальный телефон — но я как раз с графикой развлекался, на мелком экранчике как-то не очень.

Так что opengapps существует — и хорошо, если понадобится — попробую :-)
это уже есть в ChromeOS. И осенью будет у яблок. Там iosприложения будут работать из коробки на арм маках.
а есть версия от противного — samsung Dex
DeX. При этом есть такие штуки как Nexdock / NexDock Touch / Mirabook(эти правда никак родить ничего не могут) / HP Lapdock (еще от виндового EliteBook) — «ноутбук» на базе DeX (телефон цепляется к 'ноуту-без-мозгов', и либо на кабеле лежит рядом либо висит на жестком держателе). И зачем ноут нужен если докстанция в разы дешевле ноута и может служить долго (только телефоны менять).
А зачем они тогда еще и Catalyst городили?(который упрощает портирование с iPad на macOS?)
оооо, замечательный вопрос. рекомендую к просмотру
Такое ощущение, что Каталист приложения будут позиционироваться как полноценные маковсковские приложения с адаптацией UI конкретно для мака. К примеру, UISwitch превращается в checkbox (NSSwitchButton). И это будет работать как на arm, так и на x86-64
А вот запуск iOS апп на арме — альтернатива для тех, кто не хочет заморачиваться с портированием и будет просто работать.
Apple уже именно это и планирует (поскольку это ж Apple — вам придется купить новый мак на Apple Silicon и приложения будут с iOS). И вроде как будет удобно.
Вся эта возня какая-то странная. Я помню, давным давно был Nokia N900 (владельцем не был, но облизывался), который использовал достаточно большой стек технологий из обычного настольного GNU/Linux (именно с жирным GNU). И на нем работали обычные Linux приложения очень даже. С поправкой на разрешение и интерфейс, конечно. Но победил Android, где решили сделать всё своё, свои библиотеки, свой IPC, свою модель безопасности. Про безопастноть отдельно упомяну, что концептуально это выглядит криво и можно было вместо кучи пользователей для приложений использовать тот же AppArmor, т.к. потом возник геморрой, как добавить нескольких человеческих пользователей в систему. Только ядро Linux тоже самое, но и то переделанное. И вот теперь, эти хиленькие приложеньица пытаются втащить на ноутбуки (Chrome OS) или заменить ими полноценный компьютер (недавно тут была статья про Samsung DeX). Теперь ещё и Apple в ту же сторону. И это какой-то мазохизм в присядку:
— А давайте на мобильных устройствах напишем всё заново, там же всё другое! Ой нет, давайте интерфейс сделаем один на компе и на мобилке (привет майкрософт!), это же так удобно, когда у вас меню из здоровенных прямоугольников, на мобилке можно нажимать пальцем, а в монитор — головой. Эх нет, неудобно, давайте сделаем разные интерфейсы, вернём пуск. Идея! Надо вообще сделать одни и те же приложения и на мобилках и на рабочем столе. Сейчас мы вам ещё притащим 100500 игрушек «тапни чтобы перепрыгнуть какашку» с мобилок (привет Яблоки).
А зачем он нужен, этот Инстаграм? Чтобы что? Мне кажется, он сам часть той же проблемы, что и описанная в статье. Если им пользуется куча народа, это ещё не значит, что это что-то полезное.
Иногда это просто требование бизнеса, из серии «у конкурентов есть и у нас будет», а уж полезный или нет дело десятое, главное «чтобы было».
Не надо сравнивать инстаграмных блогерш с теми кто за компом работает. Вин 8 не зря провалилась и следующие попытки обречены ровно на такой же результат. Мы не будем писать код на планшете если привыкли сидеть как минимум за 3-мя мониторами. Есть определённые задачи которые удобнее делать с планшета телефона потому что их легко таскать с собой, но есть куча работ где никуда не надо идти, а раз так то нафига мобильное решение вообще нужно.
Работать с телефона/планшета можно если вместо работы из дома лежишь на пляже и в чатиках делаешь вид что работаешь :D
Только не нужно забывать, что абсолютное большинство пользователей как раз «инстаграмные блогерши», а массовый рынок всегда ориентируется на большинство.
IDE, всякие тяжелые CAD-пакеты и прочее подобное добро ориентируется далеко не на большинство, а на узкую группу специалистов и организаций (зачастую с неплохой платежеспособностью).
Не станут они веб/мобильными.

vdsina_m, а вы почему сделали фит с филпакартом? Он у вас типа рекламное лиуо или вроде этого, вы за рекламу ему платите или как?

Я вообще испытал когнитивный диссонанс. Ну т.е. когда статью открыл — увидел что это ВДСина, потом начал читать, и почему-то подумал что писал статью Фил. Потом подумал — «да не, это ВДСина, просто какой-то копирайтер с двача пишет в стиле Фила», а потом долистал до конца и слегка прифигел.

Но это кстати круто — раз слог фила так легко детектится просто по куску текста — значит можно обучить нейросетку писать тексты в стиле Фила, а того — отправить писать код.
Это не круто, потому что теперь придётся уходить с VDSina.

И почему вы считаете, что отправить Фила писать код будет хорошо? Насколько я понял из этой статьи и комментариев к ней, чем меньше он будет трогать клавиатуру, тем лучше.

Это, кстати, уже второй персонаж на Хабре за последний год, который пишет фанфики для программистов, а ему все хлопают.
Ни слова не понял ваш русский язык с кучей невосстановленного контекста
Я вообще испытал когнитивный диссонанс


Когнити́вный диссона́нс — состояние психического дискомфорта индивида, вызванное столкновением в его сознании конфликтующих представлений (украл с вики).

Ну т.е. когда статью открыл — увидел что это ВДСина


ВДСина — провайдер впс-серваков и прочего подобного, официлальный российский, зарегестрированный в реестре распространителей информации, и по сообщениям их поддержки в чатике — без задней мысли готовый пускать майора на свое оборудование.

почему-то подумал что писал статью Фил.


Автор поста, fillpackart — знаменит на хабре тем, что пишет посты, провоцирующие волны споров, холиваров и прочего хорошего.

Потом подумал — «да не, это ВДСина, просто какой-то копирайтер с двача пишет в стиле Фила»


Два.ч — самая крупная и достаточно популярная среди школоты, студентоты и постаревших, но не потерявших молодецкой тяги к угару людей, русскоязычная «анонимная» имиджборда (форум с картинками без регистрации) — настолько крупная, что иногда на двач в качестве источника ссылаются всякие журналисты типа ленты.

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

Но это кстати круто — раз слог фила так легко детектится


Детектится — распознается.

просто по куску текста — значит можно обучить нейросетку


Нейросетка — нейросеть, например GAN — Генеративно-состязательная сеть (англ. Generative adversarial network, сокращённо GAN) — алгоритм машинного обучения без учителя, построенный на комбинации из двух нейронных сетей, одна из которых (сеть G) генерирует образцы, а другая (сеть D) старается отличить правильные («подлинные») образцы от неправильных (wiki). По-сути, эта та штука, что стоит за проектами типа «thispersondoesntexist» и тысячами разных других.

Надеюсь стало яснее.

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


λ> :t unzip
unzip :: [(a, b)] -> ([a], [b])

Скоро как у Татьяныча будет. Нейросетка будет писать тексты для забора.

Префикс I в интерфейсах — это пережиток прошлого? Что?

А меня наоборот. Теоретически это мешает переделывать интерфейс в класс и обратно (главное роль типа в программе, а интерфейс это или класс — вторична). Практически, правда, я соблюдаю нейминг конвеншнс того места, где я оказался.

А для чего нужно переделывать интерфейс в класс? По-мойму плохая практика.

Обычно наоборот, конечно. Интерфейсы плохи тем, что их расширение это breaking change. Или кто-то соверинжинирил и сейчас ещё не нужен класс и интерфейс модно убрать лишнюю сущность, оставив только класс.

Они этим не плохи, а хороши. В этом, можно сказать, их суть.
Делать интерфейсы = бетонировать.

Да, поэтому когда надо перелезать участок забора рефакторят.

Ну это зависит от коде стайла, нет? Я видел кодовые базы, где интерфейс звался SomeCoolManager а реализация — SomeCoolManagerImpl (или SomeCoolManagerStub в тестах). В целом, здесь префикс I не нужен так как по всему коду используется только первый, а Impl — только в файле реализации.

В Java, кстати, его и не делают, насколько я знаю. Тут вопрос не в том, нужен он или нет, вопрос в том, чтобы писать привычный для шарпистов код на C#. По крайней мере, меня убедили именно таким аргументом.

В Java его не ставят, потому что канонично оперировать именно объектом интерфейса, а не реализующим интерфейс классом (которые часто обозначаются суффиксом Impl, но это не обязательно).

В C# маленькую I вполне можно терпеть. А вот в PHP, например, некоторые продвигают суффикс Interface. Вполне живут всякие LoggerInterface в ключевых стандартах… Вот тогда немного задумываешься и становится понятным, что все эти суффиксы и префиксы не нужны. Именно имя интерфейса является главным именем, которое используется везде и именно оно должно быть емким, кратким и красивым. Без суффиксов и префиксов.
Оперирование интерфейсами — это не фишка, присущая конкретному ЯП, а общая концепция.
Я предпочитаю префикс I, это куда нагляднее, чем инверсная логика «нет суффикса — интерфейс, есть суффикс Impl — реализация».

Не могу говорить за все языки, потому как их не знаю.
КМК, ставить префиксы имело смысл в языках без явного синтаксического разделения сущностей (Pascal, C, C++), но там, где семантическая роль выделена синтаксисом самого языка, дополнительное обозначение избыточно. Может еще кто-то кодит в блокноте, и ему/ей сложно искать в коде определение сущности — ну как бы штош...

Код ревью же. Его часто делают из браузера (десктопного), и там IDE не подсветит

С языковыми серверами на бэкенде подсветит. Но блин...

Возникает вопрос, а почему важно знать интерфейс это или реализация? Ведь везде должны быть только интерфейсы, не? Точнее везде должны использоваться именно те сущности, которые должны быть предоставлены чужому коду. Если библиотека дает интерфейс и несколько реализаций, то везде используется интерфейс. Если мы создали сущность Post, то везде используется именно она, потому что интерфейса нет. Так может немного переосмыслить эту ситуацию и везде использовать именно простые имена и не обращать внимания интерфейс это или класс.
Возникает вопрос, а почему важно знать интерфейс это или реализация? Ведь везде должны быть только интерфейсы, не?

Например чтобы на кодревью надавать по шапке тому кто поленился и вместо интерфейса использует класс :)

P.S. И да, кодревью далеко не всегда делается в IDE и поэтому удобнее когда интерфейс можно отличить от реализации просто по названию.
Так можно же делать стандарты когда нормальное имя без префиксов и суффиксов должно использоваться. Использует он Logger — молодец. FileLogger — нет. Хотя… конечно, всё не так просто. Вроде гитхабы делают подвижки в сторону понимания кода и скоро будет кое-как перемещаться по нему и во время ревью…
Например чтобы на кодревью надавать по шапке тому кто поленился и вместо интерфейса использует класс :)
А зачем? Какая разница чем представлен тип — классом или интерфейсом? При условии, что речь не идет об АПИ какой-нибудь библиотеки, а о внутреннем коде.

Если это вот прямо совсем "внутренний код", то никакой. А если речь идёт хотя бы о разных проектах, то использование классов может создать определённые проблемы. Например лишние зависимости между отдельными проектами. Или даже перекрёстные ссылки.

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

С префиксами в имени такое заметнее. Особенно если ревьюишь не в IDE.

В самом деле? Т.е. слово interface вместо class в объявлении класса — это незаметно, а префикс I — это заметно? Ну и в той же Java интерфейс также может содержать тела методов, и, следовательно имеет все те же риски, что и класс.

Нет. Префикс "I" или его отсутствие очень просто и быстро видно в самом APl.


И да, с интерфейсами можно тоже кучу глупостей наделать. Просто такая банальная вещь как naming conventions заметно облегчает жизнь отдельным людям в отдельных ситуациях.


Это не значит что все должны их использовать. И уж тем более не значит что всем надо использовать одни и те же. Но вот у нас такие и нам так удобнее.

В Java принято называть интерфейсы прилагательными, например Drawable, Writeable и т.д. В С++ я часто пишу префикс Abstract для нечисто-виртуальных классов, когда нужно дать понять, что это именно абстрактный класс с необходимостью переопределения некоторых методов. Либо для чисто-виртуальных классов что-то очень общее, например Transmitter, с реализациями TcpTransmitter, SerialTransmitter, UnblockingSerialTransmitter и т.д. Impl в этом случае только засоряет лаконичное имя класса, который, к слову, можно использовать и без применения полиморфизма. Объективно — использование префикса I объясняется языковыми особенностями. Например, в С++ в принципе такого понятия интерфейса, как в Java, не существует, поэтому было бы странно видеть «открывающую» I в имени класса)

Интерфейс — прилагательное, класс — существительное, метод — глагол ;)

Если нужен суффикс Impl, то, вероятно, этот интерфейс не нужно было выделять. Для клиентов нет разницы, сунут ему SomeCoolManager с реализацией или без.

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

Ничем, но это более внешнее требование по отношению к данному компоненту.

Ну, так-то интерфейс — сам по себе анти-паттерн, хотя бы потому, что нарушает SRP. External protocols — это интерфейс здорового человека, а охапка методов, которые каждая собака должна имплементировать, даже если это выходит за рамки разумного, — порождающих безумную копипасту и груду полуживых имплементаций — несомненное зло.


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


Интерфейсы кажутся приемлемым решением только людям, которые вообще не способны в архитектуру.

У меня такое впечатление, что вы увидели слово-триггер и завелись на него. Иначе такой поток атаки на интерфейсы сложно объяснить. Но хорошо, попробуем разобрать детальнее, мне уже стало интересно:


Ну, так-то интерфейс — сам по себе анти-паттерн, хотя бы потому, что нарушает SRP.

Чем нарушает-то? Прошу подробностей.


External protocols — это интерфейс здорового человека,

External protocol в контексте ООП вообще не гуглится. Дайте расшифровку, что вы понимаете под этим. Если имеется в виду связь с другими компонентами через сетевые протоколы, то я не понимаю, зачем их тут вообще примешивать.


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

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


Использование интерфейсов — уже само по себе звоночек

Чего именно звоночек-то?


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

Пометка, что определённый тип декларируется как обладающий определённым свойством. Конечно, было бы лучше дать возможность компилятору это вывести, но они ещё много лет не будут способны делать выводы только за пределами самых простейших. Если тут кто-то некомпетентен, то человечество в целом. И что, прикажете стреляться атомными бомбами?


Интерфейсы кажутся приемлемым решением только людям, которые вообще не способны в архитектуру.

Ваши альтернативные предложения — в студию. Только конструктивно.

Начну с середины, для связности.


External protocol в контексте ООП вообще не гуглится. Дайте расшифровку, что вы понимаете под этим.

Причем тут контекст ООП? Что в ООП такого особенного, что у него должны быть паттерны, идущие вразрез с не ООП? В Хаскеле это называется Type Class. В Эликсире — протокол. Полиморфизм без необходимости размазывать имплементацию по разным частям кода. Наиболее внятно принципы расписаны в гайдах по эликсиру.


нарушает SRP.
Чем нарушает-то? Прошу подробностей.

Давайте возьмем в качестве примера набивший оскомину Comparable. Сравнение — само по себе сущность, которая, кхм, отвечает за сравнение. SRP решение: описываем type class / protocol, который умеет сравнивать. Интерфейсное решение: каждый класс, который хочет уметь сравниваться, должен, видите ли, немного отвечать за сравнивание. Хотя он, вообще-то, модель User. Вы не видите тут нарушение SRP? С какой радости модель должна отвечать за данные, и еще немножко за сравнивание? А что если я хочу научить чужой класс сравниваться? Аспекты, рефлекшн, магия?


Чего именно звоночек-то?

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


Пометка, что определённый тип декларируется как обладающий определённым свойством.

Угу. А зачем? Вернемся к Comparable. Кому хорошо от того, что User знает, что он умеет сортироваться? Никому. Сущность «Сравнивание» должна уметь принять пару объектов типа User и либо вернуть -1 | 0 | 1, либо вежливо отказаться сравнивать несравнимое. Тогда и для чужих сущностей я смогу определить любой нужный мне «интерфейс» без хаков и магии.


Ваши альтернативные предложения — в студию.

Озвучил же уже: протоколы / тайпклассы и dependency injection.

Сравнение — само по себе сущность, которая, кхм, отвечает за сравнение. SRP решение: описываем type class / protocol, который умеет сравнивать. Интерфейсное решение: каждый класс, который хочет уметь сравниваться, должен, видите ли, немного отвечать за сравнивание.

И почему нет? Почему нельзя чтобы каждый класс сам решал как для него выглядит сравнение? Чем лучше если ваша сущность «Сравнивание» должна знать как выглядит сравнение для абсолютно всех существующих классов? И если в вашей ситуации мы добавляем новый класс, которые должен сравниваться, то мы должны лезть и менять вашу сущность «Сравнивание». И когда у какого-то класса вдруг почему то изменилось сравнение, то тоже самое — надо лезть в сущность «Сравнивание» и её менять. И при этом мы в теории можем сломать сравнение для уже существующих классов.

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

И что теперь делать когда нужно добавить новый сравниваемый класс? Каждый раз просить кого-то там изменить сущность «Сравнивание»?

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

Угу. А зачем? Вернемся к Comparable. Кому хорошо от того, что User знает, что он умеет сортироваться? Никому. Сущность «Сравнивание» должна уметь принять пару объектов типа User и либо вернуть -1 | 0 | 1, либо вежливо отказаться сравнивать несравнимое.

Угу, а потом ваш код великолепно компилируется, а во время исполнения ваша сущность «Сравнивание» начинает выдавать одну ошибку за другой.

Озвучил же уже: протоколы / тайпклассы и dependency injection.

И каким конкретно образом dependency injection должна заменять интефейсы?
И если в вашей ситуации мы добавляем новый класс, которые должен сравниваться, то мы должны лезть и менять вашу сущность «Сравнивание»?

Подозреваю, что речь идёт о подходе а-ля Rust, в котором будет (псевдокод)


... неважно где...
class Foo<T> {
  внутренности класса
}
... где-то ближе ...
impl Compare for Foo<T> {
  func less(a: & const T, b: & const T) {
    ...
  }
}

то есть оно не оформляется внутри типа и формальная сравниваемость не строится в зависимостях типа, а объявляется вне его.


Она может быть и сразу рядом с описанием типа, и добавлена кем-то со стороны, а увидит её компилятор или нет — зависит от того, какие объявления подключены к этому моменту, не хотим — не подключаем. Объявить Compare для чужого типа, не зная его названия — сложно, для всех сразу — невозможно, поэтому явный абьюз малореален.


Мне этот подход скорее нравится, хотя тут надо бы уточнить ряд особенностей — могу ли я, например, для производного класса запретить, наоборот, такую имплементацию, если ломаю её контракт?


И если в вашей ситуации мы добавляем новый класс, которые должен сравниваться, то мы должны лезть и менять вашу сущность «Сравнивание».

Стандартный полиморфизм по параметру X в impl Compare for X — решает эту проблему.


И когда у какого-то класса вдруг почему то изменилось сравнение, то тоже самое — надо лезть в сущность «Сравнивание» и её менять.

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


На самом деле это вполне естественный сдвиг по сравнению от явного объявления интерфейсов, когда вам надо определить какое-то свойство, которое автору соответствующих типов просто никак не было нужно.
Например, он сделал иерархию животных и выделил базовые свойства — рептилии, млекопитающие, птицы…
А мне нужно определить всех летающих: птицы, но не все; белки-летяги; летучие рыбы; рукокрылые. Я беру отдельный типаж FlyingAnimal и назначаю его применимость к заданным типам по иерархии (причём, если язык позволяет, включаю туда птиц, а потом исключаю страусов, эму, казуаров и дронтов).


В C++ строится подобное, но косвенно (через хаки типа std::enable_if, замусоривающие имя типа и закаменяющие применённое ABI). Во многих других языках и сейчас нельзя.


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


И ещё очень хорошо надо подумать над бинарной совместимостью. Если есть библиотека, в которую мы передаём просто указатель/ссылку/чтоугодно на Comparable, FlyingAnimal, etc., и её нельзя перекомпилировать под каждое применение — требуются решения, сходные с тем, как в Java для интерфейса, в C++ для базового класса при множественном наследовании...

Она может быть и сразу рядом с описанием типа, и добавлена кем-то со стороны

Но это всё равно уже не
Сущность «Сравнивание» должна уметь принять пару объектов типа User и либо вернуть -1 | 0 | 1, либо вежливо отказаться сравнивать несравнимое.


И опять же чтобы её написать надо знать либо внутренности класса, либое его интерфейс, либо ещё какое-то формальное описание этого класса. Без этого знания вы всё равно Compare не напишите.

Объявить Compare для чужого типа, не зная его названия — сложно, для всех сразу — невозможно, поэтому явный абьюз малореален.

На мой всзгляд проблема скорее не в абьюзе, а в возможной необходимости писать Compare для чужого типа, не зная его названия/содержания.

На самом деле это вполне естественный сдвиг по сравнению от явного объявления интерфейсов, когда вам надо определить какое-то свойство, которое автору соответствующих типов просто никак не было нужно.

Это совсем другая проблема и естественно интерфейсы вроде Comparable и не должны её решать.
На мой всзгляд проблема скорее не в абьюзе, а в возможной необходимости писать Compare для чужого типа, не зная его названия/содержания.

Compare как раз тут, да, слегка проблемный пример. Тип может и не экспортировать необходимые данные для сравнения. Мне кажется, с летающими получилось немного лучше.
Но совсем для неизвестных типов вроде ж никто такое и не пишет?


Это совсем другая проблема и естественно интерфейсы вроде Comparable и не должны её решать.

Тут тот момент, что при наличии таких типажей/протоколов/you_name_it может оказаться, что интерфейсы в классическом виде и не нужны...

Ну на мой взгляд интерфейсы всегда будут нужны когда у вас есть «состыковка» между двумя областями и над каждой областью независимо от друг-друга работают разные люди. Или хотя бы в теории могут это делать.

То есть в такой ситуации вам нужна какая-то форма «договора», которого будут придерживаться обе стороны. И для меня как раз вот это в первую очередь и является интерфейсом. А как там эти интерфейсы реализованны в отдельных ЯП/фреймворках/ситуациях и какие они там ещё дополнительные функции могут нести это на мой взгляд уже вторично.

А как там эти интерфейсы реализованны в отдельных ЯП/фреймворках/ситуациях и какие они там ещё дополнительные функции могут нести это на мой взгляд уже вторично.

Ну а вся ветка дискуссии как раз посвящена тем особенностям, которые для вас тут вторичны :) но далеко не так в том случае, когда это начинает влиять на реализацию.

Мне этот подход скорее нравится, хотя тут надо бы уточнить ряд особенностей — могу ли я, например, для производного класса запретить, наоборот, такую имплементацию, если ломаю её контракт?

Можете уточнить вопрос? Я его не распарсил, а ответить хочется.

Я его не распарсил, а ответить хочется.

:)))


Ну вот буквально в соседнем комментарии. Мне нужен типаж "летающие животные" (предположим игру, где персонаж может улететь от врага через пропасть).
Я знаю, что 99% птиц летают и это осилят (даже какая-нибудь курица, хоть она и не любит летать). Но есть нелетающие: персонаж-страус этого не осилит.
И у меня иерархия типов. Я могу всем птицам раздельно ставить пометку "этот летает", но если я где-то пропущу, пойдут жалобы на нелетающих астрильдов. А могу исключить только мелкие группы действительно нелетающих — но тогда я должен иметь возможность для каких-то типов выключать возможность, которая включена для их предковых типов.


В идеале я ожидаю что-то вроде:


impl Flying for Bird {
  // неважно что, важен факт разрешения impl Flying
}

#[prohibited] impl Flying for Ostrich {
}

Если такого нет, я или помечаю каждую подветку птиц раздельно (задолбаться и с ошибками), или должен рисовать что-то типа:


impl FlyingCheck for * {
  func Flies() bool { return false; }
}
impl FlyingCheck for Bird {
  func Flies() bool { return true; }
}
impl FlyingCheck for Ostrich {
  func Flies() bool { return false; }
}

но при этом проверка усложняется до


impl EscapeByFly for T
  when FlyingCheck[T] and T.Flies()
{ ... }

и мы впадаем в C++ с его проблемой, что чтобы скомпилировать, нужно интерпретировать какое-то подмножество языка и во время компиляции проверять constexprʼы.


Ну, вот, жду ответа :)

Теперь понятно, спасибо.


Ну вот вы хотите написать код:


impl Flying for Bird {
  // неважно что, важен факт разрешения impl Flying
}

#[prohibited] impl Flying for Ostrich {
}

Но какова связь между Bird и Ostrich? В расте (насколько я знаю) нет наследования типов, поэтому у вас будет просто отдельный тип Bird и отдельный тип Ostrich, с которым ваш Bird никак не может быть связан.


А чтобы обсуждать, как сделать Bird связанным с Ostrich, надо уже обсуждать более конкретные вопросы из предметной области.


и мы впадаем в C++ с его проблемой, что чтобы скомпилировать, нужно интерпретировать какое-то подмножество языка и во время компиляции проверять constexprʼы.

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

Но какова связь между Bird и Ostrich? В расте (насколько я знаю) нет наследования типов, поэтому у вас будет просто отдельный тип Bird и отдельный тип Ostrich, с которым ваш Bird никак не может быть связан.

Я упомянул, что у нас иерархия типов. И Ostrich — подкласс (неважно, насколько дальний) для Bird. От Rust здесь только условный стиль.


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

Не понял, что тут "это", расшифруете?

Я упомянул, что у нас иерархия типов. И Ostrich — подкласс (неважно, насколько дальний) для Bird. От Rust здесь только условный стиль.

Ну нельзя же просто рассматривать стиль, чтобы и тайпклассы были, и ООП-наследование. Получится скала какая-то, а там своих костылей дофига.


В подавляющем большинстве языков с тайпклассами или их аналогами нет сабтайпинг-полиморфизма и нет наследования.


Не понял, что тут "это", расшифруете?

Компилтайм-вычисления.


В языках с зависимыми типами у вас тип может зависеть от произвольного терма языка, и эти термы нужно уметь вычислять. Idris, Coq, Agda и ещё менее известные так умеют, Haskell — нет. Условный Dependent Haskell, который бы научился это делать, ждут уже лет 10-15 и всё никак не дождутся.

Ну нельзя же просто рассматривать стиль, чтобы и тайпклассы были, и ООП-наследование. Получится скала какая-то, а там своих костылей дофига.

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


В том же C++ я вполне могу определить, в согласовании со стандартными правилами разрешения полиморфизма, или функцию, которая параметризована типом и вернёт true для Bird, но false для Animal и Ostrich; или структуру, в которой будет функция со свойством; и компилятор будет обязан разобрать такие константные функции и разрешить или запретить соответствующее воздействие:


Страшный код
#include <cstdio>
#include <type_traits>

using namespace std;

struct Animal {
};
struct Chordatum : Animal {
};
struct Bird : Chordatum {
};
struct Struthionida : Bird {
};
struct Ostrich : Struthionida {
};

template<typename> struct is_flying_helper : public false_type {};
template<> struct is_flying_helper<Animal> : public false_type {};
template<> struct is_flying_helper<Bird> : public true_type {};
template<> struct is_flying_helper<Ostrich> : public false_type {};
template<typename Tp> struct is_flying
  : public is_flying_helper<typename remove_cv<Tp>::type>::type
  {};

template<typename Tp>
typename std::enable_if<is_flying<Tp>::value>::type
makeItFly(Tp&)
{
  printf("It flies!\n");
}

int main() {
  //printf("%d\n", is_flying<Animal>::value);
  Bird animal;
  makeItFly(animal);
}

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


Но то, как оно выглядит внутри — вместе со всем C++ — как китайские ёлочные игрушки: не радует.


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

И ему не надо ничего у себя там писать или менять или думать как вообще должны сравниваться мои классы.

Кстати, вот это как раз очень часто неадекватно именно потому, что сравнение может быть для разных целей заметно по-разному — тут я согласен скорее с коллегой chapuza@. Методы стандартных библиотек, которые используют сравнение (как сортировка или хранение в дереве), по умолчанию используют некоторый штатный компаратор, но дают переопределение для своих целей — и это неспроста (и не только для изменения на обратный порядок).
Возьмите, например, даты. Для списка дней рождений нам надо сравнивать, выкинув год из учёта.
Встроенное сравнение обычно предназначено обеспечивать только что неидентичные объекты неравны.

IComparable это грубо говоря «базовое» сравнение, которое большинство C# библиотек используют по умолчанию.

Если вам нужны несколько видов сравнения для одного класса, то вам нужно либо несколько интерфейсов для кажой из целей, либо действительно уже использовать «внешнее» сравнение. Для этого в C# существует тот же IComparer интефейс. И этот самый IComparer тоже понимают/поддeрживают большинство библиотек.

Но в подавляющем большинстве случаев хватает одного IComparable.
Причем тут контекст ООП? Что в ООП такого особенного, что у него должны быть паттерны, идущие вразрез с не ООП?

Я разве сказал про обязанность таких паттернов? :) Я сказал, в каком контексте пытался гуглить термин, потому что он явно не из общеизвестных. Вы заводитесь там, где просто не нужно.


Давайте возьмем в качестве примера набивший оскомину Comparable. Сравнение — само по себе сущность, которая, кхм, отвечает за сравнение. SRP решение: описываем type class / protocol, который умеет сравнивать.

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


Сущность «Сравнивание» должна уметь принять пару объектов типа User и либо вернуть -1 | 0 | 1, либо вежливо отказаться сравнивать несравнимое.

И вы получаете на этом большее нарушение — необходимость выдать этой самой Comparable в доступ (хотя она определена снаружи) внутренности объекта, которые вполне могут быть приватными. Что, friend-ы объявлять?

Вы заводитесь там, где просто не нужно.

Когда я завожусь, я надеваю цилиндр и прыгаю до потолка. Это не тот случай, поверьте :)


От того, что вы формально выносите эту роль наружу, только формальные признаки и меняются.

Отнюдь. Я не выношу «роль» наружу. Я предлагаю писать код так, чтобы модель отвечала за свойства модели, а сравниватель  —за сравнение. Сериализатор — за сериализацию. И так далее.


Еще ярчайший пример: Object.hashCode() —  как только я захочу в хэшмапе использовать в качестве ключей разные объекты — мне придется идти и смотреть на реализацию самих объектов, а не тайп-класса.


Ну и, я все-таки настаиваю, что вынесение разных ролей за пределы одной сущности — это и есть краеугольный камень SRP.


необходимость выдать этой самой Comparable в доступ (хотя она определена снаружи) внутренности объекта, которые вполне могут быть приватными. Что, friend-ы объявлять?

Изящно, но мимо. Сортировка по чему-то такому, что недоступно извне — за гранью разумного. Это как сортировать Objectы. Не бывает такого, что мне нужно отсортировать по какому-то признаку, но получить доступ к этому признаку мне нельзя, это нежизнеспособный пример.


Ну и это… Вот представьте, что мне втемяшилось сравнивать яблоки и столы. В какой класс: «Apple» или «Table» мне положить правильный компаратор?

А с чего вы решили что Comparable должен применяться для сравнения разных классов между собой? Он отвечает за сравнение объектов одного класса.


Но давайте другой пример. Скажем я пишу ORM, которой будут пользоваться какие-то неизвестные мне люди для каких-то своих неизвестных мне нужд. То есть они просто берут какие-то свои классы, а мой ORM генерирует из них таблицы в базе данных и сам целиком отвечает за работу БД.


И скажем мне чтобы решить использовать Insert или Update надо знать есть у меня уже где-то этот объект или он новый. Для этого мне нужна какая-то функциональность, которая банально сравнивает два объекта произвольного класса и говорит мне идентичны они с точки зрения бизнес-логики или нет. Я такое всегда решал через интерфейс IEquatable. Как вы предлагаете такое решать без интерфейсов?

А с чего вы решили что Comparable должен применяться для сравнения разных классов между собой? Он отвечает за сравнение объектов одного класса.

Ну с того, например, что чуть-чуть разбираюсь в CS.


public interface Comparable<T> → This interface imposes a total ordering on the objects of each class that implements it. — Java8

public int CompareTo(object obj) { if (obj == null) return 1;.NET

От микрософтов я ничего внятного в документации и не ждал, но поправьте меня, если я ошибаюсь: сравнение с null вот прямо в первом же примере.




И скажем мне чтобы решить использовать Insert или Update надо знать есть у меня уже где-то этот объект или он новый.

Погуглите Upsert, эта проблема решена в XIX веке.


сравнивает два объекта произвольного класса и говорит мне идентичны они с точки зрения бизнес-логики или нет
Я такое всегда решал через интерфейс IEquatable.

Круто, что вам разрешили изменить код, к которому вы даже теоретически доступа не имеете. Либо вы можете обязать ваших пользователей написать вам пол-библиотеки за вас — и тогда вариантов масса. Либо нет — и тогда у вас нет гарантии, что IEquatable имплементирован хоть кем-то вообще.

От микрософтов я ничего внятного в документации и не ждал, но поправьте меня, если я ошибаюсь: сравнение с null вот прямо в первом же примере.

null в шарпах это не отдельный класс. Это грубо говоря просто «пустая ссылка». Более того там ниже по тексту:
This interface is implemented by types whose values can be ordered or sorted. It requires that implementing types define a single method, CompareTo(Object), that indicates whether the position of the current instance in the sort order is before, after, or the same as a second object of the same type.


Погуглите Upsert, эта проблема решена в XIX веке.

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

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

Кто и где мне разрешил менять какой-то код? Я вообще ничей код менять не собираюсь. Я пишу свою собственную ORM и ставлю условие что для того чтобы использовать с ней какой-то класс, то этот класс должен имплементировать интерфейс IEquatable.

Либо вы можете обязать ваших пользователей написать вам пол-библиотеки за вас — и тогда вариантов масса.

Они вообще не должны за меня ничего писать. Они должны сами для себя решить как должны сравниваться на идентичность их собственные классы.

Может им достаточно одного id для сравнения. А может у них id композитные. А может у них как id вообще используется какой-то их собственный класс. Или им для идентичности необходимо чтобы абсолютно все поля были идентичны.

Откуда я должен это знать когда я пишу своё ORM?

Похоже, этот комментарий стал хэдшотом. А жаль, было интересно(=

Этот комментарий стал выстрелом в голову самому себе. Я не вижу смысла продолжать что-то объяснять людям, которые в соседних предложениях пишут буквально следующее:


Я [...] ставлю условие что для того чтобы использовать с ней какой-то класс, то этот класс должен имплементировать интерфейс IEquatable.

Они вообще не должны за меня ничего писать.

Ну так а в чём конкретно претензии? Особенно если учитывать что предложенные вами альтернативы с инъекциями и DP имеют точно ту же проблематику.

Они не имеют этой проблематики. И я примерно пятьсот раз это уже повторил и расписал, с примерами, которые вы просто не понимаете.


Претензий никаких нет вообще.

Ну уж нет. Ваши альтернативы это проблематику точно так же имеют. Потому что если вы сами знаете как будет выглядеть сравнение для классов пользователя, то зачем вам вообще нужны инъекции или ДП? Сразу запихиваете это в вашу имплементацию и проблемы нет.

А если вы вашу имплементацию финализировали, отдали кому-то и этот кто-то хочет добавить сравнение для каких-то своих новых классов при помощи инъекции или DP, то он это точно так же должен делать сам. Или вы предлагаете ему в такой ситуации обращаться к вам и ждать пока вы найдёте время сделать это сами?

Так что конкретно в данном аспекте разницы нет ровно никакой.
А с чего вы решили что Comparable должен применяться для сравнения разных классов между собой? Он отвечает за сравнение объектов одного класса.

То есть даже с производным классом сравнить нельзя? По-моему, это чрезмерное ограничение.

У вас в такой ситуации будет сравнение по имплементации IComparable из базового класса.

Это очень толсто.


Вы мне лично сами пару месяцев тому — демонстрировали мощь хаскеля на примере сортировки разных типов; лень ссылку искать.


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


Kanut вон выше пишет, что в шарпе мне даже не удастся изобрести специальный интерфейс, чтобы сравнивать по нему, все равно придется построить God-объект, который будет сортировать разношерстные коллекции.


В джаве, слава Гослингу, мне хотя бы дадут объявить IHavingDate с методом getDate, и я смогу их отсортировать, если ни одна из имплементаций не забудет про него.

Kanut вон выше пишет, что в шарпе мне даже не удастся изобрести специальный интерфейс, чтобы сравнивать по нему, все равно придется построить God-объект, который будет сортировать разношерстные коллекции.

На самом деле не совсем так. В теории вы можете написать интрефейс IGodComparable, который будет сравнивать любые классы, которые имплементируют интефейc ISpecialComparable. Просто мне сложно представить зачем это нужно.

У меня John Major от этой фигни.


Даже в хаскеле вы не можете сравнивать и сортировать разные типы, вы можете их завернуть в один экзистенциальный тип и сортировать его. А если вам нужен аналог IHavingDate, то у вас либо будет экзистенциал вроде


class HasDate a where
  getDate :: a -> Date

data SomeHasDate where
  theSHD :: HasDate a => a

либо, в более мощных языках, что-то вроде списка List (a : Type ** (a, a -> Date)).


Что, в принципе, тот же экзистенциал, вид сбоку.

Любые в зависимости от задачи.
Вот у меня есть например 3 подвида таймеров: однократные, многократные с интервалом между стартами и многократные с интервалом между работами. Но для сравнения мне нужно только время ближайшего старта.

Тогда либо выводите все три из одного базового класса, время ближайщего старта пихаете в базовый класс и пишете там сравнение по нему. Либо создаёте свой новый интерфейс, который имеет внутри время ближайщего старта и пишите сравнение по этому интерфейсу.

То есть в теории можно сравнивать разные объекты до тех пор пока они все либо имеют один базовый класс, либо имплементируют один общий интерфейс.

Но вот именно IComparable и именно с абсолютно произвольными классами работать не будет.
То есть в теории можно сравнивать разные объекты до тех пор пока они все либо имеют один базовый класс, либо имплементируют один общий интерфейс.

В какой теории? В теории ущербных языков программирования?


Перечитайте самое начало этого треда: интерфейсы — тупиковая ветвь эволюции, придумавшим их людям должно быть стыдно. Они приносят проблемы на ровном месте, нарушают основные работающие принципы CS и вообще бессмысленны со всех точек зрения, кроме «я умею только в один энтерпрайзный язык, и тут так, поэтому это хорошо».


Вы же даже сами чуть ниже расписываетесь в том, что интерфейс не нужен:


К счастью для этого у отдельных классов/типов есть CompareTo [...].
В какой теории? В теории ущербных языков программирования?

В теории, обсуждая ситуацию, имеющуюся на данный момент в C#.

Перечитайте самое начало этого треда: интерфейсы — тупиковая ветвь эволюции, придумавшим их людям должно быть стыдно

Я вот пока вижу с вашей стороны кучу критики интеpфейсов, но так и не увидел ни одного конкретного ответа на поставленные мною вопросы. И вариaнтов «безинтерфейсных» решений озвученных мною проблем я от вас тоже пока не увидел.

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

Вы же даже сами чуть ниже расписываетесь в том, что интерфейс не нужен:

Это уже какая-то демагогия начинается. Естественно интерфейсы нужны не всегда и естественно не все проблемы решаются с помощью интерфейсов. Но это не значит что интерфейсы не нужны в принципе.
обсуждая ситуацию, имеющуюся на данный момент в C#

Если вы вдруг не обратили внимание, C# сюда принесли и здесь обсуждаете только вы.


так и не увидел ни одного конкретного ответа на поставленные мною вопросы

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


вариaнтов «безинтерфейсных» решений озвученных мною проблем я от вас тоже пока не увидел

Прям беда. Ваши «проблемы» — это не проблемы вообще, их можно решить и интерфейсом, и отдельным сортировщиком, и как угодно. Но только интерфейсный вариант заставляет пользователей вашего кода писать кучу им не нужного бойлерплейта, чтобы ваша библиотека была способна работать.


На мой взгляд это вы просто похоже в вашей работе не сталкиваетесь с проблемами, которые решаются при помощи интерфейсов.

Ваша правда; ибо таких задач нет. Точнее, не так: такие задачи появляются как искусственные ограничения, поставленные плохо спроектированным языком программирования. Я не пишу на языках, которые вынуждали бы меня постоянно чувствовать себя удаляющим гланды проктологом.


не все проблемы решаются с помощью интерфейсов

Тут ветка, в ветке контекст. Контекст — волею случая — интерфейс Comparable. Простейший, как амеба. Один, блин, метод. Но костылей вокруг пришлось понагородить — районную больницу можно было бы этими костылями обеспечить. ПростоComparambe, ComparambeСВывертом, CompareTo… Удивлен, что нет CompareFrom и CompareInstead.


А всего-то надо было: понять, что сравниваемость ортогональна физическим свойствам и вынести ее в отдельную сущность сбоку.

Если вы вдруг не обратили внимание, C# сюда принесли и здесь обсуждаете только вы.

Вообще-то нет. Про Comparable и, цитирую, «чуть-чуть разбираюсь в CS» начал совсем не я.

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

Это не отвечает на поставленные мною вопросы и не даёт решения для описаных мною примеров. И как раз поэтому я их вам и задал.

Ваша правда; ибо таких задач нет.


Ну давайте я ещё раз повоторю если вы что-то пропустили или не поняли:

Допустим я пишу библиотеку, которая должна отвечать за сортировку данных. Как мне без интерфейсов сделать так чтобы эта библиотека могла сортировать абсолютно любые сравниваемые типы данных? Причём даже те типы данных, которые появятся после окончания работы над этой библиотекой? И с ошибками во время компиляции, а не во время исполнения?

Тут ветка, в ветке контекст. Контекст — волею случая — интерфейс Comparable. Простейший, как амеба. Один, блин, метод.

Я не вижу здесъ «простейшего как амёба метода». Я вижу пожелания вроде того чтобы этот метод мог сравнивать между собой абсолютно любые типы данных. Чтобы он мог сравнивать по разному в зависимости от контекста. Чтобы он мог сравнивать даже те типы данных, которые пока ещё не существуют. И так далее и тому подобное.

Но если для вас это простейщий метод, то наверняка вам не составит труда показать имплементацию метода, который удовлетворяет хотя бы трём вышепречисленным условиям. На любом удобном вам языке и без интерфейсов.
И с ошибками во время компиляции, а не во время исполнения?

Ух ты, как мы прямо на лету ТЗ-то меняем, любо-дорого смотреть. А ничё, что не все языки — компилируемые?


Я вижу пожелания вроде того чтобы этот метод мог сравнивать между собой абсолютно любые типы данных.

Нет только те, которые хотят сравниваться. Ну да ладно, я и для любых могу (идея позаимствована у Армстронга и Вирдинга) — оператор сравнения работает из коробки для всех типов данных языка:


number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string

Да, это не совсем то, чего вы ожидали. Ну ладно, давайте поближе к земле.


Чтобы он мог сравнивать по разному в зависимости от контекста

ruby, классическая Dependency Injection, пример из моего первого комментария.


def compare o1, o2, comparator = Comparator.def
  comparator.(o1, o2)
end

Чтобы он мог сравнивать даже те типы данных, которые пока ещё не существуют. И так далее и тому подобное.

Пример поизящнее: map-sort из elixir.


Инъекция кода, изменение AST.


defmodule User do
  use Comparable, compare_to: fn 
    me, %User{} = user -> me.full_name < user.full_name
    me, %{id: id} = other -> me.id < id
    me, other -> me < other
  end
  ...

Ну и, наконец, протоколы.


defprotocol Comparable do
  @doc "Returns a term that would be used to compare"
  def term(data)
end

...

@spec sort(any(), any()) :: boolean()
def sort(e1, e2) do
  case {Comparable.impl_for(e1), Comparable.impl_for(e2)} do
    {nil, _} -> e1 < e2
    {_, nil} -> e2 < e1
    {c1, c2} -> c1.term(e1) < c2.term(e2)
  end
end

Теперь если какая-то сторонняя сущность пожелает участвовать в конкурсе, от автора потребуется имплементация одного метода из протокола, причем он может как сам ее написать, так и воспользоваться любой существующей.


Ах да, ошибки во время компиляции. Ну, эликсир компилируется, так что всегда пожалуйста: в последнем примере имплементация протокола будет такая:


@compile {:inline, sort: 2}
def sort(e1, e2) do
  [e1, e2]
  |> Enum.map(&Comparable.impl_for!(&1).term(&1))
  |> Enum.reduce(&:</2)
end
Ух ты, как мы прямо на лету ТЗ-то меняем, любо-дорого смотреть. А ничё, что не все языки — компилируемые?

Почему же на лету. Это уже упоминалось в дискуссии. Вы пропустили?

Нет только те, которые хотят сравниваться. Ну да ладно, я и для любых могу (идея позаимствована у Армстронга и Вирдинга) — оператор сравнения работает из коробки для всех типов данных языка:

Меня не имнтересует сравнение для ограниченного набора типов данных. Меня интересует сравнение для вообще всех сравниваемых типов данных.

ruby, классическая Dependency Injection, пример из моего первого комментария.

Это здорово, но откуда ваш comparator знает как сравнивать эти самые о1 и о2? Откуда функция вызывающая comparator знает сколько у него входных параметров и какого типа результат? Это где-то описано или я могу в качестве comparator'a запихнуть всё что угодно?

Пример поизящнее: map-sort из elixir. Инъекция кода, изменение AST.

Откуда я знаю как должен выглядеть инъектируемый код? Сколько параметров он должен иметь? Что возвращать? Это где-то описано? Чем это описание принципиально отличается от интерфейса?
Меня не имнтересует сравнение для ограниченного набора типов данных. Меня интересует сравнение для вообще всех сравниваемых типов данных.

А это вообще все типы данных. Эрланг — функциональный язык, в нем нет «произвольных объектов». Интересует вас это, или нет (на самом деле это только демонстрирует ширину вашего кругозора), — мне фиолетово, не я просил примеров «на любом удобном вам языке и без интерфейсов».


Это уже упоминалось в дискуссии.

В дискуссии между кем и кем? Я не читаю побочные ветки, и вы совершенно не вправе ожидать от меня, что я стану тратить на это время.


откуда ваш comparator знает как сравнивать эти самые о1 и о2?

Вы его передаете при вызове метода. Передайте тот, который знает. А лучше, почитайте что-нибудь про DI в целом.


Откуда я знаю как должен выглядеть инъектируемый код?

Да вам это и не нужно, главное, что компилятор в курсе.


Что возвращать?

Код никому не обязан что-то возвращать.


Чем это описание принципиально отличается от интерфейса?

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

А это вообще все типы данных. Эрланг — функциональный язык, в нем нет «произвольных объектов». Интересует вас это, или нет (на самом деле это только демонстрирует ширину вашего кругозора), — мне фиолетово, не я просил примеров «на любом удобном вам языке и без интерфейсов».

Это здорово. То есть если кому-то нужны эти самые произволные объекты, то он должен про них забыть только потому что вам не нравяться интерфейсы?

В дискуссии между кем и кем? Я не читаю побочные ветки, и вы совершенно не вправе ожидать от меня, что я стану тратить на это время.

Ну так а я дискутирую здесь не только с вами, но и с другими людьми.

Вы его передаете при вызове метода. Передайте тот, который знает. А лучше, почитайте что-нибудь про DI в целом.

То естъ вы точно так же предлагаете «скинуть половину работы на пользователя»? Подождите, но разве это не было одним из пунктов вашей критики в сторону решения с интерфейсами?

Откуда я знаю как должен выглядеть copmarator? что бдует если я передам функцию с тремя входными параметрами, которая возвращает boolean?

Да вам это и не нужно, главное, что компилятор в курсе.

В смысле мне это не нужно? Я могу инъкетировать абсолютно что угодно и ваш пример будет работать?

Ксатати а что будет если два человека инъектируют две разные имплементации для сравнения данных одного типа? Будет ошибка при компиляции? При выполнении? Будет использоваться первый или последний?

Код никому не обязан что-то возвращать.

Как тогда узнать результат сравнения?

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

А у интерфейсов нет множества вариантов? Про абстрактные классы вы ничего не слышали? Инъекция в принципе не может работать вместе с интерфейсами?

П.С. И самое главное «простейшего метода» я так и не вижу. Я точно так же вижу достаточно сложную конструкцию, котороая точно так же сваливает кучу работы на пользователя. Да ещё и требует иъекций и/или DI.
Я не пишу на языках, которые вынуждали бы меня постоянно чувствовать себя удаляющим гланды проктологом.

То есть вы правда считаете, что иметь возможность хранить в каком-то одном списке сущности разных типов только на том основании, что у них всех есть атрибут "дата" — это нормально?

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


Так же считают авторы всех column-based и NoSQL баз данных, ивентлогов, мессаджброкеров, любого GUI, включая браузеры, и вообще примерно всего в мире софта, которым люди пользуются, а не показывают на закрытых конференциях для избранных.

Так же считают авторы всех column-based

То-то мы kdb+ обвешивали типами.


NoSQL баз данных

Ну это пока у них схема не появляется, чтобы хоть как-то контролировать всю вакханалию.


ивентлогов

Тут тоже до первой схемы для выполняемого машиной анализа логов.


мессаджброкеров

Вы бы ещё ФС назвали.


любого GUI

А с ним-то что?

любого GUI

А с ним-то что?

С ним то, что любой простой layout — это список, который в подавляющем большинстве случаев умеет разные типы.

С ним то, что любой простой layout — это список, который в подавляющем большинстве случаев умеет разные типы.

Разные типы или абсолютно произвольные типы?

Потому что по моему опыту даже в GUI у всех типов в списке обычно есть либо базовый класс, либо общий интерфейс, либо хотя бы одни и те же методы/проперти.
class Widget a where
  ...

class Widget a => TextBox a where
  ...

class TextBox a => TextEdit a where
  ...

data SomeWidget where
  MkSomeWidget :: Widget a => a -> SomeWidget

mkLayout :: [SomeWidget] -> Layout
mkLayout = ...

Хотя, может, это лучше не на тайпклассах делать, а через trees that grow-подобное в стиле


data Widget a = Widget
  { draw :: DrawFunType
  , ...
  , extra :: a
  }

data TextBoxData a = TextBoxData { .. }

type TextBox a = Widget (TextBoxData a)

и так далее (пишу из головы, гуи на хаскеле не писал никогда).

Мне второй подход симпатичнее, хотя и с тайп-классами это не так убого, как с интерфейсами в ООП.


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


Но тут, как обычно, выяснилось, что что такое «разные типы» — каждый понимал по своему: от радикального ООП от Kanut


по моему опыту даже в GUI у всех типов в списке обычно есть либо базовый класс, либо общий интерфейс

GTK, так, просто например, — написан на C. Там нет классов и интерфейсов.


до радикального type everything от вас


class Widget a => TextBox a where  ...
class TextBox a => TextEdit a where ...

А ведь почти все, например, системные утилиты в гуях — чуть ли не рефлекшеном ходят по свойствам того, что им попалось, и достают оттуда все подряд. Так в 95 венде делал EventLog (или как он там назывался) — так в современных линуксах делают графические оболочки для systemd. Чистая магия.

Тогда у вас нет сравнения самих объектов, а есть сравнение того, что возвращает условная getStartTime.

а есть сравнение того, что возвращает условная getStartTime.

Да. Но это как раз то, что нужно в данном случае.

Но это совсем не то же самое, что сравнение объектов. У вас есть какое-то отображение из множества объектов на множество дат, скорее всего, сюръективное, но точно не инъективное, и вы им пользуетесь. Вы не сравниваете исходные объекты (хотя бы потому, что, неформально, есть более «мелкое» разбиение, удовлетворяющее свойствам порядка).

Вы не сравниваете исходные объекты

Ну а для каких объектов может быть сравнение именно "исходных объектов", а не каких-то их проекций, или вообще левых сущностей? По-моему, оно остаётся таким только для целых чисел (и их проекций 1:1, вроде дат). Уже для плавучих мы имеем выбор между ordered/unordered и total.


А дальше? Точки? Можно упорядочивать по ax+by с любыми a и b, а можно ещё и проецировать на квадраты. Работников? По фамилии, имени, отчеству, номеру паспорта, ИНН, дате рождения, в любых комбинациях. Что дальше?


Вы знаете заметные классы (в смысле общего рассуждения) таких объектов, чтобы для них сравнение объектов "в себе" имело важный смысл и превосходило по значимости все альтернативные критерии сравнения?

Да хоть «пост на хабре» или, ну, вот из моего текущего проекта всё, где написано deriving (Eq, Ord) здесь или здесь.


В мапу их положить или что-то такое — вполне себе.


Вы знаете заметные классы (в смысле общего рассуждения) таких объектов, чтобы для них сравнение объектов "в себе" имело важный смысл и превосходило по значимости все альтернативные критерии сравнения?

А если их нет, то это означает, что сравнение для ваших объектов не определено. Это тоже нормально.

> А если их нет, то это означает, что сравнение для ваших объектов не определено. Это тоже нормально.

Э-кхм…

— Верно, — сказал Чапаев, с силой проводя щеткой по спутанным конским волосам, — умею. А потом как дать из пулемета…
— Но мне кажется, — сказал я, — что я и могу.
— Попробуй.
— Хорошо, — сказал я. — Я тоже задам последовательность вопросов о местоположении.
— Задавай, задавай, — пробормотал Чапаев.
— Начнем по порядку. Вот вы расчесываете лошадь. А где находится эта лошадь?
Чапаев посмотрел на меня с изумлением.
— Ты что, Петька, совсем охренел?
— Прошу прощения?
— Вот она.


вот я определил сравнение. Тут — по x, тут — по y, а тут — по порядку установки на карту.
Вот оно, определено.

> или, ну, вот из моего текущего проекта

У меня не скоро будет время грок это всё вот на неосвоенном языке, поэтому, если хотите продолжения дискуссии не через пару месяцев, то расшифруйте.
вот я определил сравнение. Тут — по x, тут — по y, а тут — по порядку установки на карту.
Вот оно, определено.

Ну это же не порядок на самих объектах, а порядок на некоторой их проекции.


У меня не скоро будет время грок это всё вот на неосвоенном языке, поэтому, если хотите продолжения дискуссии не через пару месяцев, то расшифруйте.

Я не Дедфуд, но расшифрую. deriving Ord позволяет автоматически вывести порядок для типа, если для всех его составляющих определён порядок. Сам выводимый порядок является, условно говоря, лексикографическим: два значения этого типа сравниваются покомпонентно в порядке, перечисленном в определении типа.

вот я определил сравнение. Тут — по x, тут — по y, а тут — по порядку установки на карту.
Вот оно, определено.

Нет, это не «оно». Это много разных сравнений, как тут рядом AnthonyMikh написал.


У меня не скоро будет время грок это всё вот на неосвоенном языке, поэтому, если хотите продолжения дискуссии не через пару месяцев, то расшифруйте.

Там описывается некоторый набор типов (в каждом месте, где написано data), которые вложены один в другой, так как описывают синтаксис и систему типов некоторого языка, и везде, где написано deriving (Eq, Ord, ...), компилятор выводит операции сравнения на равенство и упорядочивания.


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

С какой радости модель должна отвечать за данные, и еще немножко за сравнивание? А что если я хочу научить чужой класс сравниваться? Аспекты, рефлекшн, магия?
Если сравнение целиком и полностью определяется данными (т.е. вы уверены, что не возникнет ситуации, когда изменение логики сравнение будет вызвано не изменениями данных), то интерфейс Comparable не нарушает SRP.

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

Условно: Integer implements Comparable — это ОК. User implements Comparable — скорее всего не ок, т.к. велика вероятность что мы захотим в разных ситуациях сравнивать пользователей по разным полям, и даже сравнение по-умолчанию вполне может меняться без изменения данных.
Integer implements Comparable — это ОК

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


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

К счастью для этого у отдельных классов/типов есть CompareTo, которое опять же работает с ограниченным числом классов/типов.

То есть именно в случае с BigInteger именно этой проблемы у вас не будет:)
Вы конечно можете делать что угодно, но если мы говорим про Comparable из java, то он предназначен строго для сравнения с объектами фиксированного типа. В 99% он используется для сравнения только с объектами того же типа. Хотите чего-то более замороченного — берите Comparator, хотя и там все так себе для разнотипных объектов.
если мы говорим про Comparable из java

Нет, в этой ветке мы говорим о том, что интерфейсы в целом, равно как и Comparable из java, — никому не нужная сущность, появившаяся оттого, что авторы языка плохо умели в проектирование языков.


Джаву и шарп я как раз приводил в пример костыльного, нерабочего решения, к тому же — нарушающего SRP. Если нужно уметь сравнивать объекты только одного типа — даже простой метод на объекте, формирующий то, что умеет сравниваться из коробки (беззнаковое целое, например) — был бы уместнее (и быстрее).

Конкретно эта ветка пошла от вашего заявления, что интерфейсы (и Comparable в частности) нарушают SRP.

Но теперь я вижу, что у вас просто какое-то свое представление о SRP, ибо как можно аргументируя нарушения SRP ссылаться на рефлекшен, аспекты и перегрузку операторов я не понимаю. Это вообще ортогональные друг другу понятия.
Итерфейсы очень часто нужны для тестов или скажем если ведётся параллельная разработка несколькими командами. Тогда под них можно написать моки и спокойно разрабатывать-тестировать.
1) У вас ЯП не поддерживает моки классов?
2) Как параллельная разработка влияет? Если вы выделяете код в библиотеку и сторонняя команда её использует, то им нет разницы, SomeCoolManager — это интерфейс или класс. Это бы противоречило сути интерфейсов.
1) У вас ЯП не поддерживает моки классов?

Чтобы сделать мок класса этот класс сначала должен быть в наличии. И как бы если ещё в каких-нибудь юнит-тестах с мока работать более-менее удобно, то в остальных случая не особо.

Как параллельная разработка влияет? Если вы выделяете код в библиотеку и сторонняя команда её использует, то им нет разницы, SomeCoolManager — это интерфейс или класс. Это бы противоречило сути интерфейсов.

Как раз таки разница интерфейс или класс в таком случае очень большая. Потому что если у меня прописан класс, то я могу использовать только этот класс. А если прописан интерфейс, то я могу использовать любой класс его имплементирующий.

И проблема как раз в том что я могу «выделить интерфейс» но не дать никакой имплементации и стороняя команда уже может начинать имплементировать свои вещи ориентиpуясь на этот интерфейс. А я буду параллельно писать свою имплементацию под него.
Потому что если у меня прописан класс, то я могу использовать только этот класс. А если прописан интерфейс, то я могу использовать любой класс его имплементирующий.
Это не имеет смысла в контексте существования SomeCoolManager и SomeCoolManagerImpl, который, судя по бессмысленному суффиксу Impl, принципиально единственный наследник интерфейса, кроме моков (но тесты не должны управлять кодом). У класса уже есть интерфейс. Вы можете использовать интерфейс класса SomeCoolManager невзирая на то, есть ли там под капотом имплементация или нет. Клиентский код от этого факта абстрагирован.
Я говорю о ЯП вроде C#, Java, PHP, где где субтипизация только явная. В более структурно-типизированных ЯП с интерфейсами-протоколами как Go, Typescript, это имеет больше смысла.

В остальном, это не особо резонирует с моим опытом. Возможно, в вашей среде это имеет больше смысла (в тех интерфейсах, которые отделяются от основного кода и используются другими). Но, по моим наблюдениям, многие уже издавна стали выделять интерфейсы из классов просто потому что использование интерфейсов вместо классов само по себе ведёт к большей гибкости. Скорее к иллюзии гибкости и бесполезной церемониальности.
Это не имеет смысла в контексте существования SomeCoolManager и SomeCoolManagerImpl, который, судя по бессмысленному суффиксу Impl, единственный наследник интерфейса.

Занчит возможно в данном конкретном случае интерфейс и не нужен. Я же вроде нигде не писал что интерфейсы нужны абсолютно везде и всегда.

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

Ну лично у меня «внутри» проектов/библиотек/модулей интерфейсы используются редко. Но тут каждый сам решает для себя что ему удобнее.
Согласен, телефон мне нужен только чтобы пользоваться сервисами потоковой музыки + мессенджерами исключительно на улице. В остальном, смартфоны не считаю необходимыми.
НЛО прилетело и опубликовало эту надпись здесь
Фонарь — пожалуй, самая популярная функция
Банковское приложение
Калькулятор
Программа для распознавания растений
Мобильный планетарий
НЛО прилетело и опубликовало эту надпись здесь
мой список


1./2./3./4. и 7. — да
Для создания заметок использую OneNote, он сейчас отлично синхронизируется с десктопной версией, а возможностей у него выше крыши.

Из неупомянутого — офис (в основном — просмотр документов), сканирование/распознавание, почта, калькулятор, мобильная точка доступа, читалка, погода, банковское приложение, фонарик и казуальные игры.
НЛО прилетело и опубликовало эту надпись здесь
Калькулятор, фонарик и погода — согласен


По роду работы есть необходимость сканировать и распознавать фрагменты текста.
Наиболее удобный для этих целей инструмент — смартфон.
По востребованности у меня это фича номер один (после основных функций телефона, естественно :) А уже намного потом — калькулятор, фонарик и погода.
Вот да! Но буквально все производители смартфонов считают иначе. Они делают их так, как будто это будет твоё основное или даже единственное устройство для всего на свете, включая, например, просмотр видеоконтента. А я вот не могу смотреть видео на телефоне — хочется «нормальный экран», который не нужно держать в руках.

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

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

Запускаю ютуб раз в полгода, когда кто-то что-то скидывает посмотреть.
Искренне не понимаю, как можно смотреть ютуб и сериалы с телефона, когда есть нормальный полноразмерный монитор.
Да, или когда в гостях и хочу кому-то что-то быстро показать, а комп или другое более подходящее устройство далеко.

В слове "телевизор" много ошибок. Смотреть что-либо из видеоконтента гораздо удобнее с 1.5м+ телевизора.

Я тоже далеко не Чигначгук-зоркий глаз :)
Телевизор (или кресло от него) нужно ставить на минимально-допустимое расстояние. Была статья на хабре с табличками и графиками. Если поставить 1.5м телек в 5 метрах от зрителя, то толку никакого не будет, конечно.

это же пережиток прошлого — времени, когда IDE не умела их подсвечивать. Теперь умеет, префикс летит на свалку истории.
нейминг должен быть нормальным без IDE, и тут дело не в телефонах
Это самой собой, но как связаны «нормальности нейминга» и наличие в имени информации о том какой тип единицы компиляции назван этим именем? Тем более, что во многих языках разница между абстрактным классом и интерфейсом очень зыбкая.

А то так можно и венгерскую нотацию тащить везде и всюду.
Смартфон нынче штука в жизни близкая к трусам — без него и в доме-то находиться сложно, не то, что из него выйти. И тренд на увеличение мобильной разработки тоже присутствует. Все это понятно, логично, в некоторой мере даже эволюционно — то, что сейчас можно делать со смарта, десять лет назад даже насчет офиса Сбербанка сомневался бы, что получится.

Что реально печалит — это попытка сэкономить на реальной разработке под десктоп под видом «унификации внешнего вида». Когда пытаешься установить десктопное приложение, и понимаешь, что то, что ты поставил — сбитое в кучку то самое мобильное приложение с минимумом функциональности, добитое Электроном с целью запуска на десктопе. Когда понимаешь, что полная функциональности и настроек различного уровня сложности понимания и кастомизации Панель управления, существовавшая в Windows с 1993 года, вымирает и заменяется свистоперделками из «Настроек», не имеющих и десятой части того уровня кастомизации, который был доступен раньше.

Да, порог вхождения в смартфоны и современные ПК понизился, и новая аудитория — уже не те энтузиасты, которые были готовы разбираться со всем подряд на протяжении 30 лет. Понимаю, что тренд на упрощение не просто так появился. Но общий подход «пользователь — дурак, мы сами за него все порешаем» уже лет 7-8 как заставляет меня грустить…

А еще — хотите оставить минимум функциональности, так оставляйте, хрен с вами. Но, черт побери, зачем, зачем на 4к экраны размером 28-32 дюйма тащить интерфейсные решения, принятые для 5.2'' смартфонов? Почему нельзя пользоваться API, обеспечивающими стандартный вид, соответствующий операционной системе?
В скором будущем мне видится возврат к декстопам. Только это будет виртуальный монитор(два/три) в AR/VR очках.
Присел на лавочке в парке, повесил виртуальный монитор перед собой, раскладная клавиатура на колени и в бой.
Боюсь, с современным трендом на голосовые помощники и отказ от текста, как бы не вышло, что через 10 лет мы будем надиктовывать код голосом. А вместо IDE будет какая-нибудь Алиса, через команды которой и придётся работать с кодом. И все будут ругаться, плеваться, но всё равно пользоваться, потому как под новые платформы ничего другого просто не будет.
, что через 10 лет мы будем надиктовывать код голосом.


Такие прогнозы делались с конца 90х, а воз и ныне там :)
Вспоминается одна из серий Lawrenc E. Dahners, там недалекое будущее но один из признаков действительно хорошего программиста — именно что работа с клавиатуры.
При этом все что бы сейчас назвали компьютером/планшетом/etc — называется «AI» и имеет и голосовое управление (и часто только его), если вычислительный блок (возможно удаленный) реально мощный — то там далеко не Алиса по интеллекту.
Ну не знаю, думаю что навряд ли. Учитывая то, что голосовой ввод — далеко не самая удобная вещь. Тебя слышат посторонние, лишний раз напрягать голосовые связки нужно, проговаривать команды определённым образом. Да и постоянная необходимость говорить не способствует рабочей обстановке
Через 10 лет вероятно уже будут первые рабочие прототипы нейроинтерфейса для прямой работы с 2/3D графикой.
На счёт кода не знаю, т.к. человек не машина, но мысленный набор плюс выделение кода по взгляду(для копирования/исправления), могут заметно поднять скорость работы.
А голосовое управление/набор текста уже сейчас показал свою без перспективность, как минимум в виду того что слышат другие.
Идея что мы будем чтото говорить висит в воздухе более 20 лет, со времен Dragon dictate. И чтото мне подсказывает что все разговорные интерфейсы будут такими же обрезками как и мобильные