Как Douglas Mayle отметил, это в основном обозначает имя типа. Следовательно, Вам не рекомендовалось бы закончить имена переменной или имена функций с' _t
', так как это могло вызвать некоторый беспорядок. А также size_t
, стандарт C89 определяет wchar_t
, off_t
, ptrdiff_t
, и вероятно некоторые другие, которых я забыл. Стандарт C99 определяет много дополнительных типов, такой как uintptr_t
, intmax_t
, int8_t
, uint_least16_t
, uint_fast32_t
, и так далее. Эти новые типы официально определяются в [1 110], но чаще всего Вы будете использовать
, который (необычно для стандарта C заголовки) включает
. Это (
) также определяет макросы для использования с printf()
и scanf()
.
, Поскольку Matt Curtis отметил, нет никакого значения для компилятора в суффиксе; это - ориентируемое на пользователя соглашение.
Однако необходимо также отметить, что POSIX определяет много дополнительных имен типов, заканчивающихся в' _t
', и резервы суффикс для реализации. Это означает, что, если Вы работаете над связанными с POSIX системами, определение Ваших собственных имен типов с соглашением опрометчиво. Система я продолжаю работать, делала его (больше 20 лет); мы регулярно сбиваемся с толку системами, определяющими типы с тем же именем, как мы определяем.
Может быть, не все объекты, но чем больше объектов вы вводите в свой отряд, тем лучше становится ваше разделение проблем, поэтому я определенно рекомендую вам переехать в этом направлении.
Необязательно передавать все объекты в качестве параметров метода. Часто лучше внедрять соавторов в классы с помощью Constructor Injection. Это сохраняет ваши интерфейсы в чистоте, в то время как ваши реализации могут импортировать нужных соавторов.
Допустим, ваша исходная реализация выглядела так:
public class Foo
{
public Ploeh DoStuff(Fnaah f)
{
var bar = new Bar();
return bar.DoIt(f);
}
}
Это можно было изменить так:
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
public Ploeh DoStuff(Fnaah f)
{
return this.bar.DoIt(f);
}
}
Обратите внимание, что я изменил bar
от экземпляра Bar к экземпляру IBar, тем самым отделяя Foo от конкретной реализации IBar.
Я не уверен, какой язык / инструменты вы используете, но способ, которым это можно сделать - rails, - это просто имитировать конструктор, например:
@user = mock_model(User)
User.stub(:create).and_return(@user)
Итак, с этого момента в ваших тестах, если вы вызываете User.create (User - это «класс»), он всегда будет возвращать вашу предопределенную переменную @user, что позволяет вам полностью контролировать, какие данные используются в ваших модульных тестах.
Теперь, когда вы знаете, Какие именно данные находятся в ваших тестах, вы можете начать заглушать методы экземпляра ваших объектов, чтобы убедиться, что они возвращают правильные данные, которые вы можете использовать для тестирования ваших методов.
[Отказ от ответственности: я работаю в Typemock]
Вы есть три варианта, два из которых требуют некоторого рефакторинга:
Разработка с учетом тестируемости не всегда является хорошей практикой, особенно с существующим проектом, где
вы уже написали код.
Так что если вы начинаете с чистого листа или имеете небольшой проект, возможно, можно передавать объекты в качестве аргументов конструктору класса, если у вас не слишком много параметров.
- Если вы используете контейнер IoC.
Если вы не хотите изменять весь существующий код и / или не хотите разрабатывать свой код определенным образом, чтобы сделать его «более тестируемым» (может вызвать некоторую странность на вид кода - используйте Isolator (или аналогичный инструмент) если вы используете Java).
Вы должны отдавать предпочтение методам, которые не принимают аргументов, за которыми следует один аргумент, два и, наконец, три . Все, что принимает больше 3, - это запах кода. Либо существует класс, ожидающий обнаружения во всех передаваемых аргументах, либо класс / метод пытается сделать слишком много.
С точки зрения передачи зависимостей вы можете использовать внедрение конструктора, но со временем это становится громоздким по мере того, как вы постепенно переходите к необходимости проходить через весь граф объекта.
В какой-то момент вы не собираетесь отказываться от создания одного объекта из другого, но вы должны писать программное обеспечение в соответствии с хорошими принципами проектирования. Например, SRP, DI и т. Д.
Там, где у вас много зависимостей, вы можете найти контейнер IoC, который поможет вам управлять ими всеми.
При работе с унаследованным кодом вам может быть полезно прочитать Майкла Фезера. Эффективно работает с устаревшим кодом . В книге есть много способов протестировать вашу систему.
Просто наблюдение: вы говорите о методах, а я предпочитаю говорить о классах.
На этот вопрос нет общего ответа. Иногда действительно важно отделить создание класса от использования.
Учтите:
Есть еще одна уловка: сделать внедрение необязательным. Это означает, что когда вы передаете экземпляр в конструктор, он будет использован. Если нет, новый экземпляр создается самим классом. Это удобно при работе с устаревшим кодом и когда у вас нет инфраструктуры внедрения зависимостей.
Первая часть - это немного загруженный вопрос. Это все равно, что спрашивать: «При наезде на пешеходов в моей машине должны ли я держать руль обеими руками?»
Метод, который создает экземпляры множества других объектов, почти наверняка делает слишком много. Класс с большим количеством этих методов, вероятно, не следует принципу единственной ответственности.
Однако один из ключевых способов сделать ваш код тестируемым - это использовать IoC (инверсия управления), где зависимости класса (или метода) передаются ему, а не класс, запрашивающий их. Это значительно упрощает тестирование, так как вы можете пройти в mocks.
Итак, краткий ответ - «Да», передайте свои зависимости и посмотрите на хороший компонент внедрения зависимостей . Длинный ответ: «Да, но не делай этого». Фреймворки DI, вероятно, заставят вас передавать зависимости объектам, а не методам, и вы обнаружите, что хотите ограничить эти зависимости - что хорошо.
И, конечно же, рефакторинг для уменьшения зависимостей - это хорошо. Сокращение ваших методов до одного дела почти никогда не бывает плохим. Я полностью согласен с тем, что это долгосрочная выгода, если вы можете позволить себе краткосрочные затраты.
Имитируйте только объекты, которые мешают при написании модульных тестов. Если метод создает объект для выполнения своих задач, и вы можете проверить его результат, тогда нет необходимости имитировать класс создаваемого объекта.
Используйте mock, если хотите изолировать класс от других. Используйте имитацию, чтобы держать тесты подальше от
Использование объекта отдельно от их построения
Я бы попытался использовать внедрение зависимостей для класса, а не создавать объект методом класса (как рекомендует выбранный ответ). Если это не имеет смысла, подумайте о создании фабричного класса, который производит создаваемые объекты. Затем вы можете передать эту фабрику через внедрение зависимостей.
Я предпочитаю высмеивать практически все, что находится вокруг объекта, и определять поведение тестируемого объекта в терминах вызовов и ответов от связанных объектов.
Чтобы для эффективного выполнения этой задачи необходимо, чтобы ваши интерфейсы были на семантическом уровне, а не на уровне реализации в целом.