Padrões de caso de uso e repositório
Defina casos de uso como protocolos Swift e implemente interfaces de repositório.
Padrões de caso de uso e repositório é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
O que é um Caso de Uso?
Um caso de uso, também chamado de interator, encapsula uma única ação de negócio e coordena entidades do domínio e repositórios.
struct PlaceOrderUseCase {
let cart: CartRepository
let payment: PaymentService
let orders: OrderRepository
func execute(userId: Int) async throws -> Order {
let items = try await cart.items(for: userId)
let receipt = try await payment.charge(items: items)
return try await orders.create(receipt: receipt)
}
}Responsabilidade Única
Cada caso de uso faz exatamente uma coisa. Várias responsabilidades significam vários casos de uso.
// One use case per business action:
struct FetchUserUseCase { ... }
struct UpdateUserUseCase { ... }
struct DeleteUserUseCase { ... }Caso de Uso como Protocolo
Defina um protocolo para o caso de uso, para que ele possa ser simulado nos testes da camada de Apresentação.
protocol PlacingOrder {
func execute(userId: Int) async throws -> Order
}
struct PlaceOrderUseCase: PlacingOrder { ... }O que é um Repositório?
Um repositório abstrai a fonte de dados. Os chamadores interagem com um protocolo Swift; a implementação pode usar rede, Core Data ou memória.
protocol OrderRepository {
func create(receipt: PaymentReceipt) async throws -> Order
func list(userId: Int) async throws -> [Order]
func cancel(orderId: Int) async throws
}Implementação do Repositório
O repositório concreto traduz chamadas do domínio em operações de rede ou de banco de dados.
struct RemoteOrderRepository: OrderRepository {
func create(receipt: PaymentReceipt) async throws -> Order {
let dto = receipt.toDTO()
let data = try await api.post("/orders", body: dto)
return try JSONDecoder().decode(OrderDTO.self, from: data).toDomain()
}
func list(userId: Int) async throws -> [Order] { ... }
func cancel(orderId: Int) async throws { ... }
}Repositório em Memória para Testes
Forneça um repositório em memória para testes rápidos e determinísticos, sem operações de entrada e saída.
final class InMemoryOrderRepo: OrderRepository {
var orders: [Order] = []
func create(receipt: PaymentReceipt) async throws -> Order {
let order = Order(id: orders.count + 1, items: receipt.items)
orders.append(order)
return order
}
func list(userId: Int) async throws -> [Order] { orders }
func cancel(orderId: Int) async throws { orders.removeAll { $0.id == orderId } }
}Composição de Casos de Uso
Os casos de uso podem chamar outros casos de uso para compartilhar suboperações, mantendo cada um concentrado em sua responsabilidade.
struct CheckoutUseCase {
let validateCart: ValidateCartUseCase
let placeOrder: PlaceOrderUseCase
let notifyUser: NotifyUserUseCase
func execute(userId: Int) async throws -> Order {
try await validateCart.execute(userId: userId)
let order = try await placeOrder.execute(userId: userId)
try await notifyUser.execute(order: order)
return order
}
}Repositório versus Serviço
Repositório: operações de criação, leitura, atualização e exclusão sobre um único tipo de entidade. Serviço: coordena várias entidades ou chama APIs externas sem lidar diretamente com o armazenamento.
// Repository: single entity
protocol UserRepository { func getUser(id: Int) async throws -> User }
// Service: cross-entity operation
protocol AuthService { func login(email: String, password: String) async throws -> Session }Cache em Repositórios
Os repositórios podem armazenar resultados em cache de forma transparente, sem que o caso de uso conheça esse detalhe da implementação.
struct CachedUserRepository: UserRepository {
private var cache: [Int: User] = [:]
private let remote: UserRepository
func getUser(id: Int) async throws -> User {
if let cached = cache[id] { return cached }
let user = try await remote.getUser(id: id)
cache[id] = user
return user
}
func saveUser(_ user: User) async throws { try await remote.saveUser(user) }
}Testabilidade
Como os casos de uso dependem de repositórios definidos por protocolos, você pode injetar objetos simulados para testar a lógica de negócio de forma isolada.
let repo = InMemoryOrderRepo()
let sut = PlaceOrderUseCase(orders: repo, ...)
let order = try await sut.execute(userId: 1)
XCTAssertEqual(repo.orders.count, 1)Tradução de Erros
Os repositórios devem traduzir erros da camada de dados, como erros de rede ou de banco de dados, em erros do domínio antes de retorná-los.
func getUser(id: Int) async throws -> User {
do {
let data = try await api.get("/users/\(id)")
return try decode(data)
} catch let e as URLError where e.code == .notConnectedToInternet {
throw DomainError.offline
}
}Verificação Rápida
Qual é a principal diferença entre um Repositório e um Serviço na Arquitetura Limpa?
Recapitulação da lição
Os casos de uso encapsulam ações de negócio únicas e dependem de protocolos de repositório. Os repositórios abstraem as fontes de dados por meio de um protocolo. Use repositórios em memória para testes rápidos. Os repositórios traduzem erros da infraestrutura em erros do domínio. Os serviços coordenam operações que envolvem várias entidades.
Aprenda Swift com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 122
- Aulas
- 409
Perguntas Frequentes
A aula “Padrões de caso de uso e repositório” é grátis?
Sim — o texto completo de “Padrões de caso de uso e repositório” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “Padrões de caso de uso e repositório”?
Defina casos de uso como protocolos Swift e implemente interfaces de repositório. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Padrões de caso de uso e repositório”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Camadas: domínio, dados e apresentação
- Padrões de caso de uso e repositório
- Inversão de dependências com abstrações de protocolos
- Integração das camadas sem um framework de DI