Ввод указателя функции
TLDR:
Ввод указателя функции в класс Customer
.Значение этого указателя функции может составлять Order.GetAll
в производстве и MockOrder.GetAll
в тестах.
ПРИМЕР:
Зависимость ( проблемная статическая функция, от которой мы зависим ):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Наш зависимый класс ( зависит от статической функции ):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Рабочий класс клиента ( выполняет внедрение зависимостей ):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Проверка класса клиента ( как модульный тест может внедрить ложную зависимость ):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
ОБСУЖДЕНИЕ:
Как выФактически внедрение «указателя функции» будет зависеть от синтаксиса и возможностей, доступных на вашем языке.Здесь я просто говорю об общей концепции.
Это не совсем симпатичное решение.Вероятно, было бы проще, если бы вы могли изменить GetAll
на метод экземпляра (возможно, введя объект OrdersLoader
или воспользовавшись ответом Пола Филлипса).Но если вы действительно хотите сохранить его как статическую функцию, то это решение будет работать.