Как распространить информацию об общем программировании среди членов команды?

20

Я остаюсь в среде, где люди верят:

  1. Обобщения Java являются функцией, используемой исключительно для написания библиотеки, а не для реального кодирования.
  2. C ++ является языком программирования OO; templateявляется необязательной функцией, которую можно избежать

Хотя эти люди очень полагаются на библиотеки, написанные с использованием универсального программирования (например, STL, контейнеры Java). Если я пишу код, используя templates или generics, рецензент кода, скорее всего, отклонит его и прокомментирует, чтобы написать его «надлежащим / понятным / элегантным» способом.

Такой менталитет применим от обычного программиста до самого старшего менеджера. Выхода нет, потому что 90% времени эти люди лоббируют.

Как лучше всего ( не перерезать горло ) объяснить их, практический подход к написанию кода, который представляет собой ОО и универсальное программирование одновременно?

iammilind
источник
11
Я желаю вам удачи, но вам, вероятно, придется уйти, если вы хотите, чтобы ваш путь ..
Человек
3
@ TheMuffinMan, ты прав. Я покинул это рабочее место, и теперь у меня есть своя собственная компания. Здесь у меня есть полный контроль над кодированием!
Iammilind

Ответы:

14

В мире все еще есть люди, которые не используют дженерики jave в «обычном кодировании». Я могу поверить в это с помощью шаблонов C ++, но дженерики? Их даже не сложно выучить / использовать. Серьезно, лучшими функциями Java и C ++ являются соответственно дженерики и шаблоны.

Лучший способ убедить людей в чем-то - это дать убедительный аргумент, не угрожать и быть правым.

Пока вы не делаете что-то вроде использования шаблонов в качестве языка программирования, параметрический полиморфизм (дженерики / шаблоны) почти наверняка хорош.

1. Избегает дублирования кода.

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

2. Поддерживает лучшую статическую проверку.

Без параметрического полиморфизма вы заканчиваете тем, что пишете такие вещи, как public Object clone()или public boolean equals(object b)которые не являются просто мерзостями, у них есть типы, которые не предоставляют информации о том, что они делают, и неизменно в конечном итоге выдают исключения повсеместно. Альтернативой параметрическому полиморфизму является повсеместное приведение

3. Код ООП с непараметрическим полиморфизмом в принципе не может правильно обрабатывать «двоичные методы».

Вы используете это часто.

4. Это лучшая практика

В Java использование обобщений считается наилучшей практикой (см. «Эффективная Java» Джоша Блоха). Крупные мыслители С ++, такие как Саттер и Александреску, также поощряют использование шаблонов для решения различных задач.

5. Это соответствует ОО-парадигме.

Люди часто не замечают этого, но комбинация подтипирования и обобщений делает систему НАМНОГО более мощной, выразительной и объектно-ориентированной, чем любая система с одним из них.

Рассмотрим миксины Скалы. Это хорошая функция, которая позволяет вам собрать ваши объекты из составных частей. Обобщения и шаблоны могут имитировать некоторые из этих преимуществ. Например, скажем, один из ваших объектов использует базу данных. Хороший дизайн позволил бы вам абстрагировать доступ к базе данных в отдельный класс. Если все сделано правильно, это не только позволяет вам издеваться над хранилищем данных (ключ к тестируемости), но также означает, что вы можете добавить альтернативные реализации, такие как эта новая база данных no-sql. Здесь, однако, у вас может быть проблема, независимо от того, какую реализацию вы используете, вы получите различные возможности вашего бизнес-объекта.

Дженерики на помощь!

   public class Business<S extends Datastore>{
      private S store; ...
   }

Теперь вы можете начать статически дифференцировать ваши Businessобъекты на основе способности использовать специфические особенности базы данных. Вам все еще нужны некоторые проверки и приведение во время выполнения, но вы можете начать создавать НАМНОГО лучший код.

и

6. Нормальный код не существует.

Во вселенной программирования есть только три вещи:

  1. библиотеки,
  2. конфигурации и
  3. плохой код

Если вы не думаете о своем коде, как о библиотеке, у вас серьезные проблемы, когда меняются требования к вашему проекту. Архитектура - это (возможно) искусство проектирования хороших API.

Я считаю это отношение ошеломляющим. После того, как вы привыкнете к программированию с параметризованными типами, если вы не используете их, то все становится больно И у Java и C ++ есть куча грубых мест, которые они помогают исправить.

Филипп JF
источник
7
Я как понятие , что normal codeне существует и что есть только три вида: libraries, configurationsи bad code. Это идеалистическая аргументация, хотя вам все равно придется объяснить ее своим коллегам, хотя они могут быть не такими идеалистическими, как вы. Хотя я согласен, что использование параметризованных типов просто замечательно, когда вы освоите его.
Спойк
3
Черт, даже шаблоны C ++ не так сложны в использовании, если вы не используете их для целей метапрограммирования шаблонов. :-)
In silico
-1 за предложение, что каждый, кто решит не использовать дженерики, делает это только потому, что не знает, как работает эта функция.
tp1
учитывая вероятность неправильного использования, я бы сказал, что ограничение / не использование шаблонов / шаблонов может быть намного лучшим решением, за которое вы отдаете должное.
Ryathal
Люди, которые отказываются использовать дженерики / шаблоны для крупномасштабной разработки программного обеспечения, будут случайно и неизбежно создавать «второй язык» - интерпретатор, работающий на Java, который реализует любой «деловой язык», который они имеют в виду. en.wikipedia.org/wiki/Inner-platform_effect
Рулон
16

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

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

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

  • Будут ли дженерики (или что-то еще) улучшать стоимость их продукта? Возможно нет.

  • Будут ли дженерики (или что-то еще) затруднить работу людей, которых они уже наняли, для выполнения своей работы? Да.

  • Будут ли дженерики улучшать время выхода на рынок? Если бы вы были единственным инженером, может быть. Но если целая группа инженеров должна пройти обучение по дженерикам, прежде чем в доме будет написана другая строка кода, нет.

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

Майк Накис
источник
9

Я передал бы достоинства дженериков рецензенту кода и другим коллегам перед любым обзором:

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

2) Обобщения обеспечивают безопасность типов без накладных расходов на несколько реализаций.

Таким образом, [1] и [2] уменьшают риск ошибки в коде. Это экономит время разработчика и, следовательно, деньги компании.

Если читаемость является проблемой, то неловкость использования универсальных типов может быть поставлена ​​под угрозу. Это одна из причин, по которой вы можете расширить рекомендации по кодированию. Это может быть сделано в контексте рабочего дня, а не только для расширения библиотек (однако, по мере необходимости рекомендуется реорганизовать методы рефакторинга и пометить возможные методы-кандидаты для библиотек в коде для последующего легкого распознавания). Следовательно, не было бы никаких причин не использовать их в повседневном контексте.

Я хотел бы добавить несколько утверждений о том, что у других программистов нет проблем с универсальными шаблонами: универсальные шаблоны широко используются в Java и многих других языках, таких как C #. Любому серьезному программисту было бы трудно без таких безопасных строительных блоков.

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

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

CarneyCode
источник
7

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

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

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

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

Очевидно, я не могу похвастаться реальным примером, не нарушив соглашение о неразглашении. Но в качестве примера того, что я сделал, было бы сделать шаблон стратегии и применить его к генерикам. Итак, это шаблон стратегии:

введите описание изображения здесь

И чтобы программисты могли применить этот шаблон, вы можете добавить универсальный тип, Contextкоторый должен использовать что-то, имеющее Strategyтип. В коде это будет выглядеть примерно так в Java:

// declare the generic Context class that has a type "S" 
// that is an upper bound class of Strategy
public class Context <S extends Strategy> {
    S strategy;

    // Constructor with an initial strategy
    public Context(S initialStrategy) {
        this.strategy = initialStrategy;
    }

    public void doSomething() {
      strategy.execute(); // assumes that Strategy has an execute() method.
    }

    public void setStrategy(S strategy) {
        this.strategy = strategy;
    }
}

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

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

Spoike
источник
Люблю диаграмму! Какой инструмент вы использовали?
Яннис
@YannisRizos Я использовал yuml.me, который создает диаграммы из текстового ввода. Бета-сервис в настоящее время немного глючит (однако вы можете загрузить сгенерированную картинку в свой пост, используя сгенерированную ссылку).
Спойк
в закладки, спасибо, что поделились. хотя я действительно не хочу изучать еще один синтаксис, хотя и упрощенный, он выглядит круто, и я в какой-то момент попробую.
Яннис
@YannisRizos О, я сам постоянно забываю синтаксис. Вот почему есть удобная страница образцов . Я обнаружил, что быстрее написать простые диаграммы классов в yuml, чем использовать Visio.
Спойк
@YannisRizos yUml - классный инструмент. Вот несколько примеров того , что вы можете делать с ним: carnotaurus.philipcarney.com/tagged/yUML
CarneyCode
4

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

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

BЈовић
источник
4

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

Одна из наиболее эффективных стратегий здесь - сосредоточиться на крошечной победе. В книге я прочитал следующий пример : автор был убежденным пользователем, не принадлежащим Apple. Они ей не нравились, и она не хотела иметь с ними ничего общего. У нее было много дискуссий с людьми, поддерживающими позицию Apple, и каждый из них просто толкнул ее каблуки глубже в землю. Затем кто-то купил ей iPod shuffle, и таким образом ее предубеждения исчезли. Это не заставляло ее хотеть покупать только продукты Apple, но жесткая, укоренившаяся анти-Apple позиция была заменена более сбалансированной точкой зрения. Здесь было место для компромисса, и она постепенно перешла на Apple.

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

Конкретный момент, на котором нужно сосредоточиться, зависит от вашей ситуации, но вот одна идея: разделение, которое вы рисуете между библиотеками и «реальным кодом», кажется очень неестественным. На мой взгляд, программист, создающий приложение, должен тратить 80% своего времени на библиотеку для типа приложения, которое он делает, и 20%, используя эту библиотеку для сборки приложения. Весь код, который стоит хранить, следует рассматривать как библиотеку. Я бы посоветовал вашим руководителям обобщить часть вашего кода во внутреннюю библиотеку (если вы еще этого не сделали). По их собственной логике, они должны использовать для этого дженерики, и, по оценкам выше, 80% вашего кода может оказаться внутри библиотеки. Как только вы заставите всех использовать дженерики с другой стороны, они должны привыкнуть к этому, и предубеждения должны исчезнуть.

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

Примечание "понятно". Если рецензент кода не видит преимущества обобщений, тогда все <<<>>>-материалы - это просто непонятный шум, который не нужен.

Я бы посоветовал взглянуть на то, сколько на самом деле текущих ошибок (открытых или недавно исправленных) в вашей базе данных ошибок, которых можно было бы избежать с помощью обобщений. Ищите ClassCastExceptions.

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


источник
2

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

Еще несколько случайных мыслей из моего общего путешествия:

  • Исключения ClassCastException возникают во время выполнения, но обычно они появляются при первых нескольких запусках и их легко исправить.
  • В каждой статье, которую я читал о дженериках, говорится, что иногда они просто не работают, и вам нужно время от времени использовать @SuppressWarnings(value="unchecked"). Как вы узнаете, выходите ли вы за пределы дженериков или просто глупы, и вам нужно больше думать?
  • Это может быть трудно применить @SuppressWarnings(value="unchecked")только к одной строке.
  • Я добавил несколько необычных дженериков в один из моих классов. Я знал нескольких программистов, которые могли бы улучшить класс до того, как я его сгенерировал, которые никогда не могли его коснуться и впоследствии получить чистую компиляцию.

Generics очистил мой код и слишком много раз предупреждал меня о проблемах, чтобы я отказался от него, но я также вижу увеличение времени разработки, дополнительное время, затрачиваемое на обучение, и программистов на Java, вынужденных работать на C #, C и Visual Basic. ..или Java 1.4. Я бы сосредоточился на написании кода, который могут понять ваши коллеги. Если вы можете использовать некоторые понятные дженерики, отлично. Я рассматриваю дженерики Java как возможность / проблему, которая еще не выяснена.

RalphChapin
источник