Должен ли кто-нибудь создать совместно используемый частный член класса или сохранить переменную в области метода, чтобы передать ее как второй аргумент метода?

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

public void SendOrder(Order order, XmlOrder xmlOrder, Insider insider)
{
    string customerCode = CustomerServices
                 .Get(insider.CustomerId)
                 .Code;

    OutputData outputData = CreateOutputData(order, xmlOrder, customerCode);
    CreateReservations(order, customerCode, outputData);
    PlaceOrder(order, xmlOrder, outputData, customerCode);
}
...
private void CreateReservations(Order order, string customerCode, OutputData outputData)
{
    ...
    try
    {
        ReservationServices.AddReservation(reservation);
    }
    catch (BusinessException ex)
    {
        Logger.Log(ex);
        outpuData.Status = Statuses.BusnessError;
        throw;
    }
}

(Это просто демонстрационный код, а не реальный)

Проблема заключается в том, что я должен был передать, например, outputData для других функций, только чтобы изменить его статус, если произойдет исключение или передайте метод CustomerCode нескольким функциям. Класс отвечает за отправку нескольких, не связанных сообщений в WebService, поэтому, когда я его создавал, я не планировал привязывать переменные, связанные с данным порядком, как состояние класса. Это хорошая практика, чтобы исключить такие переменные из функции и сделать их членами класса? Существуют ли какие-либо рекомендации для таких ситуаций? Каковы ваши методы и решения для таких проблем?

3 голоса | спросил helvy91 28 Jpm1000000pmSun, 28 Jan 2018 15:16:59 +030018 2018, 15:16:59

1 ответ


3
  

Следует ли создать совместно используемый частный член класса или сохранить переменную в области метода, чтобы передать ее как второй аргумент метода?

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

  

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

Мне кажется, что вы имеете дело с несколькими абстракциями здесь.

Иногда мы используем несколько параметров вместо создания формальной абстракции. Например, у нас есть координата x и y и использовать их как параметры в нескольких местах. Они должны восприниматься как пара - они, таким образом, являются неформальной абстракцией. Чтобы сделать формальную абстракцию, мы можем создать класс Point, который связывает x и y вместе. Теперь, когда мы проходили две переменные, мы пропускаем одну абстракцию. Единственная абстракция лучше, чем переменные пары в том, что клиент, использующий их, имеет меньше проблем, и Point более безопасен по типу и меньше ошибок, поскольку отдельные значения координат (например, int s)). Например, можно случайно поменять x и y; можно использовать x с неправильным y при работе с несколькими точками.

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

Когда вы решаете, нужно ли добавлять поля в существующий класс vs. create, создайте другой класс, вот один из способов подумать об этом. Если они логически разделяют абстракции, то у них должны быть отдельные классы. Если они являются одной и той же абстракцией, добавьте поля в класс. Проверьте время жизни отдельных полей. Если все они имеют одинаковое время жизни (и все время жизни как объект (экземпляры класса)), это согласуется с одной логической абстракцией. Однако, если некоторые из полей не инициализируются после того, как другие были правильно инициализированы (например, в конструкторе или методе init), а другие поля только инициализированы и действительны во время определенных последовательностей операций, то они относятся к логически раздельной абстракции, которая указывает отдельные классы.

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

Кроме того, можно обновить outputData (либо путем добавления полей к нему, либо путем создания обертки), используя приведенный выше анализ времени жизни, чтобы определить ) для захвата (order и xmlorder) и outputData и customerCode.

Таким образом, ваш код может выглядеть так:

public void SendOrder(OrderBundle orderBundle, Insider insider)
{
    string customerCode = CustomerServices
                 .Get(insider.CustomerId)
                 .Code;

    OutputDataBundle outputBundle = CreateOutputData(orderBundle, customerCode);
    outputBundle.CreateReservations();
    outputBunlde.PlaceOrder();
}

(независимо от типа качества и имен переменных).

ответил Erik Eidt 28 Jpm1000000pmSun, 28 Jan 2018 19:04:01 +030018 2018, 19:04:01

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132