Есть ли что-нибудь по сути неправильно с длинными объектными цепочками вызова? [закрытый]

Вам нужно перебрать элементы массива и проверить его значение.

Принимая оператор return , вы выходите из функции, которая на самом деле не задана. Более того, вы хотите сосчитать и других 'a'.

let arr = ['a', 'b', 'c', 'a', 'a', ],
    a = 0,
    i;

for (i = 0; i < arr.length; i++) {
    if (arr[i] === 'a') {
        a = a + 1;
    }
}

console.log(a);

6
задан jaco0646 4 December 2018 в 16:29
поделиться

20 ответов

флаг является красным, и он говорит две вещи полужирным:

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

и одна вещь в круглых скобках:

  • используйте свойство, т.е. задачу. ActionPlan вместо task.getActionPlan ()

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

File clientFolder = task.DocumentsFolder;

это, по крайней мере, скроет древовидную структуру от кода вызова. Внутренне свойства могут быть похожими:

class Task {
    public File DocumentsFolder {
        get { return ActionPlan.DocumentsFolder; }
    }
    ...
}
class ActionPlan {
    public File DocumentsFolder {
        get { return ClientFile.DocumentsFolder: }
    }
    ...
}
class ClientFile {
    public File DocumentsFolder {
        get { return Client.DocumentsFolder; }
    }
    ...
}
class Client {
    public File DocumentsFolder {
        get { return ...; } //whatever it really is
    }
    ...
}

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

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

5
ответ дан 8 December 2019 в 13:51
поделиться
0
ответ дан 8 December 2019 в 13:51
поделиться

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

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

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

enum FolderType { ActionPlan, ClientFile, Client, etc }

interface IFolder
{
    IFolder FindTypeViaParent( FolderType folderType )
}

и каждый класс, который реализует IFolder, вероятно, просто, делает

IFolder FindTypeViaParent( FolderType folderType )
{
    if( myFolderType == folderType )
        return this;

    if( parent == null )
        return null;

    IFolder parentIFolder = (IFolder)parent;
    return parentIFolder.FindTypeViaParent(folderType)
}

Изменение должно сделать интерфейс IFolder:

interface IFolder
{
    FolderType FolderType { get; }
    IFolder Parent { get; }
}

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

[быстрые движения]

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

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

Как заметка на полях, можно хотеть считать DDD (Доменный Управляемый Дизайн) понятием агрегата и определить, кто крупные игроки. Что окончательный владелец является объектом, который ответственен? например, колеса автомобиля. В дизайне, который моделирует автомобиль, колеса являются также объектами, но они принадлежат автомобилю.

Возможно, это работает на Вас, возможно, это не делает. Как я сказал, это - просто выстрел в темноте.

0
ответ дан 8 December 2019 в 13:51
поделиться

Я указал бы на Закон Demeter, также.

И добавьте, что статья о Говорит, не Спрашивать

0
ответ дан 8 December 2019 в 13:51
поделиться

Другой важный побочный продукт объединения в цепочку является производительностью.

Это не имеет большого значения в большинстве случаев, но особенно в цикле Вы видите разумное повышение производительности путем сокращения косвенности.

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

0
ответ дан 8 December 2019 в 13:51
поделиться

В зависимости от Вашей конечной цели Вы, вероятно, хотели бы использовать Принципал Наименьшего количества Знания для предотвращения тяжелой связи и ценный Вы в конце. Как направляются, сначала любит выражаться.. "Только говорите со своими друзьями".

0
ответ дан 8 December 2019 в 13:51
поделиться

Этот вопрос очень близко к https://stackoverflow.com/questions/154864/function-chaining-how-many-is-too-many#155407

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

Хотя я слышу, что поклонники Python полагают, что объединение в цепочку большая забава. Это могло бы быть просто слухом... :-)

0
ответ дан 8 December 2019 в 13:51
поделиться
0
ответ дан 8 December 2019 в 13:51
поделиться

Это не плохо как таково, но Вы могли бы получить проблемы, читая это в 6-месячном. Или коллега мог бы получить поддержание задач / написание кода, потому что цепочка Ваших объектов вполне... длинна.

И я повторно подставляю это, Вы не должны представлять переменные в своем коде. Таким образом, объекты действительно знают все, что они должны спрыгнуть с метода к методу. (Здесь возникает вопрос, если Вы не сверхспроектировали немного, но кого я должен сказать?)

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

    task.getClientFromActionPlan();

Вы затем, конечно, могли использовать

    task.getClientFromActionPlan().getDocumentsFolder();

Намного более читаемый и в случае, если Вы делаете эти "удобные методы" право (т.е. для тяжелых используемых объектных цепочек), а тем более вводить ;-).

Edith говорит: Эти удобные методы, которые я предлагаю часто, содержат Nullpointer-проверку, когда я пишу им. Таким образом, даже можно бросить Nullpointers с хорошими сообщениями об ошибках в (т.е. "ActionPlan был пустым при попытке получить клиент от него").

0
ответ дан 8 December 2019 в 13:51
поделиться

Это - субъективный вопрос, но я не думаю, что существует что-то не так с ним в какой-то степени. Например, если цепочка расширяется вне читаемого aread редактора затем, необходимо представить некоторых местных жителей. Например, на моем браузере я не вижу последние 3 вызова, таким образом, я понятия не имею, что Вы делаете :).

0
ответ дан 8 December 2019 в 13:51
поделиться

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

Иначе я не вижу вреда в выполнении, что Вы делаете. Это, конечно, лучше, чем

ActionPlan AP = task.getActionPlan();
ClientFile CF = AP.getClientFile();
Client C = CF.getClient();
DocFolder DF = C.getDocumentsFolder();
0
ответ дан 8 December 2019 в 13:51
поделиться

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

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

0
ответ дан 8 December 2019 в 13:51
поделиться

Самый большой флаг в мире.

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

getClientFile () может возвратить пустой указатель, и затем getClient () перестанет работать и когда Вы ловите это, предполагая, что Вы - ловля попытки, у Вас не будет подсказки, относительно которой перестал работать.

0
ответ дан 8 December 2019 в 13:51
поделиться

Я соглашаюсь с плакатом, который упомянул Закон Demeter. То, что Вы делаете, создает ненужные зависимости от реализаций большого количества этих классов, и на структуре самой иерархии. Это wil делают очень трудным протестировать Ваш код в изоляции, так как необходимо будет инициализировать дюжину других объектов только для получения рабочего экземпляра класса, который Вы хотите протестировать.

1
ответ дан 8 December 2019 в 13:51
поделиться

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

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

В последнем случае затем "получить" методы в порядке, пока они используются авторизованными классами. То, как Вы осуществляете ту политику, является платформой - и зависимый процесса.

Таким образом в случае, где "получить" методы считают хорошо, все еще необходимо столкнуться с проблемой. И к сожалению, я думаю, что это зависит от класса, который перемещается по цепочке. Если для того класса уместно быть связанным со структурой (скажите, фабрика), то позволенный это быть. Иначе необходимо попытаться Скрыть Делегата.

Править: щелкните здесь для моего сообщения.

1
ответ дан 8 December 2019 в 13:51
поделиться

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

1
ответ дан 8 December 2019 в 13:51
поделиться

В первую очередь, укладка кода как этот может сделать это раздражающим для анализа NullPointerExceptions и ссылок проверки при продвижении в отладчик.

Кроме этого, я думаю, что все это сводится к этому: у вызывающей стороны должно быть все то знание?

Возможно, его функциональность могла быть сделана более универсальной; Файл мог затем быть передан в качестве параметра вместо этого. Или, возможно, ActionPlan даже не должен показывать, что его реализация основана на ClientFile?

2
ответ дан 8 December 2019 в 13:51
поделиться

Методы считывания и методы set являются злыми. Обычно постарайтесь не получать объект сделать что-то с ним. Вместо этого делегируйте саму задачу.

Вместо

Object a = b.getA();
doSomething(a);

сделать

b.doSomething();

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

3
ответ дан 8 December 2019 в 13:51
поделиться

Ну, каждая косвенность добавляет одну точку, где она могла пойти не так, как надо.

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

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

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

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

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

ActionPlan taskPlan = task.GetActionPlan();
ClientFile clientFileOfTaskPlan = taskPlan.GetClientFile();
Client clientOfTaskPlan = clientFileOfTaskPlan.GetClient();
File clientFolder = clientOfTaskPlan.getDocumentsFolder();

Я предполагаю, что это сводится к личному мнению об этом вопросе.

4
ответ дан 8 December 2019 в 13:51
поделиться

Да. Это не лучшая практика. С одной стороны, если существует ошибка, более трудно найти его. Например, Ваш обработчик исключений мог бы отобразить отслеживание стека, которое показывает, что у Вас есть NullReferenceException на строке 121, но какой из этих методов возвращает пустой указатель? Необходимо было бы вырыть в код для обнаружения.

0
ответ дан 8 December 2019 в 13:51
поделиться
Другие вопросы по тегам:

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