Перегрузки по сравнению с универсальными аргументами

Возможное решение целей, не обязательно заголовок вопроса:

Вместо того, чтобы подать специальное предложение всем, служите ему случайным наборам IP-адресов за один раз. Например, разделите пространство IP в 256 уникальных блоков, и в time=0, только позвольте людям с IP-адресами в первом блоке, и в time=5 секунды, позвольте людям от первого блока и второго блока..., пока прошлый временной интервал не наступает, и позвольте всем видеть соглашение. Одна идея рандомизировать его состояла бы в том, чтобы взять младшие значащие биты md5/sha их IP плюс немного соли на основе соглашения.

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

Объединение этого с некоторыми из других идей походит на хорошую идею.

8
задан devoured elysium 24 August 2009 в 05:04
поделиться

5 ответов

ИМХО, если вам нужны операторы if / switch, лучше перегрузить. Дженерики должны использоваться там, где реализация не зависит от конкретного типа, чтобы его можно было повторно использовать.

Итак, как общее правило:

  • перегрузка, если будет отдельная реализация для каждого типа
  • , используйте дженерики, если можете имеют единую реализацию, которая работает для всех возможных типов.
22
ответ дан 3 November 2019 в 12:50
поделиться

Запах кода.

Если у вас есть « какой-то if / switch », это запах кода, который просто кричит о полиморфизме . Это предполагает, что дженерики не решение этой проблемы. Обобщения следует использовать, когда код не зависит от конкретных типов , которые вы ему передаете.

Посмотрите это видео Google Tech Talks: « The Clean Code Talks - Наследование, полиморфизм и Тестирование ». Он конкретно касается того, о чем вы говорите.

7
ответ дан 3 November 2019 в 12:50
поделиться

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

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

Пример:

class SomeParser
{
    void Parse<T>(ParseStrategy<T> parseStrategy, T data)
    {
        //do some prep

        parseStrategy.Parse(data);

        //do something with the result;
    }
}

class ParseStrategy<T>
{
    abstract void Parse(T data);
}

class StringParser: ParseStrategy<String>
{
    override void Parse(String data)
    {
        //do your String parsing.
    }
}

class IntParser: ParseStrategy<int>
{
    override void Parse(int data)
    {
        //do your int parsing.
    }
}

//use it like so
[Test]
public void ParseTest()
{
    var someParser = new SomeParser();
    someParser.Parse(new StringParser(), "WHAT WILL THIS PARSE TO");
}

и тогда вы сможете передать любую из разработанных вами стратегий. Это позволит вам правильно изолировать ваши проблемы по нескольким классам и не нарушать SRP (принцип единой ответственности.

4
ответ дан 3 November 2019 в 12:50
поделиться

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

1
ответ дан 3 November 2019 в 12:50
поделиться

Здесь есть одна проблема - если вам требуются операторы if / switch для работы универсальных шаблонов, у вас, вероятно, более серьезная проблема. В этой ситуации наиболее вероятно, что общий аргумент не будет работать (правильно) для КАЖДОГО типа, а только для фиксированного набора типов, с которыми вы работаете. В этом случае гораздо лучше предоставить перегрузки для индивидуальной обработки определенных типов.

У этого есть много преимуществ:

  • Нет шансов неправильного использования - пользователь не может передать недопустимый аргумент
  • В вашем API больше ясности - очень очевидно, какие типы подходят
  • Generic методы более сложны в использовании и не так очевидны для начинающих пользователей
  • Использование универсального предполагает, что допустим любой тип - они действительно должны работать с каждым типом
  • Универсальный метод, вероятно, будет медленнее, с точки зрения производительности

Если ваш аргумент МОЖЕТ работать с любым типом, это становится менее очевидным. В этом случае я бы все равно подумал о включении перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

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

Если ваш аргумент МОЖЕТ работать с любого типа это становится менее ясным. В этом случае я бы все равно подумал о включении перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

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

Если ваш аргумент МОЖЕТ работать с любого типа это становится менее ясным. В этом случае я бы все равно подумал о включении перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

re пользователь не может передать недопустимый аргумент
  • В вашем API больше ясности - очень очевидно, какие типы подходят
  • Общие методы более сложны в использовании и не так очевидны для начинающих пользователей
  • Использование универсальный предполагает, что допустим любой тип - они действительно должны работать с каждым типом
  • Общий метод, вероятно, будет медленнее, с точки зрения производительности
  • Если ваш аргумент МОЖЕТ работать с любым типом, это становится менее очевидным. В этом случае я бы все равно подумал о включении перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

    re пользователь не может передать недопустимый аргумент
  • В вашем API больше ясности - очень очевидно, какие типы подходят
  • Общие методы более сложны в использовании и не так очевидны для начинающих пользователей
  • Использование универсальный предполагает, что допустим любой тип - они действительно должны работать с каждым типом
  • Общий метод, вероятно, будет медленнее, с точки зрения производительности
  • Если ваш аргумент МОЖЕТ работать с любым типом, это становится менее очевидным. В этом случае я бы часто все же рассматривал возможность включения перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

    и не так очевидно для начинающих пользователей
  • Использование универсального метода предполагает, что допустим любой тип - они действительно должны работать с каждым типом
  • Общий метод, вероятно, будет медленнее, с точки зрения производительности
  • Если ваш аргумент МОЖЕТ работать с любым типом это становится менее очевидным. В этом случае я бы часто все же рассматривал возможность включения перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

    и не так очевидно для начинающих пользователей
  • Использование универсального метода предполагает, что допустим любой тип - они действительно должны работать с каждым типом
  • Общий метод, вероятно, будет медленнее, с точки зрения производительности
  • Если ваш аргумент МОЖЕТ работать с любым типом это становится менее очевидным. В этом случае я бы все равно подумал о включении перегрузок, а также общего резервного метода для типов. Это обеспечивает повышение производительности, когда вы передаете методу "ожидаемый" тип, но вы все равно можете работать с другими, неожиданными типами.

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

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

    2
    ответ дан 3 November 2019 в 12:50
    поделиться