Re[27]: Мэйнстрим vs. Самосовершенствование :)))
От: Павел Кузнецов  
Дата: 02.11.04 15:46
Оценка: 50 (5) -1
AndrewVK:

> <...> чем такой вариант:

>
> public interface ISortable
> {
>     void Sort();
> }
>
> public class SomeList : IList, ISortable
> {
>     ...
>     public void Sort() {...}
> }
>
> ...
> someListInstance.Sort();
>

>
> хуже такого:

По-моему, ниже опечатка, и ISupportSort от IList унаследован быть не должен.

>
> public interface ISupportSort : IList
> {
>     int CompareElements(int index1, int index2);
>     void Exchange(int index1, int index2);
> }
>
> public class SomeList : IList, ISupportSort
> {
>     ...
>     int ISupportSort.CompareElements(int index1, int index2) {}
>     void ISupportSort.Exchange(int index1, int index2) {}
> }
>
> ...
> SomeSortFunction(someListInstance);
>


Имхо, в последнем варианте функция сравнения элементов в ISupportSort быть не должна по нескольким причинам, но это уже вопрос отдельный, хотя и похожий на обсуждаемый.

Первый вариант хуже по нескольким причинам:

Сортировка не является основной функциональностью SomeList

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

В частности:
  • Сохраняется ли в результате сортировки порядок элементов, для которых CompareElements возвращает 0 (т.е. они "равны" с точки зрения функции сравнения). Для некоторых использований это является критичным моментом.
  • Какова алгоритмическая сложность используемого алгоритма. Не секрет, что разные алгоритмы сортировки работают принципиально по-разному на разных входных данных. Например, классическая "быстрая сортировка" очень плохо подходит для "почти упорядоченных" последовательностей, в том смысле, что она работает намного хуже других алгоритмов, если не на месте стоят всего несколько элементов. И во многих случаях только пользователь может знать характер "входных" данных.
  • Каковы требования к памяти используемого алгоритма. Для большинства использований, особенно если используются "простые" алгоритмы, типа той же "быстрой сортировки", это не суть важно, но там, где это имеет значение, обойти эту проблему весьма непросто.
    И т.д., и т.п.

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

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

    Есть множество аналогичных алгоритмов, которые нужны пользователю

    И если пытаться тем или иным образом включить все эти алгоритмы в SomeList, возникает множество проблем, аналогичных описанным для сортировки, плюс еще некоторые.
  • Часть из этих алгоритмов нуждается в том же интерфейсе, что и сортировка. Например, в ряде приложений необходимым является использование так называемой "частичной сортировки", т.е. алгоритма, приводящего последовательность к такому виду, что все элементы "меньшие" заданного, находятся "слева" от него, а все "большие" — "справа". По сути этот алгоритм является одним из шагов "быстрой сортировки".
  • Другие алгоритмы могут отличаться по назначению. Например, поиск. К поиску необходимость возможности "настройки" пользователем применима в неменьшей степени, чем к сортировке. И в неменьшей степени очевидно, что предоставить в классе SomeList, для которого поиск является "вспомогательной" функциональностью, все нужные пользователю, но вполне аналогичные алгоритмы не реально.
  • В любом случае, разработчики "библиотеки" предусмотреть все нужные пользователю алгоритмы не могут принципиально.

    Повторное использование алгоритмов

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

    Расширяемость множества алгоритмов

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

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

    Никаких из этих проблем не возникает, если "вспомогательные" алгоритмы (то есть не основные для самого класса, в данном случае SomeList) будут вынесены за пределы класса.
    Posted via RSDN NNTP Server 1.9 gamma
  • Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.