LINUX.ORG.RU

паттерны для правильного (и типизированного) JavaScript

 ,


0

3

Навеяно горячими стримами Мурыча. Я вот задумался: а ведь действительно, можно обойтись без TypeScript, если придумать удобные паттерны для JavaScript. Не хватает двух вещей:

  • Типизации на входе и на выходе, внутри тел функций и у констант она избыточна.
  • Интерфейсов. Для классов можно использовать наследование, но для объектов уже надо думать над валидаторами.

Без остального сахара можно обойтись.

Первое можно решить с помощью optional, как в Java. Можно написать один обработчик для всех типов (с методами getString, getInt и т. д.), или разные. Привязать к синглтону, чтобы мочь глобально отключать проверки в рантайме (например, по флагу в env). Так мы получаем удобные подсказки в редакторе и работающую проверку типов.

Вот с интерфейсами для Object / Array / Set / Map сложнее. Думаю, нужно поэкспериментировать с optional, чтобы на выходе тоже дёргались типизированные методы.

А чтобы получить типизированные интерфейсы для классов, просто наследуемся от типизированного родителя: где на входе и выходе методов optional, а тело просто делает throw new Error('not implemented').

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

Хочется изобрести рабочую методологию для написания больших и запутанных проектов, а не использовать костыли вроде TypeScript. Это не кажется невозможным. Или может она уже есть, а я о ней не знаю? Из известного нравится подход Тимура Шемсединова: чистый JS с *.d.ts декларациями. Но это не совсем то.

★★★★

Последнее исправление: InterVi (всего исправлений: 2)

Ответ на: комментарий от alysnix

Так вы сами привели пример и сами его отбросили.

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

Ну держите ещё один: профилирование. Например профилирование использования памяти приложением для поиска узких мест и оптимизации.

Могу привести ещё несколько, но похоже что Вы настроены их всех отвергать и говорить что это не входит в «иногда без интроспекции не обойтись».

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 2)
Ответ на: комментарий от Obezyan

Могу привести ещё несколько

хорошо бы.

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

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

alysnix ★★★
()
Ответ на: комментарий от Obezyan

зачем в с++, с вполне себе статическими темплейтами, где класс инстанцируется во время компиляции юнита, РАНТАЙМ информация каких-то прочих классах?? причем всю эту рантайм инфу компилятор и делает своими руками и запихивает в обьектный файл.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

зачем в с++, с вполне себе статическими темплейтами, где класс инстанцируется во время компиляции юнита, РАНТАЙМ информация каких-то прочих классах?

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

И вообще, интроспекция довольно важна, т.к. в C++ нет настоящей рефлексии как в Java или C#, потому она отдувается «за себя и за того парня».

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

Obezyan
()
Ответ на: комментарий от Obezyan

паттерн «стратегия» реализуется на с++ прямо в лоб, на виртуальных функциях, вообще без каких либо шаблонов и рефлексии тем более.

https://www.geeksforgeeks.org/strategy-method-design-pattern-c-design-patterns/

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

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

Как я и говорил, Вы и дальше будете отнекиваться. Какой смысл продолжать Вам что-то объяснять?

Obezyan
()
Ответ на: комментарий от Obezyan

Какой смысл продолжать Вам что-то объяснять?

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

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

карочи, давайте паттерн, что В ПРИНЦИПЕ не может быть реализован без интроспекции.

alysnix ★★★
()
Ответ на: комментарий от alysnix

карочи, давайте паттерн, что В ПРИНЦИПЕ не может быть реализован без интроспекции.

Вы видимо перепутали интроспекцию и рефлексию. Интроспекция — это способность программы исследовать тип или свойства объекта во время работы программы.

Соответственно, все паттерны, в реализации которых требуется проверка класса, тот самый instanceof в других ЯП, не могут обойтись без интроспекции.

Obezyan
()
Ответ на: комментарий от Obezyan

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

с рефлексией найти паттерн принципиально нереализуемый иным способом будет еще трудней.

Конечно, ведь в С++ нет рефлексии вообще.

интроспекция - есть подмножество рефлексии

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

Obezyan
()
Ответ на: комментарий от Obezyan

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

терминологический спор. «является подмножеством» и «построена на» - не суть важно в данном случае.

alysnix ★★★
()
Ответ на: комментарий от Obezyan

раскроем компетентные источники на странице - рефлексия.

https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%84%D0%BB%D0%B5%D0%BA%D1%81%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)

и обратим внимание на абзац.

Отражение (рефлексия; холоним интроспекции, англ. reflection) — процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. Парадигма программирования, положенная в основу отражения, является одной из форм метапрограммирования[1] и называется рефлексивным программированием. 

где применена связка - «холоним интроспекции».

открываем авторитетный источник на странице -

https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%80%D0%BE%D0%BD%D0%B8%D0%BC_%D0%B8_%D1%85%D0%BE%D0%BB%D0%BE%D0%BD%D0%B8%D0%BC

где читаем -

Холо́ним (др.-греч. ὅλος = «целое» + ὄνομα = «имя») — понятие, которое является целым над другим понятием или их множеством (то есть другое понятие предстаёт в качестве составной части первого).

сопоставляем полученные знания из авторитетных источников

рефлексия; холоним интроспекции,...

с моим высказыванием

интроспекция - есть подмножество рефлексии

и делаем положительное умозаключение об их эквивалентности.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

потому что, чтобы нарушить или оспорить столь фундаментальные принципы

Сектант, в чём они фундаментальные, что их нарушать нельзя? Тебе просто сказали «так надо» и ты повторяешь, вообще не понимая, почему так надо и зачем?

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

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

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от Obezyan

Вы сейчас описали довольной большой кусок С/С++ проектов.

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

Мне иногда кажется, что у многих программистов на С и С++ какая-то ментальная травма от указателей и смещения адресов в памяти.

Оно-то может и оправданно, когда задачу надо решать за 0,5мс, а не за 4мс. Но в прикладной области это совершенно не имеет решающего значения. Зато имеет значение сложность внесения изменений. А еще было бы не плохо хорошо понимать, что происходит в системе и какие где данные гуляют прямо во время работы этой системы, а также что-то делать с этим структурами на ходу, когда все пойдет не по плану, а оно обязательно так и пойдет.

crutch_master ★★★★★
()
Ответ на: комментарий от alysnix

иногда, это когда?

Она всегда нужна. У тебя что-то идёт в системе не так. Данные не те приходят, результаты каких-то операций не такие, как ожидались и т.д. Надо разобраться, а тут ой, у нас же все инкапсулированно, что же делать? Как же нам теперь разобраться, почему вся эта ооп сранина на 1М строк начала не так работать? Как же восстановить стейт системы на вчера в 11 вечера? Как же нам теперь поможет ооп религия? Какой паттерн надо было применить? Кто же нас теперь спасёт?

crutch_master ★★★★★
()
Ответ на: комментарий от alysnix

вся эта дискуссия вообще не нужна

Вот именно. Ты тут не нужен со своим ооп и ковырянием иголкой в жопе.

правильно закрытого класса - это прямое нарушение инкапсуляции

Подай на нас в суд.

и знает его в точности только тот, кто этот класс писал или сопровождает

У тебя оопэ головы еще и довесом к плюсам головы. Есть множество способов организовывать код на высоком уровне, вокруг оопэ/ст дрисни мир не крутится.

crutch_master ★★★★★
()
Ответ на: комментарий от alysnix

делают сеттеры-геттеры, к тем полям, к которым нужен доступ.

И чем пустой сеттер/геттер отличается от присваивания? Кек. Вы зомбы религизоные делаете это просто потому, что кто-то сказал, что «так надо». А по сути это ничем не отличается от структуры с public полями.

то есть никто не применяет мэпперы

Что у вас там принято всё делать руками, это мы поняли. Циклы надеюсь научились писать? Если вам n раз надо сделать операцию, вы же не n раз пишите код?

потому что чел делает глупости и гордится этим.

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

сделано это не с бухты-барахты

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

он что предлагает? открыть все внутренности и сделать какие-то «мэпперы»

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

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crutch_master

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

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

alysnix ★★★
()
Ответ на: комментарий от crutch_master

И чем пустой сеттер/геттер отличается от присваивания?

даже в тривиальном виде он не пустой, а тупо присваивает или возвращает значение.

преимущества.

  1. имя переменной с которой он работает - не фиксировано и может быть изменено.

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

  3. код сеттера/геттера может быть изменен так, что будет проверять инварианты, вести логи, проверять корректность доступа, обеспечивать thread safety и прочее богатство фантазии.

  4. сеттер/геттер не дает возможности получить адрес переменной и передать его куда-то.

если вам это сходе непонятно, то зачем вы вообще в профессии?

alysnix ★★★
()
Ответ на: комментарий от crutch_master

Сектант, в чём они фундаментальные, что их нарушать нельзя?

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

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Инкапсуляция - это защита от дурака, чтобы тот сам себе не выстрелил в ногу. Коммандная разработка, кровавый интерпрайз - все дела. Тож самое с интерфейсами. Главный петух сидит их в каком-то редакторе рисует uml, потом генерит код интерфейсов, а его макаки - их реализуют… В js и без инкапсуляции нее обходились с _, а потом появились Symbol и приватные свойства… С интерфейсами идея была понятна, но не прижилась… Ну все это излишне. Когда у тебя в конторе два фронта и три бекендера… Ну два-три человека и так скоординируются, избыточная сложность… Да, я понимаю что во всем есть какой-то глубинный смысл, но ведь большинству оно не нужно

rtxtxtrx
()
Ответ на: комментарий от rtxtxtrx

Инкапсуляция - это защита от дурака, чтобы тот сам себе не выстрелил в ногу.

неполно. защита от дурака в том числе. но, вы же запираете сарай с мопедом не от дурака?

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

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

сеттер позволяет вам и просто динамически запрещать изменение внутреннего состояния, а также, например, проверять права на вызов сеттера(типа не все треды могут вызывать сеттер, в зависимости от прав треда/режима секурности и так далее).

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

открытые поля и прямая с ними работа - это нубство на уровне первых шагов.

alysnix ★★★
()
Ответ на: комментарий от alysnix

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

rtxtxtrx
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

rtxtxtrx
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от rtxtxtrx

Мартин ни сном ни духом. Это был запрос от лисперов. Но куда тебе. Ты же дебажишь с её помощью. Люди разучились и ссут писать «ЙА не знаю, расскажи». Если ты скажешь, что не знаешь и хочешь узнать - на тебя упадёт холодильник и появится на лбу позорная несмываемая метка, мой яркий представитель дебилов.

Человек, навернувший (что мало вероятно, просто слышал) Дядю - почему DI завернули в контейнер? Но куда тебе ответить, ты же не писал ничего.

anonymous
()
Ответ на: комментарий от anonymous

Кого я дебажу? Что за вздор? Какой позор? Зачем мне на каждый чих лепить сервисы? Причем тут вообще депенденси инжекшон? Напоминаешь ты мне царя или тот покусал тебя

rtxtxtrx
()
Ответ на: комментарий от rtxtxtrx

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

Кого я дебажу? Что за вздор? Какой позор?

И ты не ссышь писать в develop. Ты же не только обоссался, так ещё и срёшь в прямом эфире, Царя всуе вспоминая. Ничё, пока такие лохи есть в индустрии, будем косить нормально денёг. Главное - продолжай. Я тебе припишу к Нику - «ссыкунец-developer».

anonymous
()
Ответ на: комментарий от rtxtxtrx

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

И главное, что обосравшись на ЛОР, ты даже не можешь перестать отвечать анонимусу, бездарный ссукунец, продолжая разбрызгивать фекалии безграмотности вокруг.

anonymous
()
Ответ на: комментарий от alysnix

раскроем компетентные источники на странице - рефлексия.

Вот второй «специалист» подъехал, приводящий не создателя этого выражения, а Wiki, как сурьёзный источник. Чай не 1000 лет назад и не на древнегреческом, а на молодёжном английском. Это тред переписи не осиливших.

anonymous
()
Ответ на: комментарий от anonymous

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

rtxtxtrx
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)
Ответ на: комментарий от alysnix

какого еще выражения создателя?

Понятие рефлексии ввёл, если я не ошибаюсь, дохтур Brian Cantwell Smith в 1982, в своей диссертации «Procedural reflection in programming languages».

Для ознакомления.

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

masterOf
()
Ответ на: комментарий от rtxtxtrx

Тебе выше написали, Царём здесь и не пахнет. Аноним сагрился на вот это выражение

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

И я анонима поддерживаю.

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

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

masterOf
()
Ответ на: комментарий от masterOf

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

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

это все скорей из области ИИ, чем реальной конкретной практики.

не, ну понятно что взяв такой рефлексивный компилятор фортрана можно его рефлексией превратить в компилятор с++ 20. а то и 26.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Не. Тут попытка Lisp запузырить в C. Идея оказалась непростой, надо наворачивать избыточно кода. Что даёт? Гибкость. Как побочный эффект можно всё узнать о классах, либах, API. Обработать и запустить. Некий всеядный интерфейс.

Есть видосы применения в OOP. Но опять же, надо разбираться как минимум в ООP (а ещё лучше смотреть видосы c Alan Kay) и тогда ты понимаешь плюсы и почему в ЯП есть этот набор библиотек - Reflection.

anonymous
()
Ответ на: комментарий от alysnix

даже в тривиальном виде он не пустой, а тупо присваивает или возвращает значение.

Это и есть пустой, потому что он нихрена не делает.

имя переменной с которой он работает - не фиксировано и может быть изменено.

И getA вернёт b, гениально, а главное просто и понятно. А самое главное, он почти наверняка изменен не будет в большинстве объектов. Но геттеры делать надо ради геттеров и похер, что этот объект используется один раз, а дальше про него забивают. А мало ли, надо наделать геттеров, гетторы сами себя не наделают.

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

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

код сеттера/геттера может быть изменен так, что будет проверять инварианты, вести логи, проверять корректность доступа, обеспечивать thread safety и прочее богатство фантазии.

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

сеттер/геттер не дает возможности получить адрес переменной и передать его куда-то.

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

если вам это сходе непонятно, то зачем вы вообще в профессии?

Кек. Ооп догматик рассуждает о том, кому что делать в профессии. Ты все равно, что деревенский поп, который пытается в науку.

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

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

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)