Должен ли "свободный" (или цепной) метод быть неизменным?

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

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 в каждом из этих связанных методов. Они просто изменяют исходный объект и возвращают его (для удобства). Для меня это создает двусмысленность, потому что кто-то, называющий эти методы, может предположить, что они являются неизменяемыми (т.е. Они оставляют исходный объект неповрежденным, но возвращают измененный объект).

Означает ли это нарушение какой-либо передовой практики в отношении свободно-совместимых интерфейсов?

Ответы

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

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

Ответ 5

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

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