Как я привожу доводы против ввода Утки на языке со строгим контролем типов как Java?

Вы можете использовать рекурсивный метод и использовать обратный вызов setState для следующей итерации:

dataFetch = async () => {
  // ...
  this.setState({
    message: `Loading ${Number.parseFloat(
      (page * 100) / (maxPages || data.max_pages),
    )}%`,
  }, () => {
    InteractionManager.runAfterInteractions(() => {
      this.dataFetch(page + 1, data.max_pages);
    });
  });
};

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

6
задан sharptooth 31 March 2009 в 08:04
поделиться

11 ответов

При высказывании "утиного ввода на языках со строгим контролем типов", Вы на самом деле означаете "подражать (выделяют подтипы) в полиморфизме на статически типизированных языках".

Дело не в этом плохо, когда у Вас есть объекты данных (DTOs), которые не содержат поведения. Когда у Вас действительно есть полноценная модель OO (спросите себя, если это действительно имеет место), затем, необходимо использовать полиморфизм, предлагаемый языком в соответствующих случаях.

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

На самом деле Вы сказали это обоснованно хорошо тут же.

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

Способ, которым Вы знаете, что это - плохая идея, состоит в том, что это делает код хрупким: если Вы используете это и изменения иерархии типа, то это, вероятно, повреждает тот экземпляр - расчески везде, это происходит. Кроме того, Вы затем теряете преимущество строгого контроля типов; компилятор не может помочь Вам путем фиксации ошибок заранее. (Это несколько походит на проблемы, вызванные преобразованиями типа в C.)

Обновление

Позвольте мне расширить это немного, с тех пор из комментария кажется, что я не был довольно ясен. Причина Вы используете преобразование типа в C, или instanceof, это, что Вы хотите сказать "как будто": используйте это foo как будто это был a bar. Теперь, в C, нет никакой информации о типе выполнения вокруг вообще, таким образом, Вы просто работаете без сети: при преобразовании типа чего-то сгенерированный код собирается рассматривать тот адрес, как будто он содержал конкретный тип независимо от того, что, и необходимо только надеяться, что он вызовет ошибку времени выполнения вместо того, чтобы тихо повредить что-то.

Утка, вводящая просто, повышает это до нормы; на динамическом, языке со слабым контролем типов как Ruby или Python или Smalltalk, все - невведенная ссылка; Вы снимаете сообщения в нем во времени выполнения и видите то, что происходит. Если это понимает конкретное сообщение, это "идет как утка" - это обрабатывает его.

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

На языке со строгим контролем типов как Java у Вас не может действительно, строго, быть утиного ввода вообще: необходимо сказать компилятор, что вводит, Вы собираетесь рассматривать что-то как. Можно получить что-то как утиный ввод при помощи бросков типа, так, чтобы можно было сделать что-то как

Object x;   // A reference to an Object, analogous to a void * in C

// Some code that assigns something to x

((FoodDispenser)x).dropPellet();          // [1]

// Some more code

((MissleController)x).launchAt("Moon");   // [2]

Теперь во время выполнения, Вы прекрасны, целый x - своего рода FoodDispenser в [1] или MissleController в [2]; иначе бум. Или неожиданно, никакой бум.

В Вашем описании Вы защищаете себя при помощи расчески else if и instanceof

 Object x ;

 // code code code 

 if(x instanceof FoodDispenser)
      ((FoodDispenser)x).dropPellet();
 else if (x instanceof MissleController )
      ((MissleController)x).launchAt("Moon");
 else if ( /* something else...*/ ) // ...
 else  // error

Теперь, Вы защищены от ошибки времени выполнения, но у Вас есть ответственность выполнения чего-то разумного позже, в else.

Но теперь предположите внесение изменения в код так, чтобы 'x' мог взять типы 'FloorWax' и 'DessertTopping'. Теперь необходимо пройти весь код и найти все экземпляры той расчески и изменить их. Теперь код является "хрупким" - изменяется в требовании среднем большом количестве изменений кода. В OO Вы стремитесь сделать код менее хрупким.

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

  public interface VeebleFeetzer { /* ... */ };
  public class FoodDispenser implements VeebleFeetzer { /* ... */ }
  public class MissleController implements VeebleFeetzer { /* ... */ }
  public class FloorWax implements VeebleFeetzer { /* ... */ }
  public class DessertTopping implements VeebleFeetzer { /* ... */ }

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

VeebleFeetzer x;   // A reference to anything 
                   // that implements VeebleFeetzer

// Some code that assigns something to x

x.dropPellet();

// Some more code

x.launchAt("Moon");
8
ответ дан 8 December 2019 в 04:31
поделиться

хм...

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

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

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

Таким образом, здесь... вонючая подсказка, как Charlie указал, использование instanceof. Во многом как статические или другие вонючие ключевые слова, каждый раз, когда они появляются, нужно попросить, чтобы "Я сделал правильную вещь здесь?", не, что они - inhertitly неправильно, но они - oftenly, используемый для взламывания посредством плохого или плохого подогнанного дизайна OO.

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

Мой один ответ строки состоял бы в том, что Вы теряете одно из основных преимуществ ООП: полиморфизм. Это уменьшает время для разработки нового кода (разработчики любят разрабатывать новый код, так, чтобы помог аргументу :-)

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

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

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

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

Это не так много утки, вводящей, как это - просто надлежащий объектно-ориентированный стиль; действительно, способность разделить класс A на подклассы и назвать тот же метод на классе B и иметь его делает что-то еще - весь смысл наследования на языках.

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

6
ответ дан 8 December 2019 в 04:31
поделиться

Хотя я обычно - поклонник утиных типизированных языков как Python, я вижу Вашу проблему с ним в Java.

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

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

Короче говоря у Вас есть вместилище (трудно) вместо (легкой) выгоды небольшого количества. Я думаю, что это - патология.

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

Вы могли бы хотеть указать на своего коллегу на принцип замены Лисков, один из этих пяти столбов в ТЕЛЕ.

Ссылки:

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

Это не утиный ввод, это - просто плохой способ моделировать полиморфизм на языке, который имеет (более или менее) реальный полиморфизм.

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

Почему "подражают иерархии классов" вместо того, чтобы разработать и использовать его? Один из методов рефакторинга заменяет "переключатель" es (объединил IFS в цепочку, почти то же) с полиморфизмом. Почему использование переключается, куда полиморфизм привел бы к более чистому коду?

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

Два аргумента для ответа на названный вопрос:

1) Java, как предполагается, является "записью однажды, для выполнения куда угодно" так код, который был написан для одной иерархии, не должен бросать RuntimeExceptions, когда мы изменяем среду где-нибудь. (Конечно, существуют исключения - игра слов - к этому правилу.)

2) JIT Java выполняет очень агрессивную оптимизацию, которая полагается на знание, что данный символ должен иметь один тип и один тип только. Единственный способ работать вокруг этого состоит в том, чтобы бросить.

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

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

Вместо instanceof можно использовать Метод - и Стратегическая модель, смешал взгляды кода намного лучше, чем прежде...

0
ответ дан 8 December 2019 в 04:31
поделиться
Другие вопросы по тегам:

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