Eu estava trabalhando em um tutorial de Ray Wenderlich e notei que o autor usa extensões de classe para reter delegados de retorno de chamada em vez de tê-los tratados na própria classe, ou seja:
delegar retornos de chamada dentro da extensão de classe:
extension LogsViewController : UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
em vez de contê-lo na classe:
delegar retornos de chamada dentro da classe:
class LogsViewController : UITableViewController, UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
...
}
}
Achei isso estranho e interessante ao mesmo tempo. Ele possui um arquivo dedicado apenas às extensões da classe LogsViewController denominada "LogsViewControllerExtension.swift" e possui uma extensão diferente para cada protocolo de delegado: UITableViewDataSource, UISplitViewDelegate, etc.
várias extensões de classe, cada uma com delegação de retorno de chamada em seu próprio arquivo:
extension LogsViewController: UISplitViewControllerDelegate {
... callbacks
}
extension LogsViewController : UIPopoverPresentationControllerDelegate {
... callbacks
}
Por quê?
Que vantagens existem para fazer isso? Eu posso ver onde pode ser um pouco mais legível separar isso, mas ao mesmo tempo é um nível de indireção. Existem princípios de OO que apoiam ou são contra isso?
fonte
Respostas:
Não sei por que você disse que isso adiciona um nível de indireção. Talvez você queira dizer algo diferente do que o significado tradicional, porque não há indireção extra criada ao fazer isso. Mas por que fazer isso?
Eu faço isso porque é mais modular. Todo o código exigido pela interface é agrupado em um único local (exceto as propriedades reais.) Se, posteriormente, optar por criar uma classe separada para implementar esse protocolo (e assim introduzir um nível real de indireção), tudo o que preciso O fazer é alterar a extensão para uma classe própria (passando as propriedades necessárias por meio de uma função init) e criar uma propriedade no ViewController para instanciar o objeto.
Também coloquei quaisquer funções privadas que são usadas apenas pelas funções desse protocolo na extensão. Não fui tão longe a ponto de criar um arquivo completamente separado para a extensão, mas isso deixa claro que essas funções privadas são apenas para esse protocolo.
De qualquer forma, as pessoas costumam reclamar dos controladores de exibição de gordura e a quebra de um controlador de exibição dessa maneira ajuda a mantê-lo melhor organizado, mesmo que ele não torne o controlador de exibição mais fino.
fonte
Como Daniel disse em relação à indireção, não há nível disso.
Eu concordo com ele e gostaria de adicionar um recurso extra poderoso das extensões de protocolo que eu conhecia recentemente.
Diga que você tem um protocolo,
didCopyText
por exemplo. Você implementará isso como:No Swift, propriedades e métodos não são implementados na declaração do protocolo, você deseja escrever a implementação em todas as classes em conformidade com a
didCopyText
, com um número incremental de classes em conformidade com este protocolo com a mesma implementação, isso acabaria com apenas uma confusão código repetido. É aí que as Extensões de Protocolo são úteis.Com a implementação das propriedades e métodos do protocolo. Agora, qualquer classe que esteja em conformidade com este protocolo, usará a mesma implementação.
fonte
Digamos que sua classe suporte três protocolos e, portanto, você precisa adicionar três conjuntos de funções. O único objetivo dessas funções é oferecer suporte a um protocolo, portanto, você precisa de alguma documentação.
No entanto, se você adicionar uma extensão para cada protocolo e, em cada extensão, implementar exatamente as funções necessárias para esse protocolo, isso tornará seu código muito mais legível.
Eu provavelmente não os colocaria em arquivos separados, a menos que essas extensões sejam realmente grandes.
fonte