Возврат нового объекта против модифицирующего, переданного в качестве параметра - PullRequest
5 голосов
/ 12 августа 2010

Я натолкнулся на следующий фрагмент кода во время проверки кода.

Моя интуиция говорит мне, что это не соответствует правильному ООП.

Я думаю, что вместо LoadObjectМетод должен возвращать новый объект SomeObject вместо изменения переданного в него объекта.Хотя я не могу найти правильное объяснение того, почему это лучше.

Мое решение лучше?и если да, то почему?в частности, какие принципы или стандарты ООП нарушаются в данном примере кода (если есть)?

   public void someMethod()
    {
        ...
        var someObject = new SomeObject();
        LoadSomeObject(reader,someObject);
    }

    private void LoadSomeObject(SqlDataReader reader, SomeObject someObject)
    {
       someObject.Id = reader.GetGuid(0);
    }

Ответы [ 6 ]

8 голосов
/ 12 августа 2010

Нет ничего плохого в том, как написан код, так как вы изменяете свойство только для someObject.

Однако было бы так же правильно создать someObject в LoadSomeObject и вернуть его.

На данный момент оба варианта одинаково верны.

1 голос
/ 12 августа 2010

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

  • Функциональный - предназначен для создания новых экземпляров, а не для мутации других объектов.
  • Методический - предназначен для изменения состояния своего экземпляра хоста.

Хорошая идея, если вы хотите разделить логику манипулирования SomeObject, это создать тип SomeObjectBuilder с

 public void loadFromReader( SqlDataReader reader )

метод и

public SomeObject getValue ()

свойство

1 голос
/ 12 августа 2010

Я не гуру ОО, поэтому возьмите их с крошкой соли.

  1. объекты должны управлять собой / сами определять свое поведение, насколько это возможно. Обоснование этого очевидно, если вы когда-либо возглавляете слабую связь. Я вполне могу быть лучшим дизайнерским решением перенести детали LoadSomeObject в реализацию SomeObject, но это трудно обсудить для такого общего примера.

  2. Изменяемое состояние прекрасно в любом императивном коде (включая код OO), это основная «особенность» этих парадигм. OTOH, неизменное состояние имеет неопределяемые преимущества (я думаю, у нас есть несколько вопросов по этой теме здесь, в противном случае задайте любого сторонника FP), и наличие некоторых неизменяемых объектов не особенно не является OO.

Редактировать: Вы можете также передать читателя конструктору SomeObject.

0 голосов
/ 12 августа 2010

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

Я думаю, что это немного лучше, хотя (в большинстве случаев в любом случае):

public void someMethod()
{
    ...
    var someObject = new SomeObject();
    someObject.Load(reader);
}

И тогда, очевидно, в классе SomeObject у вас будет

public void Load(SqlDataReader reader)
{
   this.Id = reader.GetGuid(0);
}

Идея состоит в том, чтобы отдавать предпочтение методам экземпляров над статическими. Зачем создавать объект и передавать его данные, если вы можете просто заставить объект работать с собственными данными?

0 голосов
/ 12 августа 2010

Если LoadSomeObject собирается вернуть новый SomeObject, вы можете изменить имя метода, чтобы избежать путаницы. Может быть NewAndLoadSomeObject?

0 голосов
/ 12 августа 2010

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

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

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