Цель финала и изолированный

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

безопасные пароли Принуждения

  • Pro: предотвратит атаки с подбором по словарю
  • Con: также предотвратит популярность, так как большинство пользователей не в состоянии помнить сложные пароли, даже если Вы объясняете им, как к легкому помнят их. Например, путем запоминания предложений: "Я купил 1 Apple за 5 центов в Молле", приводит к "Ib1Af5CitM".

Локауты после нескольких попыток

  • Pro: замедлит автоматизированные тесты
  • Con: легко заблокировать пользователей для третьих лиц
  • Con: Создание их персистентный в базе данных может привести к большому количеству процессов записи в таких огромных сервисах как Twitter или comparables.

Капчи

  • Pro: Они предотвращают автоматизированное тестирование
  • Con: Они используют вычислительное время
  • Con: "замедлит" пользовательский опыт
  • ОГРОМНЫЙ CON : Они не без барьеров

Простые проверки знаний

  • Pro: предотвратит автоматизированное тестирование
  • Con: "Простой" находится в глазу наблюдателя.
  • Con: "замедлит" пользовательский опыт

Различный вход в систему и имя пользователя

  • Pro: Это - одна техника, которая едва замечена, но в моих глазах довольно хорошее начало для предотвращения атак перебором.
  • Con: Зависит от пользовательского выбора двух имен.

Использование целые предложения как пароли

  • Pro: Увеличивает размер доступного для поиска пространства возможностей.
  • Pro: легче помнить за большинство пользователей.
  • Con: Зависьте от пользовательского выбора.

, Как Вы видите, "хорошие" решения, все зависят от пользовательского выбора, который снова показывает пользователя как самый слабый элемент цепочки.

Какие-либо другие предложения?

9
задан ChadD 31 May 2010 в 17:19
поделиться

3 ответа

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

Также из блога Патрика Смаккиа :

  • Управление версиями: когда класс изначально запечатан, он может измениться на незапечатанный в будущем без нарушения совместимости. (…)

  • Производительность: (…) если JIT-компилятор видит вызов виртуального метода с использованием запечатанных типов, JIT-компилятор может создать более эффективный код, вызвав метод невиртуально. (…)

  • Безопасность и Предсказуемость: класс должен защищать свое собственное состояние и не позволять себе когда-либо испортиться. Когда класс распечатан, производный класс может получать доступ и управлять состоянием базового класса, если какие-либо поля данных или методы, которые внутренне управляют полями, доступны и не являются закрытыми. (…)

Это все довольно веские причины - я фактически не знал о преимуществах производительности последствия, пока я не нашел его только сейчас :)

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

)

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

)

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

14
ответ дан 4 December 2019 в 07:23
поделиться

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

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

10
ответ дан 4 December 2019 в 07:23
поделиться

Джошуа Блох в своей книге «Эффективная Java» говорит об этом. Он говорит «документ на наследство или запретить его». Дело в том, что класс - это своего рода контракт между автором и клиентом. Разрешение клиенту наследовать от базового класса делает этот контракт намного более строгим. Если вы собираетесь наследовать от него, вы, скорее всего, переопределите некоторые методы, в противном случае вы можете заменить наследование на композицию. Какие методы разрешено переопределять и что вы должны делать для их реализации - следует задокументировать, иначе ваш код может привести к непредсказуемым результатам. Насколько я помню, он показывает такой пример - вот класс коллекции с методами

public interface Collection<E> extends Iterable<E> {    
  ...
  boolean add(E e);
  boolean addAll(Collection<? extends E> c);
  ...
}

Есть некая реализация, то есть ArrayList. Теперь вы хотите унаследовать от него и переопределить некоторые методы, чтобы он выводил на консоль сообщение при добавлении элемента. Теперь вам нужно переопределить как add , так и addAll , или только добавить ? Это зависит от того, как реализован addAll - работает ли он напрямую с внутренним состоянием (как ArrayList) или вызывает add (как AbstractCollection). Или может быть addInternal , который вызывается как add , так и addAll . Таких вопросов не было, пока вы не решили унаследовать от этого класса. Если просто использовать - не беспокоит. Итак, автор класса должен задокументировать его, если он хочет, чтобы вы унаследовали от его класса.

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

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

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

Итак, в основном комментарий: «Потому что класс не хочет иметь потомков, и мы следует уважать его пожелания ».

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

6
ответ дан 4 December 2019 в 07:23
поделиться