Какой лучший (самый полезный) интерфейс вы написали? - PullRequest
4 голосов
/ 30 ноября 2008

Заголовок в основном это прописывает. Какие интерфейсы вы написали, что заставляет вас гордиться и вы используете много. Я думаю, у парней, которые написали IEnumerable<T> и, что не менее важно, IQueryable<T>, было хорошее чувство после их создания.

Ответы [ 6 ]

5 голосов
/ 30 ноября 2008

Строго интерфейс? Или просто API? Я вроде доволен тем, как сработал универсальный оператор (доступно здесь ) - я регулярно вижу людей, спрашивающих об использовании операторов с шаблонами, поэтому я ' Я рад, что это удобный ответ для многих людей. Это может быть немного проще в C # 4.0 , но я очень сомневаюсь, что это будет так же быстро - у дерева DLR / динамического материала есть издержки.

Я также очень рад, что в Push LINQ было полезно, что Джон уже упоминал; -p

3 голосов
/ 30 ноября 2008

Я доволен дизайном интерфейса в основе Push LINQ . Это очень простой интерфейс, но с его помощью вы можете делать разные интересные вещи. Вот определение (из памяти, но оно будет, по крайней мере, довольно близко):

public interface IDataProducer<T>
{
    event Action<T> DataProduced;
    event Action EndOfData;
}

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

Три достопримечательности:

  • Имя отстой. Я хочу переименовать его, и я получил несколько хороших отзывов, но имя еще не пришло.
  • Обработчики событий не следуют стандартным соглашениям .NET о наличии аргументов отправителя / события. В этом случае это не имеет особого смысла.
  • Многоадресный характер событий делает его идеальным для расчета нескольких агрегатов и т. Д. Все это бесплатно.
1 голос
/ 01 декабря 2008

Для работы с MVP-шаблонами у меня есть несколько базовых интерфейсов фреймворка:

public interface IValidatable {
  bool IsValid { get; set; }
  void ShowValidationFailureMessage(string message);
}

public interface ISubmitable {
  event EventHandler Submit;
  void ShowSubmitFailureMessage(string message);
  void ShowSubmitSuccessMessage(string message);
}

public interface ICancelable {
  event EventHandler Cancel;
}

С этими 3 интерфейсами я могу написать Presenter, который имеет эти общие операции (которые охватывают в основном все операции с формами) Например:

public interface ILogin : IValidatable, ISubmitable, ICancelable {
  string Username { get; set; }
  string Password { get; set; }
}

Затем вы можете создать докладчика и удалить его.

1 голос
/ 30 ноября 2008

Полагаю, у парней, которые написали IEnumerable…, было хорошее чувство после создания [it].

Я не уверен. IEnumerable был довольно неудачным, поскольку интерфейсы идут. Это видно из того факта, что IEnumerable<T>, его общий аналог, на самом деле предлагает совершенно другой интерфейс. (Ну, «другое» - это не хорошее слово; в основном, оно добавляет одноразовость и лишает акцента совершенно бесполезный Reset метод; однако этот метод, конечно, все еще присутствует.)

Кроме того, похожие языки, имеющие сходные конструкции (на ум приходит Java), имеют гораздо лучшую, более расширяемую конструкцию для удовлетворения тех же потребностей (и более). Например, итераторы Java могут быть расширены, чтобы быть двунаправленными или позволять изменять доступ (тогда как IEnumerable всегда только для чтения).

РЕДАКТИРОВАТЬ: Поскольку в комментариях столько противоречий, позвольте мне уточнить. Я не говорю, что IEnumerable (или IEnumerator) являются плохими интерфейсами. Они адекватны. Тем не менее, они могли бы быть сделаны лучше. Если ничего другого, то, по крайней мере, метод Reset выглядит как беспорядок.

Терье сказал, что он «использует это все время» - это точно моя точка зрения! IEnumerable является ключевым интерфейсом всей платформы .NET. Это вездесущий. Без него не было бы .NET. Поэтому слишком много, чтобы попросить совершенный интерфейс?

«Адекватный» - это еще одно слово для неудачи.

0 голосов
/ 01 декабря 2008

Это интерфейс ActionScript 3, который послужил основой нашего нового поведения Flash Player в as3.

public interface IDisposable {
  public function dispose():void;
}

Как и следовало ожидать, метод dispose должен закрывать любые ресурсы и удалять любые ссылки на все, что возможно.

Программисты на C ++ могут смеяться над этим «инновационным» интерфейсом (что вполне справедливо), но в as3 возникло множество проблем, связанных с управлением памятью во Flash. Все эти проблемы - "старая шляпа" для многих скомпилированных языков, но программисты ActionScript только сейчас сталкиваются с этими проблемами впервые.

Да, это все еще язык для сбора мусора. Но, что бы там ни было, «ручного удержания» намного меньше, чем в ActionScript 2, о чем свидетельствует необходимость этого интерфейса.

0 голосов
/ 30 ноября 2008

Я работаю над системой проверки, которую планирую вскоре выпустить в сообщество. По сути, это реализация шаблона Specification .

Базовый интерфейс предназначен для функционального характера:

public interface ICheckable<T>
{
    CheckResult Apply(T target);
}

CheckResult - это struct, представляющее значение в трех состояниях: Passed, Failed и Ignored. Все преобразования и операторные перегрузки используются для обработки значения Boolean.

Это позволяет валидаторам выражать «У меня нет мнения» вместо того, чтобы возвращать вводящее в заблуждение значение true (думаю, RangeValidator означает, что пустое поле является действительным, поэтому оно хорошо сочетается с RequiredFieldValidator).

Композиция происходит естественным образом и выполняется со статическими классами в стиле Linq. Каждая точка в проверке является неявной And следующей операции:

public static ICheckable<T> Add<T>(this ICheckable<T> check, ICheckable<T> otherCheck)
{
    return new Check<T>(t => check.Apply(t) && otherCheck.Apply(t));
}

public static ICheckable<T> Either<T>(this ICheckable<T> check, ICheckable<T> firstCheck, ICheckable<T> secondCheck)
{
    return check.Add(t => firstCheck.Apply(t) || secondCheck.Apply(t));
}

public static ICheckable<T> Not<T>(this ICheckable<T> check, ICheckable<T> negatedCheck)
{
    return check.Add(t => !negatedCheck.Apply(t));
}

Методы расширения работают хорошо:

public static ICheckable<int> Percentage(this ICheckable<int> check)
{
    return check.Add(n => n >= 0 && n <= 100);
}

public static ICheckable<T> GreaterThanOrEqualTo<T>(this ICheckable<T> check, T value) where T : IComparable<T>
{
    return check.Add(t => t.CompareTo(value) >= 0);
}

public static ICheckable<T> LessThanOrEqualTo<T>(this ICheckable<T> check, T value) where T : IComparable<T>
{
    return check.Add(t => t.CompareTo(value) <= 0);
}

public static ICheckable<T> Range<T>(this ICheckable<T> check, T minimum, T maximum) where T : IComparable<T>
{
    return check.GreaterThanOrEqualTo(minimum).LessThanOrEqualTo(maximum);
}

// RangeExcludeMinimum
// RangeExcludeMaximum
// RangeExclusive

Каждая операция включает в себя перегрузки, которые принимают лямбда проверки построения:

public static ICheckable<T> Add<T>(this ICheckable<T> check, Func<ICheckable<T>, ICheckable<T>> makeCheck)
{
    return check.Add(makeCheck(new IgnoredCheck<T>()));
}

Таким образом, вы можете сделать синтаксис следующим образом:

ICheckable<int> check;

check.Add(i => i.Percentage().GreaterThan(50).Even());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...