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

Вы можете попробовать использовать библиотеку Bowser для этого:

console.log("You are using " + bowser.name + " version: " + bowser.version + " os: " + bowser.osname);

// Check for Chrome 20+
const isChrome = bowser.check({chrome: "20"}, true);
console.log("Chrome: ", isChrome);
<script src="https://cdnjs.cloudflare.com/ajax/libs/bowser/1.9.4/bowser.min.js"></script>

8
задан 4 revs, 2 users 100% 14 February 2010 в 09:49
поделиться

14 ответов

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

DirectoryComparer c = new DirectoryComparer();

int equality = c.Compare("C:\\Dir1", "C:\\Dir2");

... и поскольку Dana упоминает, существует интерфейс IComparer в .NET, который отражает этот шаблон.

IComparer. Сравните метод возвращает интервал, так как использование классов IComparer, прежде всего, с сортировкой. Общий шаблон, хотя приспосабливает проблему вопроса в этом:

  1. Конструктор инициализирует экземпляр с (дополнительно) "конфигурированием" параметров
  2. Сравните метод берет два параметра "данных", сравнивает их и возвращает "результат"

Теперь, результатом может быть интервал, bool, набор diffs. Безотносительно соответствий потребность.

12
ответ дан 5 December 2019 в 04:55
поделиться

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

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

0
ответ дан 5 December 2019 в 04:55
поделиться

Я определенно сделал бы второе.

Долгие действия в конструкторе прекрасны, если они на самом деле создают объект, таким образом, это применимо.

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

0
ответ дан 5 December 2019 в 04:55
поделиться

Если аргументы просто будут обработанными после того как затем, я не думаю, что они принадлежат или как аргументы конструктора или как состояние экземпляра.

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

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

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

Conceptualy конструктор является функцией, отображающей объектное представление на объект, который он представляет.

По определению выше Integer.valueOf (1) на самом деле больше конструктора, чем новое Целое число (1) потому что Integer.valueOf (1) == Integer.valueOf (1)., В любом случае это понятие также означает, что все аргументы конструктора и только аргумент конструктора, должны определить, равняется поведению объекта.

0
ответ дан 5 December 2019 в 04:55
поделиться

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

0
ответ дан 5 December 2019 в 04:55
поделиться

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

  • Выдержать сравнение снова - что если измененные каталоги?
  • Измените файлы, которые Вы сравниваете путем обновления участников.

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

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

Поэтому я предпочитаю:

DirectoryComparer = new DirectoryComparer(&Dir1,&Dir2);

DirectoryComparer-> Выдерживают сравнение ();

Или

DirectoryComparer = new DirectoryComparer();

DirectoryComparer-> Выдерживают сравнение (&Dir1, &Dir2);

1
ответ дан 5 December 2019 в 04:55
поделиться

Если Вы работаете с C#, Вы могли бы использовать дополнительные методы для создания метода для сравнения 2 каталогов, которые Вы присоедините к сборке в DirectoryClass, таким образом, это посмотрело бы некоторая вещь как:

Directory dir1 = new Directory("C:\.....");
Directory dir2 = new Directory("D:\.....");

DirectoryCompare c = dir1.CompareTo(dir2);

Это было бы намного более четкой реализацией. Больше на дополнительных методах здесь.

0
ответ дан 5 December 2019 в 04:55
поделиться

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

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

Что делает DirectoryComparer класс делает? Что, это - ответственность? С моей точки зрения (который является представлением программиста на C++) похоже, что Вы были бы более обеспечены только с использованием бесплатной функции, но я не думаю, что у Вас могут быть бесплатные функции в C#, не так ли? Я предполагаю, что Вы соберете файлы, которые отличаются в DirectoryComparer объект. Если так, Вы могли лучше создать что-то как массив файлов или эквивалентного класса, которым это называют соответственно.

1
ответ дан 5 December 2019 в 04:55
поделиться

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

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

2
ответ дан 5 December 2019 в 04:55
поделиться

Я согласовываю с общим чувством не выполнения долгих операций внутренних конструкторов.

Кроме того, в то время как на предмет дизайна, я рассмотрел бы изменение Вашего 2-го примера так, чтобы DirectoryComparer.Compare метод возвращает что-то другое, чем a DirectoryComparer объект. (Возможно, новый названный класс DirectoryDifferences или DirectoryComparisonResult.) Объект типа DirectoryComparer походит на объект, который Вы использовали бы для сравнения каталогов в противоположность объекту, который представляет различия между парой каталогов.

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

Например:

DirectoryComparer comparer = new DirectoryComparer(
    DirectoryComparerOptions.IgnoreDirectoryAttributes
);
DirectoryComparerResult result = comparer.Compare("C:\\Dir1", "C:\\Dir2");
3
ответ дан 5 December 2019 в 04:55
поделиться

Я думаю, что интерфейс мог бы быть тем, что Вы после. Я создал бы класс, чтобы представить каталог и иметь ту реализацию интерфейс DirectoryComparer. Тот интерфейс включал бы сравнить метод. Если C# уже имеет интерфейс Comparable, Вы могли бы также просто реализовать это.

В коде Ваш вызов был бы:

D1 = new Directory("C:\");
..
D1.compare(D2);
5
ответ дан 5 December 2019 в 04:55
поделиться

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

3
ответ дан 5 December 2019 в 04:55
поделиться

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

1
ответ дан 5 December 2019 в 04:55
поделиться

Я предпочитаю второй.

Я ожидаю конструктора к instanciate класс. Метод выдерживает сравнение, делает то, что он разработан, чтобы сделать.

10
ответ дан 5 December 2019 в 04:55
поделиться
Другие вопросы по тегам:

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