Tips&Tricks

Распечатка доклада в Харькове

декабря 5, 2014  |  Published in Best Practices, Tips&Tricks, Новости, Уголок философа

Подготовил доклад для встречи организуемой DataArt в Харькове: «Философия систем сквозь призму разработки ПО», но, увы, не смог его рассказать так, как положено. С этой целью и выкладываю шпоргалку (без редактирования, как есть) для того, чтобы хотя бы из нее вы почерпнули ту информацию, которой я хотел бы поделиться. Номера пунктов — это номера слайдов в презентации. Презентация лежит здесь: system-philosophy.

2.

Тема моего доклада: Философия систем сквозь призму разработки ПО.

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

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

Многие философы работают над изучением сути вещей. Что есть человек или что есть этот ноутбук? На самом деле это вопросы весьма сложные.

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

Что же касается философской составляющей, то она в большей мере проявляется в самом стиле труда, а не в содержании. Сухие математические выкладки меня прельщают в меньшей мере, нежели красивый литературный слог.
Таким образом Философия систем ограничивается коротким и прагматичным объяснением: Все есть система.
4.

Целое больше, чем сумма его частей. — заметил Аристотель.

Это целое состоящее из множества частей и является системой. Система — это не просто множество компонентов вхожих в нее, но скорее отношения между этими компонентами.
5.

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

Можно сказать что рассматриваемый нами объект — это система, а среда — это суперсистема, то есть система, компонентом которой является рассматриваемая система. Внутри суперсистемы А, система А1 пребывает в некоторых взаимоотношениях с другими вложенными системами: А2, А3, …, Аn, и эти взаимодействия потенциально опасны.

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

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

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

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

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

Вы слышите об исключениях и слышите слова «в некоторых» и как неудобно мне дается категоризация систем. Позже вы узнаете почему так.
7.

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

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

8.

В чем разница между саморегуляцией и самоорганизацией?

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

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

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

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

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

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

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

 

10.

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

Все это характерно для любых систем в том числе и абиотических.
11.

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

Так, применяя адаптивную разработку, мы не допускаем разрушительных волн — цунами.
12.

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

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

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

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

Боги программирования низпослали нам принципы именуемые SOLID.

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

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

Принцип подстановки Барбары Лисков говорит о том, что компонент B, наследуемый от компонента A, должен быть способен заменить компонент А. Другими словами, он обязан реализовывать тот же интерфейс. Этот принцип перекликается с предыдущим.

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

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

Другой важный принцип низпосланный нам богами имеет название TDA. Эта аббревииатура расшифровывается как: Tell, do not ask, то есть: говори, а не спрашивай.

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

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

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

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

В ответе на вопрос: «Из чего они состоят?» кроется маленькая хитрость.

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

Одной из ошибок ученых является создание понятия таксона и таксономии, как науки. Они берут отдельные кадры фильма истории и называют их определенными именами. Так один кадр они называют Homo erectus, а другой — Homo sapiens. Но если взять типичного Homo sapiens, его родителя и его потомка, то разница между ними будет так незначительна, то они будут оставаться тем же видом Homo sapiens. И если взять их родственников — ситуация повторится. Так где же проходит черта, переступив через которую организм преобразуется в новый вид? Это похоже на вопрос о курице и яйце, тем не менее ученые продолжают заниматься этим неблагородным занятием — классификацией.

Ответ заключается в генах. Мы должны работать с генами, а не с платоновскими идеальными объектами из метафизического мира. Согласно Платону, если есть человек, то дожно существовать идеальное воплощение человека, а сам человек — лишь жалкая его тень. рТак мы создаем класс Human и наполняем его необходимыми нам свойсвами и методами. И этот класс описывает нечто одно. Будто человек — это просто шарик слепленный из глины. Он и представляет абстрактного человека, а человечностью мы назовем принадлежность к этому классу.

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

Гены — это информация об организме, закодированая в длинные цепочки ДНК.

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

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

Я о том, что для большего удобства разработки нам следует использовать концепции аналогичные генам и мемам. Некая сущность в разрабатываемой системе должна быть лишь собранием тех или иных «генов». На ум сразу приходят примеси реализуемые в Ruby через подмешивание модулей, или trait’ы в Scala. Это отличная практика переодически выность код из классов в модули. Я обычно таким модулям даю окончание -able, например:
Authenticable, Logable, и т.д.

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

Другой возможный вариант, который может использователься параллельно — это минимизация использования наследования в пользу композиции. Целое мы разбиваем на компоненты. В ксенотранспланталогии популярным опытом является пересадка сердца ГМ свиньи человеку. За исключением того, что так и не удалось добиться того, чтобы чужеродное сердце прижилось, идея отличная ибо функциональность сердца свиньи и человека идентичны.

В случае с программным обеспечением, которое является гораздо более простой системой, чем даже организм глупого моллюска с всего-то 3000-5000 нейронов, «сердце» является достаточно абстрактным компонентом для того, чтобы иметь возможность использовать его как в свинье и в обезьяне или в человеке.

 

 

Tips&Tricks: Установка gem’ов без генерации документации

сентября 5, 2012  |  Published in Ruby Gems, Tips&Tricks

Зачем?

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

Для отключения генерации документации с командой gem install используют флаги —no-rdoc и —no-ri, например, так:

$ gem install rails —no-rdoc —no-ri

Однако есть вариант получше — использовать файл .gemrc в вашей home/ директории.

Просто добавьте в него следующую строку:

gem: —no-rdoc  —no-ri

И вы забудете о генерации документации навсегда!

Tags: , , ,

Tips&Tricks: Превращение строки в константу

сентября 3, 2012  |  Published in Ruby, Tips&Tricks

Недавно в статье о Переменных и константах в Ruby я упомянул о том, что из строки можно получить константу используя Kernel.const_get, на что получил в комментариях целых два замечания. Первое касалось того, что следует использовать Object.const_get, вместо Kernel.const_get, а второе касалось того, что нужно учитывать неймспейсы, а потому получение констант из строки несколько сложнее реализовать. Та статья была о другом, потому, я решил добавить отдельную статью в Tips & Tricks о том, как правильно получать из строки константу.

Код выполняющий это действие я решил поместить в метод #constantize, метод называется так же, как аналогичный метод в Rails, и создать для него псевдоним #to_const. Собственно вот его код:

class String
  def constantize
    constants = self.split("::")
    main = Object.const_get(constants.shift)
    constants.inject(main) { |full, nested| full = full.const_get(nested) }
  end

  alias :to_const :constantize
end

Пример работы:

module SuperExtensions
  module MySuperExtension
    class Extension
      def self.hello
        puts "Hello!"
      end
    end
  end
end

klass = "SuperExtensions::MySuperExtension::Extension".to_const
klass #=> SuperExtensions::MySuperExtension::Extension
klass.hello # Hello!

Вот и все! Удачи!

Tags: , , ,

Tips&Tricks — Безболезненное расширение классов ядра

июля 21, 2012  |  Published in Ruby, Tips&Tricks, Расширения

Говорят, что расширение классов ядра (monkey-patching) — это зло. Тут еще некоторые ведут споры касательно того, что считать monkey-patching’ом — добавление новых методов или переопределение старых, но мы обойдем этот спор стороной и сконцентрируемся на том, как это делать безболезненно.
Read the rest of this entry »

Tags: , , , ,

Tips&Tricks — Проверка объявления переменной — массива и вставка нового элемента

июля 21, 2012  |  Published in Ruby, Tips&Tricks

Вам наверное знаком такой код:

a ||= []
a << elem

Так вот, вместо нее можно использовать:

a = [1,2,3,4,5]
b = nil

a = Array.new([*a, 6])
b = Array.new([*b, 1])

a # => [1, 2, 3, 4, 5, 6]
b # => [1]

UPD Предложение от Михаила Дитерле в комментариях:

a = [*a, 6]
b = [*b, 1]
Tags: , ,

Tips&Tricks: Пользовательская конфигурация вашего кода (gem’а)

июля 21, 2012  |  Published in Ruby, Ruby Gems, Tips&Tricks, Расширения

Часто необходимо пользователям gem’ов позволить настраивать их на свой вкус. Как это сделать — об этом эта маленькая статья.

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

Read the rest of this entry »

Tags: , , ,