Избранное сообщение

Фетісов В. С. Комп’ютерні технології в тестуванні. Навчально-методичний посібник. 2-ге видання, перероблене та доповнене / Мои публикации

В 10-х годах я принимал участие в программе Европейского Союза Tempus "Освітні вимірювання, адаптовані до стандартів ЄС". В рамк...

Благодаря Интернету количество писателей и поэтов увеличивается в геометрической прогрессии. Поголовье читателей начинает заметно отставать.

четверг, 31 января 2019 г.

Музей Мерседеса в Штутгарте / Фото из личного архива

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


Смотри также:

https://fetisovvs.blogspot.com/2019/01/blog-post_1.html
https://fetisovvs.blogspot.com/2019/01/blog-post_2.html
https://fetisovvs.blogspot.com/2019/01/blog-post_3.html
https://fetisovvs.blogspot.com/2019/01/blog-post_4.html
https://fetisovvs.blogspot.com/2019/01/blog-post_21.html
https://fetisovvs.blogspot.com/2019/01/blog-post_9.html
https://fetisovvs.blogspot.com/2019/01/blog-post_10.html

https://fetisovvs.blogspot.com/2019/01/blog-post_50.html
https://fetisovvs.blogspot.com/2019/01/blog-post_14.html
https://fetisovvs.blogspot.com/2019/01/blog-post_15.html
https://fetisovvs.blogspot.com/2019/01/blog-post_16.html
https://fetisovvs.blogspot.com/2019/01/blog-post_17.html
https://fetisovvs.blogspot.com/2019/01/blog-post_20.html
https://fetisovvs.blogspot.com/2019/01/blog-post_42.html
https://fetisovvs.blogspot.com/2019/01/blog-post_30.html

Браузер Google Chrome защитят от скрытых загрузок / Все о Google Chrome






Пользователи браузера Google Chrome получат защиту от попутных загрузок (drive-by downloads), которые позволяют скрытно установить на компьютер вредоносное ПО, пишет Threatpost. Эксперты рассчитывают, что новая функция решит одну из фундаментальных проблем интернет-безопасности.

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

Эксперты обсуждают эту угрозу по меньшей мере с 2013 года — именно тогда специалист Google Майк Уэст (Mike West) предложил заблокировать попутные загрузки в браузерах. Четыре года спустя он опубликовал тему для обсуждения на GitHub, где к дискуссии присоединился эксперт Chromium Яо Сяо (Yao Xiao). Он рассказал о планах добавить необходимую функцию в браузер Google и пригласил коллег к участию в ее разработке.

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

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

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

Источник: https://news.softodrom.ru/ap/b31572.shtml

Смотри также:

Релиз web-браузера Chrome 71. https://fetisovvs.blogspot.com/2018/12/web-chrome-71-google-chrome.html
Как посмотреть и извлечь файлы из кэша Google Chrome и других браузеров. https://fetisovvs.blogspot.com/2019/01/google-chrome-google-chrome.html
Как оптимизировать запуск Chrome с большим количеством сохраненных в предыдущей сессии вкладок. https://fetisovvs.blogspot.com/2019/01/chrome-google-chrome.html
Как исправить ошибку ERR_TIMED_OUT в Chrome, если сброс настроек не дал результатов. https://fetisovvs.blogspot.com/2018/11/errtimedout-chrome-google-chrome.html
Как в Google Chrome использовать функцию для YouTube «видео в отдельном окне». https://fetisovvs.blogspot.com/2018/11/google-chrome-youtube-google-chrome.html
В Chrome 71 начнётся блокировка вводящих в заблуждение рекламных блоков. https://fetisovvs.blogspot.com/2018/11/chrome-71-google-chrome.html
Как в Google Chrome включить расширенные предложения для быстрого поиска. https://fetisovvs.blogspot.com/2018/10/google-chrome-google-chrome_29.html
Google внедряет меры для противодействия вредоносным дополнениям к Chrome. https://fetisovvs.blogspot.com/2018/10/google-chrome-google-chrome.html
Как в Chrome определить папку установленного расширения. http://fetisovvs.blogspot.com/2018/09/chrome-google-chrome.html
Google Chrome заблокировал загрузку файла: как его скачать. http://fetisovvs.blogspot.com/2018/09/google-chrome-google-chrome.html
Google Chrome не отображает видео. http://fetisovvs.blogspot.com/2018/07/google-chrome-google-chrome.html
Как настроить прокси-сервер в Google Chrome. http://fetisovvs.blogspot.com/2015/03/google-chrome_19.html
Изменения Политики конфиденциальности и настроек доступа. http://fetisovvs.blogspot.com/2018/05/google-google-chrome.html
Режимы чтения для браузера Google Chrome. http://fetisovvs.blogspot.com/2018/04/google-chrome-google-chrome_17.html
Браузер Google Chrome сканирует файлы на компьютерах пользователей. http://fetisovvs.blogspot.com/2018/04/google-chrome-google-chrome.html
Как удалить логин и пароль сайта из браузера Chrome и аккаунта Google. http://fetisovvs.blogspot.com/2017/09/chrome-google-google-chrome.html
Родительский контроль в браузере Google Chrome. http://fetisovvs.blogspot.com/2017/04/google-chrome-google-chrome.html
В Google Chrome отключат страницу chrome:plugins. http://fetisovvs.blogspot.com/2017/02/google-chrome-chromeplugins-google.html
Уменьшаем потребление памяти Google Chrome. http://fetisovvs.blogspot.com/2016/01/google-chrome-google-chrome_20.html
Как сбросить настройки браузера Google Chrome. http://fetisovvs.blogspot.com/2016/01/google-chrome-google-chrome.html
Как восстановить Google Chrome браузером по умолчанию в Windows 10 после установки накопительных обновлений Windows. http://fetisovvs.blogspot.com/2016/03/google-chrome-windows-10-windows-google.html
Разработчики Google Chrome больше не доверяют собственному тесту Octane. http://fetisovvs.blogspot.com/2017/04/google-chrome-octane-google-chrome.html
Как настроить прокси-сервер в Google Chrome. http://fetisovvs.blogspot.com/2015/03/google-chrome_19.html
Профиль в браузере Google Chrome. http://fetisovvs.blogspot.com/2016/09/google-chrome-google-chrome.html
Как в Google Chrome включить блокировку нежелательных редиректов. http://fetisovvs.blogspot.com/2017/11/google-chrome-google-chrome_16.html
В Google Chrome встроили новую утилиту для защиты от нежелательных программ. http://fetisovvs.blogspot.com/2017/10/google-chrome-google-chrome.html
Google Chrome поддержит центр уведомлений Windows 10. http://fetisovvs.blogspot.com/2017/09/google-chrome-windows-10-google-chrome.htm

Jaxb (XJC) генерация классов из XML Schema (XSD) с описаниями классов и полей в виде аннотаций. XJC плагин / Программирование на Java

Думаю многие Java-разработчики которые хоть раз сталкивались с Web-сервисами, использовали генерацию Java DTO классов по описанию XML Schema (XSD)Jaxb с этим справляется на ура, не важно как его использовать, через xjc или wsimport вызов из командной строки, maven или gradle плагины.
Так быстро и просто сгенерировать классы из XSD схемы. Но вот одна проблема — практически полностью пропадают описания, имевшиеся в исходной схеме!
Практически, потому что Javadoc описание будет только у самого класса, в фиксированном формате (где не разделить описание и фрагмент XML без регулярок скажем), описание полей (филдов) отсутствуют полностью. А если вам они, как мне, нужны ещё и во время выполнения (runtime) — тут совсем беда.
Именно с этим, пришлось побороться, как ни странно, задача заняла много времени, и в результате я написал плагин, который и хотел бы представить в надежде что он может кому-то сэкономить несколько часов в будущем.


Краткий обзор возможностей Jaxb



Jaxb имеет большую историю и неплохое официальное описание, в том числе по добавлению поведения в генерируемые классы.
Основной инструмент для вызова генерации классов из командной строки — xjc также имеет не самое маленькое количество ключей. Впрочем ни один из них, не для нашего случая.
Конечно нельзя не упомянуть про -b, где можно предоставить свой биндинг. И это весьма мощное оружие, особенно в купе с множественными плагинами. Весьма неплохой блог пост (на английском) — рекомендую к прочтению как краткое введение. Но биндинг в большинстве своём ограничен статическими значениями присваемых аннтотаций или задаваемых имён, с указанием элементов, к которым он применяется. В моей проблеме это не помогает.

Jaxb (XJC) плагины



Пока искал готовое решение, нашёл множество плагинов, которые расширяют генерацию. Полагаю их обзор выходит за рамки данного поста. Что важно, делающего то что нужно именно мне, я так и не нашёл.
Но зато, пока читал ответы и вопросы на http://stackoverflow.com/, нашёл несколько вопросов, подобного рода, например:
  1. Using JAXB to handle schema annotations.
  2. How to make generated classes contain Javadoc from XML Schema documentation
  3. How can I generate a class from which I can retrieve the XML of a node as a String


и ни одного полного ответа, в некоторых за много лет!
Зато, возвращаясь к теме возможностей, оказалось что имеется API для написания плагинов! Низкоуровневое, местами запутанное, почти без документации… Но могу сказать при это весьма продвинутое, то есть вмешаться можно прямо много в какие процессы. Кстати в ответах на него часто ссылаются, для многих нестандартных случаев. Ну я и попробовал написать плагин.
Для тех, кому интересны подробности процесса написания своих плагинов, могу порекомендовать статьи:


Что хотел и зачем



Для одной из наших интеграций заказчик предоставил архив с XSD файлами, по которым мы должны были сгенерировать модель в MDM Unidata, с которой мы работаем, для дальнейшей настройки правил качества.
Отмечу что сама MDM система проприетарная, вряд ли многие с ней знакомы, но это не имеет особого значения. Суть в том что мы должны были создать по XSD описаниям справочники и реестры. При этом у реестров есть поля, в которых используется как идентификатор (имя поля), так и "отображаемое имя" — название, понятное человеку, на русском. Простую аналогию можно провести (и это вероятно также полезный пример для применения) с РСУБД в терминах которой можно считать что мы хотели сделать таблицы БД, но при этом дать описания (comment) для каждого столбца для последующего использования.
Мой план был такой:
  1. Генерируем классы по XSD с помощью XJC
  2. Затем берём прекрасную библиотеку reflections и итерируем по всем объектам, рекурсивно спускаясь по полям.


Всё быстро заработало для латинских имён, которые брались из филдов (field) классов. А вот русское, человекопонятное описание было взять неоткуда!
Править описания вручную — не вариант, потому что вложенных полей десятки тысяч.
Первой попыткой было написать подобный парсер на Groovy самостоятельно, выдирая описания из XSD. И в общем он был реализован. Но быстро выяснилось что имеется множество случаев, где требуется дополнительная обработка — рекурсивные вызовы, поддержка расширений XSD1.1 в виде restriction/extension (с поддержкой наследования и переопределения), разные типы из которых генерируются поля классов вроде <element> и <attribute><sequence><choose> и много других мелочей. Реализация обрастала дополнениями, а стройности ей не прибавлялось.
В итоге я вернулся к мысли написать плагин xjc-documentation-annotation-plugin, который вам и представляю, в надежде что он будет кому-то полезен кроме меня!

xjc-documentation-annotation-plugin



Всё выложено на гитхабе: https://github.com/Hubbitus/xjc-documentation-annotation-plugin
Там же есть инструкции, тесты и отдельный демо-проект для gradle с примером использования.
Полагаю нет смысла копировать сюда описание оттуда, просто вкратце покажу что именно он делает.
Скажем есть такой XSD фрагмент:
    <xs:complexType name="CadastralBlock">
        <xs:annotation>
            <xs:documentation>Кадастровый квартал</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="number" type="xs:string">
                <xs:annotation>
                    <xs:documentation>Кадастровый номер</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>


По умолчанию XJC сгенерит из него класс вида (геттеры, сеттеры и часть не имеющих к делу мелочей опущены для читаемости):
/**
 * Кадастровый квартал
 * 
 * <p>Java class for CadastralBlock complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="CadastralBlock"&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="number" type="{http://www.w3.org/2001/XMLSchema}string"/&gt;
 *       &lt;/sequence&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CadastralBlock", namespace = "http://hubbitus.info/xjc-plugin-demo", propOrder = {
    "number"
})
public class CadastralBlock {
    @XmlElement(required = true)
    protected String number;
}


С плагином же вы получите:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CadastralBlock", namespace = "http://hubbitus.info/xjc-plugin-demo", propOrder = {
    "number"
})
@XsdInfo(name = "Кадастровый квартал", xsdElementPart = "<complexType name=\"CadastralBlock\">\n  <complexContent>\n    <restriction base=\"{http://www.w3.org/2001/XMLSchema}anyType\">\n      <sequence>\n        <element name=\"number\" type=\"{http://www.w3.org/2001/XMLSchema}string\"/>\n      </sequence>\n    </restriction>\n  </complexContent>\n</complexType>")
public class CadastralBlock {

    @XmlElement(required = true)
    @XsdInfo(name = "Кадастровый номер")
    protected String number;
}


Обратите внимание на добавленные аннотации @XmlType.
Использовать это затем просто, как любую другую аннтотацию:
    XsdInfo xsdAnnotation = CadastralBlock.class.getDeclaredAnnotation(XsdInfo.class);
    System.out.println("XSD description: " + xsdAnnotation.name());


Рабочий пример есть в тестах: 12.


Смотри также популярное:


Зачем нужна Java. http://fetisovvs.blogspot.com/2014/07/java.html
Когда Java наконец помрёт, что с этим делать и что будет с JPoint. https://fetisovvs.blogspot.com/2018/11/java-jpoint-java.html
Разбор основных концепций параллелизма. http://fetisovvs.blogspot.com/2018/04/java.html
Первый контакт с «var» в Java 10. http://fetisovvs.blogspot.com/2018/01/var-java-10-java.html
JAVA 9. Что нового? http://fetisovvs.blogspot.com/2017/10/java-9-java.html
Руководство по Java 9 для тех, кому приходится работать с legacy-кодом. http://fetisovvs.blogspot.com/2018/08/java-9-legacy-java.html
Концепции объектно-ориентированного программирования — ООП в Java. http://fetisovvs.blogspot.com/2017/01/java-java.html
Анимации в Android по полочкам (Часть 1. Базовые анимации). http://fetisovvs.blogspot.com/2018/02/android-1-java.html
Двести пятьдесят русскоязычных обучающих видео докладов и лекций о Java. http://fetisovvs.blogspot.com/2015/12/java-5-java-java.html
Абстрактные классы и методы. http://fetisovvs.blogspot.com/2017/02/java.html
Полное руководство по Java Reflection API. Рефлексия на примерах. http://fetisovvs.blogspot.com/2017/02/java-reflection-api-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. http://fetisovvs.blogspot.com/2017/10/java-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. (Часть 3). http://fetisovvs.blogspot.com/2017/10/java-3-java.html
ТОП-3 способа конвертировать массив в ArrayList. Пример на Java. http://fetisovvs.blogspot.com/2016/09/3-arraylist-java-java.html
Ввод–вывод в Java. http://fetisovvs.blogspot.com/2016/05/java-java_28.html
Java Challengers #2: Сравнение строк. https://fetisovvs.blogspot.com/2018/11/java-challengers-2-java.html
Enum-Всемогущий. http://fetisovvs.blogspot.com/2017/02/enum-java.html
Массивы в Java. Создание и обработка. http://fetisovvs.blogspot.com/2017/10/java-java_18.html
Arrays, Collections: Алгоритмический минимум. http://fetisovvs.blogspot.com/2017/12/arrays-collections.html
Популярные методы для работы с Java массивами. http://fetisovvs.blogspot.com/2016/09/java-java_29.html
Пример использования метода replace в Java. Как заменить символ в строке? http://fetisovvs.blogspot.com/2017/01/replace-java-java.html
Класс Scanner в Java — описание и пример использования. http://fetisovvs.blogspot.com/2017/01/scanner-java-java.html
Пример использования метода trim в Java: как удалить пробелы в начале и конце строки? http://fetisovvs.blogspot.com/2017/01/trim-java-java.html
Spark — Потрясающий веб-микрофреймворк для Java. http://fetisovvs.blogspot.com/2017/10/spark-java-java.html
Чтение и запись CSV файла с помощью SuperCSV. http://fetisovvs.blogspot.com/2017/01/csv-supercsv-java-java.html
Конструкция try/catch/finally (исключения). http://fetisovvs.blogspot.com/2017/01/trycatchfinally-java.html
1000+ часов видео по Java на русском. http://fetisovvs.blogspot.nl/2017/06/1000-java-java.html
Раздача халявы: нетормозящие треды в Java. Project Loom. http://fetisovvs.blogspot.com/2018/09/java-project-loom-java.html
Шпаргалка Java программиста 7.1 Типовые задачи: Оптимальный путь преобразования InputStream в строку. http://fetisovvs.blogspot.com/2016/04/java-71-inputstream-java.html
Шпаргалки Java программиста 10: Lombok. http://fetisovvs.blogspot.nl/2017/12/java-10-lombok-java.html
Шпаргалки Java программиста 9: Java SE — Шпаргалка для собеседований и повторений. http://fetisovvs.blogspot.com/2017/12/java-9-java-se-java.html
Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson,
LoganSquare, Jackson, JsonPath и другие). http://fetisovvs.blogspot.com/2016/04/java-8-json-gson-fastjson-logansquare.html
Java 8 и паттерн Стратегия. http://fetisovvs.blogspot.com/2018/03/java-8-java.html
Java EE Concurency API. http://fetisovvs.blogspot.com/2018/08/java-ee-concurency-api-java.html
Реализация ООП-наследования в классах, работающих с SQL и MS Entity Framework. http://fetisovvs.blogspot.com/2017/02/sql-ms-entity-framework.html
Как установить соединение с СУБД MySQL в IntelliJ IDEA в редакции Community. http://fetisovvs.blogspot.com/2016/04/mysql-intellij-idea-community-java.html
TDD приложений на Spring Boot: работа с базой данных. https://fetisovvs.blogspot.com/2018/12/tdd-spring-boot-java.html
Руководство: Thymeleaf + Spring. 

https://fetisovvs.blogspot.com/2019/01/thymeleaf-spring-1-java.html
https://fetisovvs.blogspot.com/2019/01/thymeleaf-spring-2-java.html
https://fetisovvs.blogspot.com/2019/01/thymeleaf-spring-3-java.html
Максимально простой в поддержке способ интеграции java-клиента с java-сервером. http://fetisovvs.blogspot.com/2018/09/java-java-java.html
Как с помощью maven работать с библиотеками, которых в maven нет. http://fetisovvs.blogspot.com/2017/03/maven-maven-java.html
Проекты по созданию компиляторов из Java в JavaScript и исполняемые файлы. http://fetisovvs.blogspot.com/2018/01/java-javascript-java.html
Реактивное программирование с JAX-RS. http://fetisovvs.blogspot.com/2018/09/jax-rs-java.html
Компактные строки в Java 9. https://fetisovvs.blogspot.com/2018/10/java-9-java.html
Динамический прокси Java: что это и как им пользоваться? https://fetisovvs.blogspot.com/2018/12/java-java.html
Абстрактный CRUD от репозитория до контроллера: что ещё можно сделать при помощи Spring + Generics. http://fetisovvs.blogspot.com/2018/09/crud-spring-generics-java.html
Диагностика утечек памяти в Java. http://fetisovvs.blogspot.com/2017/03/java-java_18.html
Spring AOP и JavaConfig в плагинах для Atlassian Jira. http://fetisovvs.blogspot.com/2018/04/spring-aop-javaconfig-atlassian-jira.html
Блеск и нищета Java для настольных систем. http://fetisovvs.blogspot.com/2018/04/java-haulmont-java.html
Разбор задачек от Одноклассников на JPoint 2018. http://fetisovvs.blogspot.com/2018/04/jpoint-2018-java.html
Программируем… выход из лабиринта. http://fetisovvs.blogspot.com/2015/10/java.html
Основы работы с IntelliJ IDEA. Интерфейс программы. http://fetisovvs.blogspot.com/2016/09/intellij-idea-java.html
Ускоряем время сборки и доставки java web приложения. http://fetisovvs.blogspot.com/2018/03/java-web-java.html
Открытый урок Java Enterprise «CDI in action». http://fetisovvs.blogspot.com/2018/09/java-enterprise-cdi-in-action-java.html
«Мы все стремимся к сложности, а потом с ней боремся»: интервью с Венкатом Субраманиамом. http://fetisovvs.blogspot.com/2018/09/java_16.html

Рефакторинга много не бывает / Вопросы программирования

Привет, Хабр! Представляю вашему вниманию перевод статьи "Refactoring — oops, I’ve been doing it backwards" автора Джастина Фуллера (Justin Fuller).



Я очень завишу от рефакторинга, и не боюсь признать это, но есть только одна проблема: я всегда делал это задом наперед. Видите ли, то, что я делал, можно было бы точнее описать как преждевременную абстракцию кода.
Мы все знаем о рефакторинге. Если вы прочитали хотя бы одну книгу по программированию или много времени сидите на Medium, то наверняка слышали об этом. Это важная концепция, которая делает код понятным, поддерживаемым и расширяемым.

Так почему рефакторинг не оправдал моих надежд?


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


В конце концов, все получилось, но был ли мой код более сложным, чем нужно? Думаю, что да.

Главенство принципов над целью



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


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


Помните мое размышление в самом начале? Это напомнило мне мантру: «Заставь это работать, сделай это правильно, сделай это быстро». Я понял, что не следовал этому порядку. Я делал все правильно, быстро, а потом делал так, чтобы это работало!

Заставьте это работать



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


То же самое может случиться и с кодом.


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



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


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

Имейте причину для рефакторинга


Наличие SOLID-кода не является причиной. Наличие функционального или чистого кода также не является причиной.

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


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


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


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


Посмотрите на следующий пример.

// not extensible
function getUser() {
return {
name: 'Justin',
email: 'justinfuller@email.com'
}
}
// Extensible
class User {
constructor(options = {}) {
this.userData = options
} get() {
return this.userData
}
set(key, value) {
this.userData[key] = value
}
}


Что вы предпочитаете? Что обычно пишете в первую очередь? Конечно, класс User гораздо более расширяем, потому что он может обрабатывать не только имя и электронную почту. Он также может быть расширен дочерним классом, может быть SuperUser, который будет иметь гораздо больше методов, но все еще использует классические методы get() и set().


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


Мой совет — придерживайтесь простейшего шаблона.

Порядок сложности



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



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


Обычно я помещаю что-то в объект вместо простой константной переменной. Этот список держит меня под контролем и предохраняет от преждевременного рефакторинга.

Баланс



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


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


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


В следующий раз, когда захотите провести рефакторинг своего кода, подумайте, а стоит ли?

Источник: https://habr.com/ru/post/437708/?utm_source=habrahabr&utm_medium=rss&utm_campaign=437708

Смотри также:

Функциональное программирование: в Java и C# слишком много церемоний. http://fetisovvs.blogspot.com/2017/05/java-c.html
Программирование и параллелизм: как функциональные языки стали незаменимыми. http://fetisovvs.blogspot.com/2017/10/blog-post_11.html

среда, 30 января 2019 г.

Музей Мерседеса в Штутгарте / Фото из личного архива

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



Смотри также:

https://fetisovvs.blogspot.com/2019/01/blog-post_1.html
https://fetisovvs.blogspot.com/2019/01/blog-post_2.html
https://fetisovvs.blogspot.com/2019/01/blog-post_3.html
https://fetisovvs.blogspot.com/2019/01/blog-post_4.html
https://fetisovvs.blogspot.com/2019/01/blog-post_21.html
https://fetisovvs.blogspot.com/2019/01/blog-post_9.html
https://fetisovvs.blogspot.com/2019/01/blog-post_10.html

https://fetisovvs.blogspot.com/2019/01/blog-post_50.html
https://fetisovvs.blogspot.com/2019/01/blog-post_14.html
https://fetisovvs.blogspot.com/2019/01/blog-post_15.html
https://fetisovvs.blogspot.com/2019/01/blog-post_16.html
https://fetisovvs.blogspot.com/2019/01/blog-post_17.html
https://fetisovvs.blogspot.com/2019/01/blog-post_20.html
https://fetisovvs.blogspot.com/2019/01/blog-post_42.html

Google Maps (Google Карты): советы и секреты

Google Карты (или Google Maps) и Яндекс.Карты – одни из самых популярных карт для мобильных устройств и компьютеров на просторах СНГ. Они подробные, бесплатные и удобные. С ними легко путешествовать, искать информацию и ездить на автомобиле. Сегодня мы узнаем очевидные и не очень функции Google Карт. Поехали!

Отзывы и рейтинг

Если вам не понравился/понравился сервис на СТО или в кафе (к примеру) – вы всегда можете об этом написать прямо на картах Google. Про любую организацию, точку на карте или достопримечательность можно оставить отзыв. Открываем карты. Щелкаем на название интересующей точки. Слева открывается информация о точке. Здесь внизу можно поставить свой рейтинг и написать отзыв.
3D-карты
Пожалуй, самая фантастическая и впечатляющая функция от Google. 3D-модели городов и использованием фотографий со спутника и панорам улиц. Выглядит потрясающе! Вы планировали посетить Париж, но даже не сделали визу? Летите прямо сейчас туда с помощью Google Карт! Открываем карты на компьютере. Выбираем съемку со спутника. Открываем Париж. Внизу справа щелкаем 3D. Теперь вы видите реальный город с высоты птичьего полета. Каждое здание, дерево и даже автомобиль. Можно просто погулять по городу. Увидеть известные достопримечательности. К сожалению, Минск и Вильнюс пока недоступны для такого просмотра.

Измеряем расстояние

Вы хотите знать сколько метров идти до остановки? Или просто решили узнать длину Дворца Независимости? А может радиус Парка Горького? В этом помогут Google Карты. Здесь есть точная линейка. Чтобы ее вызвать, нажмите в браузере правой кнопкой мыши на любой точке на карте. Далее - Измерить расстояние. С помощью этой линейки можно создавать сложные маршруты и измерять их протяженность. Удобная и точная вещь.
Вообще, меню по правой кнопки мыши имеет много функций. Например, вы можете легко выбрать начальную и конечную точки вашего маршрута.

Оффлайн карты

Использовать Google Карты удобно, но только при наличии подключения к интернету. Что делать, если рядом нет глобальной сети? Это предусмотрела компания Google. Выбираем в приложении раздел Оффлайн-карты. Далее определяем область карты, которую хотим скачать. Скачиваем. Теперь вся информация об интересном месте у вас в кармане (без подключения к сети)!

Ваши перемещения

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

Пробки

В Google Картах можно посмотреть пробки. Причем не только в данный момент, но и какие они бывают, например, в пятницу в Москве, в 19.00 и на каких улицах. Открываем Карты, слева выбираем Пробки. Внизу в центре карты вы увидите небольшую панель. Выберите на ней Прогноз пробок. Далее вам останется выбрать день недели и время. И спланировать поездку.

Горячие клавиши

Многие знают о возможности смотреть панорамы улиц на картах Google. Но не все – о том, что ими можно управлять с клавиатуры. Вот список горячих клавиш: W A S D – вперед, назад, влево, вправо и стрелки – вверх, вниз, вправо, влево.

Создаем свои карты

Google Карты предоставляют возможность создать свою карту и поделиться ей с друзьями. Это очень просто! Заходим в раздел Мои карты. Вверху кликаем «Создать новую карту». Все. Теперь вы можете создавать маршруты, точки и делиться ими с друзьями. Отличная функция для активных путешественников.

Поиск по категориям

Если вы попали в незнакомый город и вам нужен продуктовый магазин поблизости – нет ничего проще! Набираем в поиске: «магазин» или «супермаркет». Google Карты покажут все магазины поблизости. Вам останется только выбрать. Такой поиск работает и с другими популярными запросами: СТО, кинотеатр, банкомат и другими.

Делитесь своим местоположением онлайн

Иногда ты спешишь на вечеринку, где тебя ждут друзья. Но когда точно приедешь совсем не знаешь. Чтобы друзья не звонили каждые 5 мин, достаточно включить отображение вашего перемещения онлайн. Для этого открываем Карты и выбираем – Передача геоданных. Затем щелкаем кому из ваших друзей будет видно ваше передвижение и на какое время. Готово! Теперь друзья будут наблюдать в реальном времени на какой улице вы сейчас едете.

Желтый человек

Желтый человек в правом нижнем углу экрана? Зачем он? Он находится там не просто так. Кликните на него мышью и перетяните на любое место на карте. Он покажет вам панорамы улиц, если они есть для вашего города. Информативно и красиво. А звать этого человечка - The pegman.

Голосовые команды

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

Стать локальным гидом

Вы можете «прокачивать» свой профиль в Google Картах – совсем как в игре. Дополнительные баллы начисляются за фотографии, отзывы, рейтинги, ответы, панорамы. Посмотреть ваш текущий уровень вы можете здесь. В качестве компенсации за высокие уровни вам могут предложить одним из первых протестировать новые продукты Google, а также участие в различных мероприятиях от Google.
И небольшая пасхалка от создателей Google Карт – наберите в поиске “Loch Ness” – и посмотрите в нижний правый угол на желтого человечка.
Советы актуальны для версии Google Карт для ПК и Android (10.6.2).