Observer Pattern no iOS-Swift (Behavioral Design Pattern)
Nesta história, vou escrever sobre o padrão de projeto Observer.
Atualmente, a maioria dos desenvolvedores usa RXSwift ou Combine para implementar esse padrão de design e, às vezes, não pensamos no que acontecerá por trás dessas ferramentas. Vou explicar os padrões do Observer e escrever um código de exemplo sem RXSwift ou Combine para demonstrar a ideia do padrão.
O padrão de projeto Observer permite que um grupo de objetos, conhecidos como observadores, seja notificado sobre a mudança de estado de outro objeto, referido como Subject.
Os observadores se inscrevem no sujeito. O subject atualiza todos os observadores registrados sempre que seu estado muda.
Quando um observador é notificado, ele pode recuperar o estado do assunto em que está interessado.
Essa abordagem evita o acoplamento estreito entre os observadores e o sujeito.
O sujeito só conhece o protocolo comum. Nenhum outro detalhe de implementação é compartilhado com o assunto.
Certifique-se de que os observadores cancelam o registro do assunto antes de liberá-los. Caso contrário, o sujeito mantém a referência à instância do observador que deveria ter sido destruída e continua atualizando-a, levando a bugs e comportamentos inesperados.
Vamos começar a implementar o padrão Observer.
Primeiro, crio o protocolo do observador. Os tipos precisarão estar em conformidade com este protocolo se quiserem ser notificados quando o assunto for alterado. e o protocolo declara um único método, notify.
protocol Observer {
func notify()
var uid: Int { get }
}
Então precisamos do protocolo do assunto. Eu defino o método register que permite aos observadores assinar notificações do assunto.
protocol Subject {
mutating func register(_ observer: Observer)
mutating func unregister(_ observer: Observer)
}
É isso, agora vamos ver em ação.
Farei com que o rótulo da IU esteja em conformidade com o protocolo do observador, usando uma extensão.
extension UILabel: Observer {
func notify() {
self.text = "Subject state changed"
}
var uid: Int {
return ObjectIdentifier(self).hashValue
}
}
Em seguida, farei com que o botão da interface do usuário esteja em conformidade com o protocolo do assunto, usando uma extensão.
extension UIButton: Subject {
private static var observers = [Observer]()
func register(_ observer: Observer) {
UIButton.observers.append(observer)
}
func unregister(_ observer: Observer) {
UIButton.observers = UIButton.observers.filter{$0.uid != observer.uid}
}
}
O método register deve anexar o parâmetro de entrada à lista de observadores.
E para o método de cancelamento de registro, contarei com o método de matriz de filtro, que retorna os elementos da lista de observadores que satisfazem o predicado fornecido.
UIButton agora está totalmente em conformidade com o protocolo do assunto.
func onStateChanged() {
UIButton.observers.forEach { (observer) in
observer.notify()
}
}
Agora, vamos juntar tudo.
protocol Observer {
func notify()
var uid: Int { get }
}
protocol Subject {
mutating func register(_ observer: Observer)
mutating func unregister(_ observer: Observer)
}
extension UILabel: Observer {
func notify() {
self.text = "Subject state changed"
}
var uid: Int {
return ObjectIdentifier(self).hashValue
}
}
extension UIButton: Subject {
private static var observers = [Observer]()
func register(_ observer: Observer) {
UIButton.observers.append(observer)
}
func unregister(_ observer: Observer) {
UIButton.observers = UIButton.observers.filter{$0.uid != observer.uid}
}
func onStateChanged() {
UIButton.observers.forEach { (observer) in
observer.notify()
}
}
}
Padrão de design estrutural — Adaptador no iOS-Swift
Espero que você o ache útil e possa usá-lo em seu projeto. Eu apreciaria o feedback sobre isso.
Acessibilidade de rede com Combine e Alamofire




































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)