Должен ли «плавный» (или цепной) метод быть неизменным? - PullRequest
15 голосов
/ 15 июля 2011

Скажем, у меня есть класс с некоторыми свойствами и некоторыми методами для управления этими свойствами:

public class PersonModel
{
    public string Name { get; set; }
    public string PrimaryPhoneNumber { get; set; }

    public void LoadAccountInfo(AccountInfo accountInfo)
    {
        this.Name = accountInfo.Name;
    }

    public void LoadPhoneInfo(PhoneInfo phoneInfo)
    {
        this.PrimaryPhoneNumber = phoneInfo.PhoneNumber;
    }
}

Типичное использование будет:

var model = new PersonModel();
model.LoadAccountInfo(accountInfo);
model.LoadPhoneInfo(phoneInfo);

Я думаю, было бы здорово сделатьметоды цепочки:

    public PersonModel LoadAccountInfo(AccountInfo accountInfo)
    {
        this.Name = accountInfo.Name;
        return this;
    }

    public PersonModel LoadPhoneInfo(PhoneInfo phoneInfo)
    {
        this.PrimaryPhoneNumber = phoneInfo.PhoneNumber;
        return this;
    }

Тогда использование будет:

var model = new PersonModel()
    .LoadAccountInfo(accountInfo)
    .LoadPhoneInfo(phoneInfo);

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

Ответы [ 5 ]

4 голосов
/ 15 июля 2011

Нет, вполне разумно мутировать переданный объект. Все свободно используемые методы NHibernate работают таким образом (например, когда они изменяют объект FluentConfiguration).

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

3 голосов
/ 15 июля 2011

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

1 голос
/ 15 июля 2011

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

http://blogs.msdn.com/b/laurionb/archive/2009/02/16/immutable-objects-in-fluent-interfaces-a-lesson-from-functional-programming.aspx

Однако, глядя на Moq в качестве примера, объекты не являются неизменяемыми.

Я не думаю, что здесь есть "лучшая практика". Как сказал @Ray Toal, это отдельная проблема.

1 голос
/ 15 июля 2011

Вся прелесть беглого метода заключается в возвращении одного и того же измененного объекта.

0 голосов
/ 15 июля 2011

Объекты являются ссылочным типом, и когда вы специально просите его «вернуть это», почему вы ожидаете, что он вернет что-то другое?

Не нарушает никакой лучшей практики. Фактически, если у вас нет причины, нет необходимости клонировать объект.

...