Интерфейсное безумие

Вы можете использовать lodash _.flow() для создания функции. Используйте _.map() с _.overArgs() для создания функции, которая разделяет значения, форматирует ключ и затем преобразует их в массив пар, используя _.unzip(), например [['name', 'x'], ['name', 'y']]. Транспонировать массив массивов с помощью _.unzip(), чтобы объединить пары разных свойств. Затем используйте _.map() для итерации и преобразуйте каждый массив пар в объект, используя _.fromPairs().

const { flow, partialRight: pr, map, unzip, overArgs, times, size, constant, split, fromPairs } = _

const keysMap = new Map([['BPContName', 'name'], ['BPContEmail', 'email'], ['BPContPWID', 'pwdid']])

const formatKey = key => keysMap.get(key)
const splitVals = pr(split, ';')

const fn = flow(
  pr(map, overArgs(
    (vals, k) => unzip([vals, times(size(vals), constant(k))]),
    [splitVals, formatKey])
  ),
  unzip, // transpose
  pr(map, fromPairs) // convert each pairs array to object
)

const data = {
    "BPContName":"aName;bName;cName",
    "BPContEmail":"aEmail;bEmail;cEmail",
    "BPContPWID":"aPWID;bPWID;cPWID"
}

const results = fn(data)

console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

8
задан n8wrl 31 March 2009 в 12:50
поделиться

8 ответов

Интерфейсы полезны, когда вы хотите смоделировать взаимодействие между объектом и одним из его соавторов. Однако в интерфейсе меньше значения для объекта, который имеет внутреннее состояние.

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

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

Учитывая доменный объект, который вернулся из репозитория и на который действует мой сервис, меньше стоимость. Когда я пишу тест для своего сервиса, я хочу использовать реальный объект домена и проверять его состояние. Например, после вызова service.AddSomething () я хочу проверить, что что-то было добавлено к объекту домена. Я могу проверить это, просто проверив состояние объекта домена. Когда я тестирую свой доменный объект изолированно, мне не нужны интерфейсы, так как я собираюсь только выполнять операции над объектом и проверять его на его внутреннее состояние. например действительно ли для моей овцы есть траву, если она спит?

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

Помните, что (если у вас установлена ​​копия Resharper), извлечь интерфейс позже будет крайне дешево. Также дешево удалить интерфейс и вернуться к более простой иерархии классов, если вы решите, что вам все-таки не нужен этот интерфейс. Мой совет - начинать без интерфейсов и извлекать их по требованию, когда вы обнаружите, что хотите смоделировать взаимодействие.

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

7
ответ дан 5 December 2019 в 06:39
поделиться

Кажется, что Вы страдаете немного от BDUF.

Успокойтесь с coolade и позвольте ему течь естественно.

6
ответ дан 5 December 2019 в 06:39
поделиться

Я обычно нахожу, что хочу интерфейсы для "сервисов" - тогда как типы, которые являются, прежде всего, о "данных", могут быть реальными классами. Например, я имел бы Authenticator интерфейс, но a Contact класс. Конечно, это не всегда настолько ясно, но это - начальное эмпирическое правило.

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

5
ответ дан 5 December 2019 в 06:39
поделиться

Помните, что, в то время как гибкость является достойной целью, добавленной гибкостью с МОК и DI (которые в некоторой степени являются требованиями для TDD) также увеличивает сложность. Единственная точка гибкости должна делать изменения в нисходящем направлении более быстрыми, более дешевыми или лучше. Каждая сложность увеличений точки МОК/DI, и таким образом способствует внесению изменений, в другом месте более трудных.

Это на самом деле, где Вам нужен Большой Дизайн Впереди в некоторой степени: определите, какие области, скорее всего, будут изменять (и/или нуждаться в обширном поблочном тестировании), и запланируйте гибкость там. Осуществите рефакторинг для устранения гибкости, где изменения маловероятны.

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

Теперь, области, которые могут или не могут измениться, зависят от Вашей бизнес-проблемы и среды IT. Вот некоторые повторяющиеся области.

  1. Я всегда рассматривал бы внешние интерфейсы, где Вы интегрируетесь к другим системам, чтобы быть очень изменяемыми.
  2. Независимо от того, что код обеспечивает, бэкэнд пользовательскому интерфейсу должен будет поддерживать изменение в UI. Однако запланируйте изменения в функциональности, прежде всего: не идите за борт и планируйте различные технологии UI (такие как поддержка и умный клиент и веб-приложение – шаблоны использования будут отличаться слишком много).
  3. С другой стороны, кодирование для мобильности к различным базам данных и платформам обычно является пустой тратой времени, по крайней мере, в корпоративных средах. Расспросите тут и там и проверьте, какие планы могут существовать, чтобы заменить или обновить технологии в вероятной продолжительности жизни Вашего программного обеспечения.
  4. Изменения в содержании данных и форматах являются хитрым бизнесом: в то время как данные будут иногда изменяться, большинство проектов, которые я видел, обрабатывает такие изменения плохо, и таким образом Вы получаете конкретные классы объекта, используемые непосредственно.

Но только можно сделать решение того, что могло бы или не должно изменяться.

6
ответ дан 5 December 2019 в 06:39
поделиться

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

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

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

Somethings, который обычно не был бы интерфейсами, будет классами, которые только содержат данные, как говорят, что класс Местоположения, который имеет дело с X и Y. Разногласия того, чтобы там быть другой реализацией этого являются тонкими.

0
ответ дан 5 December 2019 в 06:39
поделиться

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

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

0
ответ дан 5 December 2019 в 06:39
поделиться

Я думаю, что самый важный "гибкий" принцип является YAGNI ("Вы, не Собирается Потребность Это"). Другими словами, не пишите дополнительный код, пока он не на самом деле необходим, потому что, если Вы пишете это заранее, требования и ограничения, возможно, изменились когда (если!) Вам наконец нужен он.

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

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

2
ответ дан 5 December 2019 в 06:39
поделиться

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

Но извлеките их, когда Вы чувствуете желание сделать так - когда Вы видите потребность интерфейса - на шаге рефакторинга.

Те ответы могут помочь также.

-1
ответ дан 5 December 2019 в 06:39
поделиться
Другие вопросы по тегам:

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