Лучше иметь дублирование кода и иметь его быть очень простым/читаемым, или не иметь никакого дублирования (использующий дженерики), но быть намного более сложным?

Примечание: Этот ответ стар теперь. Блоки итератора были с тех пор добавлены к [1 110] VB.NET

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

ключевое слово C# static обычно переводится в Visual Basic с помощью Shared ключевое слово, но существует два места, где вещи становятся сбивающими с толку. Каждый - это, статическим классом C# является действительно Модуль в Visual Basic, а не Общем классе (Вы думали бы, что они позволили Вам кодировать его так или иначе в Visual Basic, но noooo). Другой то, что VB.NET действительно имеет его собственное Static ключевое слово. Однако Static имеет различное значение в VB.NET.

Вы используете Static ключевое слово в VB.NET для объявления переменной в функции, и когда Вы делаете переменная сохраняет свое состояние через вызовы функции. Это отличается, чем просто объявление частного статического участника класса в C#, потому что статический функциональный участник в VB.NET, как гарантируют, также будет ориентирован на многопотоковое исполнение, в котором компилятор переводит его для использования класса Монитора во время компиляции.

Итак, почему запись все это здесь? Ну, должно быть возможно создать допускающий повторное использование дженерик Iterator класс (или Iterator(Of T) в VB.NET). В этом классе Вы реализовали бы конечный автомат, используемый C#, с Yield() и Break() методы, которые соответствуют ключевым словам C#. Тогда Вы могли использовать статический экземпляр (в смысле VB.NET) в функции так, чтобы он мог в конечном счете сделать в значительной степени то же задание как C# yield приблизительно в том же объеме кода (отбрасывание класса implemenation самого, так как это было бы бесконечно допускающим повторное использование).

я не заботился достаточно об Урожае для попытки его сам, но это должно быть выполнимым. Однако это также совсем не тривиально, как член команды C# Eric Lippert называет это" самое сложное преобразование в компиляторе ".

я также приехал для веры, так как я записал первый проект этого более чем год назад, что это не действительно возможно значимым способом до Visual Studio, 2010 выходит, поскольку это потребовало бы отправки нескольких лямбд к классу Итератора, и так быть действительно практичными нам нужно .NET 4 поддержка многострочных лямбд.

8
задан darrickc 19 November 2009 в 19:28
поделиться

15 ответов

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

14
ответ дан 5 December 2019 в 04:38
поделиться

Excellent question; the generic answers may not fit for your situation. There are many factors decides your choice

  1. Current code quality
  2. Your product/project stage, early/growth/mature
  3. Developers' experience and skill
  4. Your project/product time to market

These are some of the crucial factors decides your choice. In my experience I realize duplicate business logic (middle tier) code is not good practice but the presentation layer can have duplicate codes.

When I am writing this I remember the article "Does Slow Growth Equal Death". Writing quality and non-duplicate code might take time but that shouldn't be a bottleneck for your business.

0
ответ дан 5 December 2019 в 04:38
поделиться

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

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

0
ответ дан 5 December 2019 в 04:38
поделиться

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

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

0
ответ дан 5 December 2019 в 04:38
поделиться

Зависит от ряда факторов:

  • Сколько кода дублируется? На самом деле это не проблема, если одни и те же пять строк появляются дважды, если для этого есть веская причина. Избегайте чрезмерной архитектуры кода, это может фактически снизить ремонтопригодность в долгосрочной перспективе, потому что следующий человек, работающий над кодом, может не оценить все тонкости в вашей архитектуре и сильно исказить ее.
  • Сколько копий того же кода ? Два - неплохо, но 10 (десятичное) не очень хорошо.
  • Почему код дублируется? Я столкнулся с рядом «дублирований», которые после того, как были созданы все требования, оказались совсем не дублированными, а лишь в некоторой степени похожими.

Так что мой ответ, возможно ...

1
ответ дан 5 December 2019 в 04:38
поделиться

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

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

1
ответ дан 5 December 2019 в 04:38
поделиться

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

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

2
ответ дан 5 December 2019 в 04:38
поделиться

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

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

4
ответ дан 5 December 2019 в 04:38
поделиться

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

4
ответ дан 5 December 2019 в 04:38
поделиться

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

9
ответ дан 5 December 2019 в 04:38
поделиться

Избегать дублирования кода - всегда хорошо. Единственное, от чего вам нужно остерегаться, - это Преждевременное обобщение .

Не нужно спешить, если вы получите пару похожих фрагментов кода. Это нормально - сидеть сложа руки, пока вы не выработаете хорошую модель.

Даже если вы позволите несколько примеров того, что вам нужно обобщить, может быть нормально, особенно, когда вещи немного более сложные и / или открытые. Будет проще сделать обобщение, если у вас есть 3-5+ примеров, а не один или два.

2
ответ дан 5 December 2019 в 04:38
поделиться

Я не понимаю, как термин "дженерики" связан с вашим вопросом. Тривиально и очевидно неправильно иметь отдельные классы для представления CollectionOfFoo и CollectionOfBar, так что это не может быть тем, о чем вы спрашиваете.

Вероятно, вам придется предоставить пример для каждой точки зрения, но вы ' Я все еще, вероятно, закрою за субъективность.

3
ответ дан 5 December 2019 в 04:38
поделиться

Рекомендация: Если код короткий, продублируйте его дважды, но не более того. .

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

Имейте в виду, что рефакторинг не делает ' t автоматически означает усложнение кода. Примите во внимание следующее:

class IntStack
{
    public int value;
    public IntStack next;
}

class StringStack
{
    public String value;
    public StringStack next;
}

class PersonStack
{
    public Person value;
    pubilc PersonStack Next;
}

Каждый раз, когда вам нужен стек для нового типа данных, вам нужно написать новый класс. Дублирование кода работает нормально, но предположим, что вы хотите добавить новый метод, может быть, метод «Push», который возвращает новый стек? Хорошо, теперь вы вынуждены добавить его в миллионы разных мест. Или вы можете использовать общий стек объектов, но тогда вы потеряете безопасность типов. Обобщения упростят архитектуру:

class Stack<T>
{
    public T value;
    public Stack<T> next;
}

Круто!

Хорошо, как насчет этого примера:

class Logger
{
    int logtype;
    public Logger(int logtype) { ... }

    public void Log(string text)
    {
        if (logtype == FILE) { ... }
        elseif (logtype == DATABASE) { ... }
        elseif (logtype == CONSOLE) { ... }
    }

    public void Clear()
    {
        if (logtype == FILE) { ... }
        elseif (logtype == DATABASE) { ... }
        elseif (logtype == CONSOLE) { ... }
    }

    public void Truncate(int messagesToTruncate)
    {
        if (logtype == FILE) { ... }
        elseif (logtype == DATABASE) { ... }
        elseif (logtype == CONSOLE) { ... }
    }
}

Хорошо, поэтому каждый раз, когда вы добавляете метод, вы должны проверять, какой тип регистратора вы используете. Болезненный и склонный к ошибкам. Обычно вы выделяете интерфейс (возможно, с помощью методов Log, Clear и Truncate), а затем создаете три класса (FileLogger, DatabaseLogger, ConsoleLogger).

Больше классов = больше архитектуры. Это легче или сложнее поддерживать в долгосрочной перспективе? В этом примере я бы сказал, что код теперь легче поддерживать, но YMMV.

6
ответ дан 5 December 2019 в 04:38
поделиться

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

0
ответ дан 5 December 2019 в 04:38
поделиться

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

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

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

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

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

0
ответ дан 5 December 2019 в 04:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: