LINUX.ORG.RU

Именование объектов и их семантический смысл.

 , , ,


0

2

Я хочу немного поныть на эту тему:) В современном программировании, имеет место извращенность. Практически не найти фреймверка, библиотеки или чего бы то ни было, где имена действительно осмысленны. Вот пример. В nodejs мы вот так вот запускаем сервер

http.Server(listener).listen(port)
Давайте попробуем описать словами, что действительно происходит *семантически*.

создается объект сервера, ему присваивается метод (listener), который дергается каждый раз, когда дергается сервер (приходит запрос). метод listen присваивает этому объекту значение порта.

А у нас что такое Server? Де факто — это метод скрытого объекта, который сеттит слушателя этому объекту. Тогда почему не setListener? Науке это неизвестно. Раньше было createServer, хоть тоже дерьмо, но хот какой то смысл несет. Сделали еще хуже.

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


server = new Server // or Server.create()
server.listener = listener
server.port = port
server.startListen()

Лично я, когда я разбираю лапшу такого рода, я все равно разворачиваю первый вариант во второй. За этим говном, во первых, теряется связь кода и его смысла, во-вторых, вуалируется семантика сообщений (то есть, такой код можно назвать ООП - кодом лишь с натяжкой), в третьих, мы не видим архитектуру, непонятна абстракция (eg в данном примере неясно, является ли port свойством подковерного объекта сервера или какого то коня в вакууме, который там сбоку припека)

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

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

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

Почему так? Что делать? Кто виноват?

server.port = port

Молодец, а теперь заставь его слушать несколько портов.

x3al ★★★★★ ()

Анонимус стал совсем унылым.

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

with

nodejs

С ума сошёл? Оно ТОР-МО-ЗИТ.

addPort

И чем оно лучше, чем listen()?

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

Да не обязательно with, это просто сокращенная запись server.setPort(port1); server.setPort(port2). Вариант не единственный, можно было бы и serversetPorts(ports)

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

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

И чем оно лучше, чем listen()?

тем что видно, что такое port, какому объекту назначено. Короче тем, что имеет смысл

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

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

Если я правильно помню, как это обрабатывается — with делает обращения к переменным во всём scope, где он стоит, дороже. То есть ты замедляешь всю функцию (и заодно вложенные функции), где этот with расположен. Плюс теряешь возможность юзать strict mode. Ну и ставишь себе мину: если в объекте появятся свойства port1/port2, тебя ждёт очень весёлый дебаг.

serversetPorts(ports)

Лучше map'нуть listen() на ports.

Плюс я нифига не понимаю, почему ты хочешь наследования в JS. Оно тут нафиг не нужно.

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

И чем оно лучше, чем listen()?

Вот этому вот объекту ты отсылаешь сообщение listen.


console.log(require("http").Server(function(){}))

//>>>> { domain: null,
//>>>>   _events: 
//>>>>    { request: [Function],
//>>>>      connection: [Function: connectionListener],
//>>>>      clientError: [Function] },
//>>>>   _maxListeners: undefined,
//>>>>   _connections: 0,
//>>>>   _handle: null,
//>>>>   _usingSlaves: false,
//>>>>   _slaves: [],
//>>>>   allowHalfOpen: true,
//>>>>   pauseOnConnect: false,
//>>>>   httpAllowHalfOpen: false,
//>>>>   timeout: 120000 }
//>>>> 

Он от чего-то, стало быть наследует его. Поди разберись тут.

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

with делает обращения к переменным во всём scope

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

Оно тут нафиг не нужно.

LOL

newquestion ()

(напишу, как предполагаю, точно это API не знаю)

http.Server это конструктор объекта. listener это параметр конструктора. В конструкторе обычно перечисляются те поля, без которых существование объекта не имеет никакого смысла.

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

В твоём варианте всё смешивается в одной сущности. Это каша, такой вариант однозначно хуже.

Legioner ★★★★★ ()

так в чем вопрос?

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

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

Нет. Без with на этапе лексинга scope полностью определён. C with — фиг тебе, все оптимизации доступа к scope псу под хвост и вся эта работа происходит в runtime. Потому, что до runtime ничерта не известно, где находится

addPort

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

http.Server это конструктор объекта.

Тогда почему не new http.Server? И посмотри на код выше, где я вытащил этот экземпляр наружу. Там даже нет этого метода. Так что, это не конструктор, а ЁНХ.

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

Без with на этапе лексинга scope полностью определён

Это ты про лексический скоп говоришь. With тут не при чем. Да и то, непонятно, как он может быть определен, если никто не мешает его менять в рантайме.

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

Ну вообще логично через new делать, но тут уже проблема JS — в нём кто как хочет, тот так и городит объектную систему, единого каноничного способа нет (разве что в ES 6 будет).

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

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

Полностью определён при условии, что в коде нет:

  • with
  • eval (за некоторыми исключениями: в strict mode, например, можно)

То есть в 100% современного кода, написанного вменяемыми кодерами, и в 99.99% всего реально встречающегося в вебе кода. Именно этот частный случай и оптимизирован в каждом движке.

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

with

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

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

Полностью определён при условии, что в коде нет:

Представь себе вот такой код

someButton.onclick = function(counter){
  return function(){counter++}
}(0)
Как компилятор будет определять содержимое скопа (в данном случае — значение пер-нной counter), если оно зависит от действий пользователя?

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

Ему не нужно значение. Ему нужно знать, где искать этот counter.

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

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

Ты можешь явно задать контекст и лукап сократится

А теперь прочитай ту ссылку.

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

А теперь прочитай ту ссылку.

У меня после вот таких вот фраз,

using full-featured variable access into JavaScript that doesn’t, rather like how the original C++ compiler

отпадает желание продолжать. Он хочет кастрировать JS до уровня плюсов?

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

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

Представь себе что ты живешь в городе N, а в пяти километрах от тебя расположен город X. Ты можешь решить, что путь до этого города лежит через Нью-Йорк. Сначала ты выясняешь, по какой стороне планеты тебе ближе добраться, затем думаешь, как лучше добраться, каким транспортом. Поезда и пароходы ты сразу отметаешь, выбираешь самолет. Затем добираешься спустя сутки, и обнаруживаешь, что твой друг уже дошел туда пешком. Самолет летает быстро, но он неуместен.

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

newquestion ()

Я хочу немного поныть на эту тему:) В современном программировании, имеет место извращенность.

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

Весь этот апи отражает работу именно стека, а не твоих «понималок».

Все остальные твои «печали» и «внутренний транслятор» олсо от отсутствия «понималки», а только «хотелки».

ЗЫЖ как там круг поживает?

anonymous ()

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

В основном это: существительные, глагола, прилагательные.

Если например провести «семантический» анализ имен в jquery, то кроме односложных и распространённых слов там ничего нет. И это правильно.

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

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

Нихера там не правильно. Например $(element).html("<p>foo</p>") должно быть get(element).setInnerHTML("<p>foo</p>"). Экономят, суки на спичках, а потом в 2-х соснах путаются.

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

Нормально все, так и надо.

Такая экономия оправдана. Поведение предсказуемо. Упрощения рулят.

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

Упрощения рулят.

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

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

Нормально все там. Кому как. Мне например более комфортный такой нейминг.

И сокращения вполне оправданы. Главное чтобы не сокращали так:

stInnrHT

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

Извиняюсь за некрофильность, но не удержался, вопиющая несправедливость, анонимус, вы опять Io двигать пришли? =)

Например $(element).html(«<p>foo</p>») должно быть get(element).setInnerHTML(«<p>foo</p>»).

JS это язык, в котором можно передавать множество параметров и самых разных типов. Ваш КО. obj.html() - без параметров вернет вам html-код внутри элемента, с параметром - установит. (а еще туда можно передавать даже функцию, да да! :D)

По вашей логике, назовем метод setOrGetOrDoSomethingAndReturnInElement тогда? (при учете что мы хотим сохранить один метод, а не писать целых три) Хотя я все забываю что вы поклоняетесь Io, поэтому вам сложно понять, что так тоже бывает=)

Экономят, суки на спичках, а потом в 2-х соснах путаются.

Как раз такое наименование и не дает нормальным людям запутаться в 2-х соснах.

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

не буди мертвых. этож анонiмус, тот самый.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.