Быстрые интерфейсы и текучие абстракции

Это также происходит со строками:

>>> s = b = 'somestr'
>>> s == b, s is b, id(s), id(b)
(True, True, 4555519392, 4555519392)

Теперь все кажется прекрасным.

>>> s = 'somestr'
>>> b = 'somestr'
>>> s == b, s is b, id(s), id(b)
(True, True, 4555519392, 4555519392)

Это тоже ожидается.

>>> s1 = b1 = 'somestrdaasd ad ad asd as dasddsg,dlfg ,;dflg, dfg a'
>>> s1 == b1, s1 is b1, id(s1), id(b1)
(True, True, 4555308080, 4555308080)

>>> s1 = 'somestrdaasd ad ad asd as dasddsg,dlfg ,;dflg, dfg a'
>>> b1 = 'somestrdaasd ad ad asd as dasddsg,dlfg ,;dflg, dfg a'
>>> s1 == b1, s1 is b1, id(s1), id(b1)
(True, False, 4555308176, 4555308272)

Теперь это неожиданным.

13
задан Lasse Vågsæther Karlsen 11 January 2009 в 20:04
поделиться

8 ответов

Текучая абстракция является абстракцией, где детали базовой действительности часто "просачиваются через".

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

А простым примером "утечки" в абстракции мог бы быть обычный тип плавающий. Это, кажется, представляет общие вещественные числа, и можно использовать его для выполнения основных вычислений. Но в некоторое время Вы встречаетесь со сценарием где 1/3*3! = 1 или 1 + 10^-20 = 1. Это - когда фактическая реализация детализирует утечку через и повреждения абстракции.

18
ответ дан 1 December 2019 в 17:19
поделиться

Спасибо парни.

Замечательное описание.

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

, Например, как плакат, кто отправил пример проверки (я написал код, подобный этому прежде).

1
ответ дан 1 December 2019 в 17:19
поделиться

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

я сначала встретился с быстрыми интерфейсами в 1990, когда полиция Интерфейса Modula-3 (я не составляю это), потребовал, чтобы все методы инициализации возвратили инициализированный объект. Я полагаю, что это использование предшествует чеканке термина "быстрый интерфейс".

3
ответ дан 1 December 2019 в 17:19
поделиться

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

, Например, в NValidate, я сделал это для упрощения проверки параметра:

public City GetCity(string zipCode)
{
   zipCode.Assert("zipCode").IsNotNullOrEmpty().HasLength(5,10).Matches("\\d[5]-\\d[4]");
   // Continue processing
}

я не могу говорить с текучими абстракциями, все же.

1
ответ дан 1 December 2019 в 17:19
поделиться

Вот регулярный повседневный интерфейс:

public interface NotFluent
{
  void DoA();
  void DoB();
  void DoC();
}

И вот быстрый интерфейс:

public interface Fluent
{
  Fluent DoA();
  Fluent DoB();
  Fluent DoC();
}

наиболее заметное отличие - то, что, когда мы возвращаем пустоту, мы возвращаем вместо этого экземпляр интерфейсного типа. То, что понято, - то, что возвращенный интерфейс является ТЕКУЩИМ ЭКЗЕМПЛЯРОМ, не новым экземпляром того же типа. Конечно, это не осуществимо, и в случае неизменных объектов (как строка) это - другой экземпляр, но может считаться тем же экземпляром, только обновленным.

Вот примеры их использования:

NotFluent foo = new NotFluentImpl();
foo.DoA();
foo.DoB();
foo.DoC();

Fluent bar = new FluentImpl();
bar.DoA().DoB().DoC();

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

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

Быстрым интерфейсом является API, который позволяет Вам писать код, который читает более или менее как нормальный английский язык. Например:

Find.All.Questions(Where.IsAnswered == true);

Объединение в цепочку метода обычно используется в качестве части реализации, но существует больше к нему, чем это. К кавычке Fowler :

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

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

26
ответ дан 1 December 2019 в 17:19
поделиться

Быстрый интерфейс термин, который ввел Eric Evans и это - просто другое название объединения в цепочку метода. Martin Fowler записал пара из статьи на этом предмете, но это примерно похоже на это:

m_Window = window::with()
    .width(l_Width)
    .height(l_Height)
    .title("default window")
    .left(200)
    .top(200)
.create();

интерфейс Fluent обычно используется для создания названный параметрами на языке, который не поддерживает их (Именованная Идиома Параметра в C++, например), или на Предметно-ориентированных языках для создания чтения кода более бегло.

я видел, что они используются для всего из библиотек обработки изображений, к библиотекам регулярных выражений, 3D библиотекам. Другие примеры включают конструкцию древовидных структур, списков или другого datastructures. Все, что требует конструкции сложных объектов (загрузка параметров) может использовать Быстрые Интерфейсы для создания ее более читаемой. Например, сравните предыдущий пример с вызовом функции CreateWindow:

 ::CreateWindow(
      "Window class", 
      "Window title", 
      dwStyle, X, Y, 
      nWidth, nHeight, 
      hWndPant, hMenu, 
      hInstance, NULL
 );
9
ответ дан 1 December 2019 в 17:19
поделиться

Нил Форд хорошо объясняет и дает примеры Fluent Interface в своей книге «Продуктивный программист».

Традиционный объект или «компонент» с геттерами / сеттерами:

Car car = new CarImpl();
MarketingDescription des = new MarketingDescriptionImpl();
desc.setType("Box");
desc.setSubtype("Insulated");
desc.setAttribute("length", "50.5");
desc.setAttribute("ladder", "yes");
desc.setAttribute("lining type", "cork");
car.setDescription(desc);

Удовлетворите ту же потребность с помощью свободного интерфейса:

Car car = Car.describedAs()
  .box()
  .length(50.5)
  .type(Type.INSULATED)
  .includes(Equipment.LADDER)
  .lining(Lining.CORK);
1
ответ дан 1 December 2019 в 17:19
поделиться