?

Log in

No account? Create an account
Белые слова [KAPACb] [ДАЖДЬ] [Анти-Синтон] [Фото] [TheQuestion] [DomEconom] [Ticketland] [ВКонтакте] [FaceBook] [Спрашивалка] Below are the 10 most recent journal entries recorded in the "Сервер не найден" journal:

[<< Previous 10 entries]

December 27th, 2017
12:17 pm

[Link]

Паразитная функциональность
https://www.gazeta.ru/science/2017/12/26_a_11545316.shtml

У автобусов ЛиАЗ-5292 есть защита от езды с закрытыми дверями. Эта полезная штука порождает опасный обратный эффект: можно использовать открытую дверь как состояние органов управления, в котором автобус не едет, но тогда он может неожиданно тронуться при закрытии двери.

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

Tags:

(Leave a comment)

December 19th, 2017
05:55 pm

[Link]

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

Вы думаете, так не бывает? А ведь сами всё видели. Бывает даже, что оба охотника из одного племени.

Tags: ,

(Leave a comment)

November 17th, 2017
11:17 pm

[Link]

Гипотеза

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

Прямо как субдоминанта-доминанта-тоника (кстати, первый пример).

С детства такое вижу: мой радиус метро кончается станциями Измайловская-Первомайская-Щёлковская, потому здесь такое уютное место. До 2003 года другой конец линии был Арбатская-Смоленская-Киевская, теперь такие кадансы надо искать в других местах: Борисово-Шипиловская-Зябликово. А другие примеры?

Труба, валторна, тромбон, туба.
Июнь, июль, август.
Cреда, четверг, пятница
.

- ну и что, что не по официальному календарю, конец в самом приятном месте.

Ещё примеры?

Tags:

(2 comments | Leave a comment)

September 8th, 2017
10:26 pm

[Link]

из фейсбука, но и тут уместно
флешмоб

10 утверждений про меня, ровно два из которых неправда.

1. я ни разу не пил пива
2. на моей гитаре однажды играл Сергей Калугин, а она была расстроена
3. единственную единицу в школе я получил за невыученные стихи, а один раз получил пять в четверти по физкультуре
4. один раз я перевёл фильм
5. из всех предметов одежды, которые я носил, самый большой эффект на окружающих произвела бирюзовая футболка
6. однажды я провел консультацию перед экзаменом в парке
7. у меня дома лежат топор, две шляпы и солонка, которые я все забываю отдать
8. однажды я публично играл на ударной установке
9. раз в две недели я не сплю всю ночь
10. я могу нарисовать схему Московского метро по памяти

Tags:

(1 comment | Leave a comment)

July 23rd, 2017
12:24 am

[Link]

Несколько мыслей о выразительности
1. Симметрия (и ритм как переносная симметрия), да и всё прямое и ровненькое, радуют глаз и восхищают во всём, кроме программного кода. Повторяемость конструкций вызывает подозрение, что какие-то из них лишние и надо использовать одну за всех.

2. Выразительность в программировании делится на "ясно, зачем это" и "ясно, как". Крайний пример второго - язык ассемблера, где каждая строчка делает понятно что, но в реальной программе теряется в дебрях структуры (а всё выглядит ровненько-ровненько, см. п.1). Крайний пример первого - почему-то тестовые библиотеки, такие, как mockito и scalatest: конструции вида when(a.isCalled()).thenReturn(whatIsNeeded) выглядят почти как связный английский текст, но поди сразу пойми, какие методы каких классов тут вызываются и какие объекты выдают. К счастью, взаимоисключение неабсолютное, языки развиваются с улучшением обеих выразительностей. Но какой код легче переиспользовать? Если первый раз видишь и нет описаний, то легче выразительный "как": очень часто бывает, что скопируешь вроде как понятный выразительный "зачем" кусок, слегка переделаешь для новой задачи и потом долго тупишь - а почему он не работает. А вообще - конечно, он лучше.

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

Tags: ,

(2 comments | Leave a comment)

July 9th, 2017
10:04 pm

[Link]

Урбанистиха
в фейсбуке уже былоCollapse )

Tags:

(Leave a comment)

June 30th, 2017
01:44 pm

[Link]

Про рефакторинг
Что меня смущает в порядке рефакторинга, предложенном Фаулером:

1. Подход "сначала реализуй самым тупым способом, потом чисти код". Ну есть же принцип RefactorFirst. Рефакторинг для того и нужен, чтобы вносить изменения было проще - соответственно, вносить изменения надо тогда, когда система к этому готова. Можно, конечно, расчитывать на то, что код стал чистым после предыдущей итерации, но, во-первых, так не всегда получается, во-вторых, само понятие "чистоты кода" не абсолютно, а зависит от тех изменений, к которым код должен быть готов: соответственно, с появлением новых требований код может перестать быть "чистым" (а в коде, готовом к изменениям, которых не будет, может быть ради этих изменений много лишнего).

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

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

Tags:

(4 comments | Leave a comment)

June 7th, 2017
10:30 pm

[Link]

Вынь пробку!
Юность прошла, диплом не прёт, с работой, похоже, мрак,
Вокруг кто спит, кто верит, кто врёт, кто фашист, кто просто дурак.
Интеллигенции не привыкать – неважно, где и когда.
Вынь пробку! Вынь пробку, там – ерунда.

По цепи намёков найдёшь за углом средь чучел и света луны
То ли новый ООН за круглым столом, то ли сходку местной шпаны.
Ты плохо знаешь, чего хочешь сам, но вдруг есть у этих ребят?
Вынь пробку! Вынь пробку, тебе говорят!

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

И ты получаешь последний фант, и что говорить о судьбе,
С глупой улыбкой везёшь чемодан, а там не твоё, не тебе.
А ты не стесняйся подумать: а что там? Вдруг там бомба иль яд?
Вынь пробку! Ещё не поздно назад!

Если долго смотреть на то, что висит, оно треснет тебя по лбу.
Если считать, что всё уже сыграно, кто тебе даст трубу?
Останется только встать в полный рост перед адским котлом, проорав:
- Вынь пробку! - И в этом ты будешь прав.

Tags:

(Leave a comment)

April 2nd, 2017
01:35 pm

[Link]

Типы и "происхождения" значений
Или вот ещё такой философский вопрос по стилю.

Можно написать так:

...
String name = foo.name;
method(name);
...
public void method(String fooName) {
  ...
}


А можно так:
...
method(foo);
...
public void method(Foo foo) {
  String  fooName = foo.name;
  ...  
}


Недостаток второго подхода в том, что метод method "слишком много знает" об объекте foo. Но зато:

  1. Мы на уровне компиляции уверены, что метод выполнится именно для Foo.name, а не какой-то другой строки;

  2. Если данные, хранящиеся в Foo.name будут храниться как-то по-другому - в двух отдельных полях Foo или вообще вне объекта - менять сигнатуру метода method не придётся.

Первого можно бы было избежать, если бы объекты/значения в языка маркировались бы не только типом, но и "происхождением". Радикальным вариантом было бы введение для каждого "происхождения" отдельного типа:
class FooName {  // жалко, что нельзя extends String
  public final String string;
  public FooName(String s) {
    this.string = s;
  }
}
...
class Foo {
  public final FooName fooName;
...
}
...
method(foo.name);
...
public void method(FooName holder) {
  String  fooName = holder.string;
  ...  
}


Но как-то нехорошо иметь слишком много классов. В каком-нибудь новом языке для этого есть синтаксический сахар?
И (2) это тоже не решает.

Tags:

(Leave a comment)

December 10th, 2016
08:12 pm

[Link]

ООП умирает

Три важных и хороших принципа объектно-ориентированного программирования гласят:


  1. Используйте полиморфизм вместо условий

  2. Разделяйте слои

  3. Не устраивайте параллельных иерархий

Реально воплощаемы только какие-то два принципа из трёх, оставшимся придётся поступиться. Вот традиционный пример:

if (a instanceof AClass) {
  doSomething(a);
} else if (a instanceof BClass){
  doSomethingElse(a);
}

Что нам советует классическоее ООП? Заменить условие полиморфизмом, засунув различное поведение внутрь классов:



a.doSomething();

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

commandMap.put(AClass, a -> doSomething(a));
commandMap.put(BClass, a -> doSomethingElse(a));
...
commandMap.get(a.getClass()).accept(a)

что, вообще говоря, уже дублирует иерархию, да и выглядит не сильно лучше исходного.

Объектно-ориентированное программирование умирает. За последние десять лет все просят - и получают - всякого перевоплощения и развития функционального программирования, будь то лямбда-исчисление, замыкания и цепочки фильтров, либо какого-нибудь "программирования, ориентированного на данные", а объектная ориентированность - уходит. Типичный веб-проект состоит из объектов модели, в которых весь функционал - геттеры и сеттеры, почти старые добрые записи из Паскаля, и нескольких слоёв репозиторий, сервисов, контроллеров, адаптеров, которые все stateless и по сути являются наборами функций.

Чуда не случилось. Пускай имеется в наличии компонента с открытым исходным кодом, которая ведёт себя почти так, как нам нужно, за исключением одной строчки - и не в методе, который мы вызываем, а где-нибудь в седьмом-десятом слое по глубине вызова. "Не надо переписывать, можно унаследовать"? ООП чуть ли не обещает нам это, но реально мы можем что-то такое сделать, только если создатели компоненты такое заранее предусмотрели; а если бы сам язык это предусматривал, это будет очень непохоже на "наследование" - это будет тот самый monkey patching со всеми его недостатками.

Что после всего этого будет - не знаю.

Tags:

(7 comments | Leave a comment)

[<< Previous 10 entries]

KAPACb Powered by LiveJournal.com