Существуют ли какие-либо реальные недостатки цепочки самореферентных методов?

14

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

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

Мой вопрос: может ли применение предыдущего соглашения считаться плохой практикой или злоупотреблением? Почему? Я не думаю, что есть какие-либо недостатки в производительности или есть?

dukeofgaming
источник
2
Посмотрите на этот вопрос для хорошего обсуждения programmers.stackexchange.com/questions/48419/…
KeesDijk
@KeesDijk Спасибо, я немного отредактировал свой вопрос, так что он не похож на этот, так как меня больше интересует случай цепочки методов из того же класса
dukeofgaming
1
в SO мне сказали, что цепочка не для C ++ - stackoverflow.com/questions/5760551/… - о чем вы думаете?
Кагали-сан
1
@mhambra Похоже, что вам нужно быть осторожным только при реализации цепочки методов и определить четкие стандарты для этого.
dukeofgaming

Ответы:

10

нет

Как указывает Кент Бек , код читается гораздо чаще, чем пишется.

Если цепочка методов делает ваш код более читабельным, используйте цепочку методов.

Стивен А. Лоу
источник
1
Отличная книга .. +1
Рейн Хенрикс
5
НО , что если вы единственный способ найти цепочку, более читабельную? Если это вопрос sytilistic, то вам придется придерживаться набора соглашений кодирования: это означает, что для обеспечения согласованности, писать так же, как существующий код.
coredump
@coredump Звучит так, что оператору уже было сказано сделать это, но я думаю, что Стивен просто говорил это, если цепочка методов делает его более читабельным.
Panzercrisis
1
Оператору @Panzercrisis было сказано воздерживаться от использования цепочки методов из-за удобства и семантики. Ответ Стивена в основном гласит «делай это в любом случае» и рассматривай только удобочитаемость кода OP, не учитывая мнение или последовательность команды. Что, если OP захочет переписать каждый существующий класс в проекте так, чтобы он соответствовал его вкусу в отношении читабельности кода? Вот как я понимаю аргумент удобства / семантики: должна быть «техническая» причина иметь цепочку методов (кстати, этот аргумент также звучит так, как будто другой человек оправдывает свои предпочтения)
coredump
9

Да, есть недостатки

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

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

Допустимый вариант использования: специальные запросы к базе данных

Библиотеки классов существуют почти во всех языках, что позволяет запрашивать базу данных, не прибегая к жестко закодированному SQL. Возьмем Entity Framework для .NET в качестве примера:

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

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

Неверный вариант использования: синтаксический сахар для настройки свойств

Теперь давайте использовать тот же шаблон с Postклассом:

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

Теперь давайте посмотрим, как вы будете использовать этот класс:

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

Когда я вижу этот код, я сразу же задаю вопрос: «После вызова SetBodyзапрашивает ли он базу данных? Нужно ли вызывать другой метод, чтобы сказать« Я сделал? »»

Что связывают вызовы метода с кодом с помощью Postкласса?

  1. У меня сложная настройка
  2. Каждый вызов метода основан на предыдущем

Является ли это на самом деле так? Нет . PostКласс никак не имеет сложную настройку. Установка заголовка, даты создания и тела не основывается на более сложной конечной цели. Вы разбили квадратный колышек в круглое отверстие.

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

Когда ваши коллеги сказали:

Свободные интерфейсы должны быть реализованы не только для удобства, но и для семантики

Они были абсолютно правы. Свободный интерфейс или цепочка методов сообщают о себе что-то, что может быть неверным.

Грег Бургардт
источник
Это предполагает, что цепочка методов и сложная конфигурация всегда идут рука об руку. Это разные сущности, и присутствие одного не должно заставлять вас предполагать другое.
Джек,
Это не просто «сложная конфигурация», это также «последующие вызовы методов, основанные на предыдущем». У цепочки методов есть мета-связь, которая не всегда соответствует цели класса.
Грег Бургардт
1
Последующее построение вызовов методов из предыдущих также отличается от цепочки методов, и я не думаю, что трактовка синтаксиса цепочки методов как сильной связи для семантики зависимых от порядка серий побочных операций является надежной или полезной. Это синтаксическая стенография, не более того. Используйте его там, где он делает вещи короче и более читабельными.
Джек,
1
Я понимаю , что вы думаете , метод цепочки отдельно, но я говорю , что другие программисты , которые не были в вашей голове и использовать другие библиотеки классов , которые действительно реализуют метод цепочки по этим причинам может в конечном итоге сделать предположения о вашем коде, которые не соответствуют действительности. Имейте в виду, что цепочка методов может подразумевать то, что вы, автор кода, не намеревались. Код, который общается четко, так же важен, как и код, который легко читать. Не жертвуйте одним ради другого.
Грег Бургардт
1
When an object's methods always return the object, it communicates a couple of things- думаю это личное мнение; трудно утверждать, что каждый, кто смотрит на цепочечные методы, примет одно и то же.
Сэм Дюфель
1

Основным недостатком является потеря ясности. Например:

x.foo();
x.bar();
x.baz();

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

x.foo()
 .bar()
 .baz();

Во-первых, не ясно, что barи bazработают с объектами того же типа, что xи вы, если только вы точно не знаете, что xкласс является единственным классом с этими методами. Даже если это так, непонятно, как работают методы xили новые объекты.

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

Doval
источник
0

Рассмотрим все стилистические элементы языков программирования (в отличие от машинного языка ручного кодирования), и это ослабляет аргумент «семантика, а не удобство».

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

обкрадывать
источник