Padrões de design por tutoriais - O poder da OOP (parte 2)
Jornada do Design Pattern - O Poder do OOP 2
Padrões de design por tutoriais — O poder da OOP (parte 2)
Padrão Singleton: padrão de design singleton puro e semi-singleton em Swift Padrão Singleton: padrões de design puros Singleton e Semi-Singleton em Swift
Pré-requisitos — Esta série de blogs requer um nível intermediário de conhecimento em programação orientada a objetos. Você deve ter conhecimentos básicos sobre classe, objeto, construtor, herança, valor e tipo de referência. Os intermediários ganharão conhecimento e os especialistas aprimorarão seus conhecimentos lendo esta série do início ao fim. Pré-requisitos – Esta série de blogs requer conhecimento intermediário em programação orientada a objetos. Você deve ter um conhecimento básico de classes, objetos, construtores, herança, valor e tipos de referência. Os usuários intermediários adquirirão conhecimento, enquanto os especialistas aprimorarão seus conhecimentos lendo esta série de capa a capa.
Classe Singleton
Classe única
Na programação orientada a objetos, uma classe singleton é uma classe que pode ter apenas um objeto durante todo o ciclo de vida de um aplicativo ou projeto. Na programação orientada a objetos, uma classe singleton é uma classe que pode ter apenas um objeto durante todo o ciclo de vida de um aplicativo ou projeto.
O padrão de design Singleton faz parte do código do ciclo de vida dos aplicativos iOS. Por exemplo, em um projeto iOS, a classe UIApplication é o melhor exemplo de uma classe singleton, que é criada pelo sistema iOS na inicialização do aplicativo e passada para o AppDelegate como um parâmetro no método application:didFinishLaunchingWithOptions:. O padrão de design singleton faz parte do código do ciclo de vida do aplicativo iOS. Por exemplo, em um projeto iOS, a classe UIApplication é o melhor exemplo de classe singleton, que é criada pelo sistema iOS quando o aplicativo é iniciado e passada para AppDelegate como um parâmetro no método application:didFinishLaunchingWithOptions:.
Existem dois tipos de padrões de design Singleton.
Existem dois tipos de padrão de design singleton.
-
Padrão de design singleton puro Padrão de design singleton puro
-
Padrão de design semi-singleton Padrão de design semi-singleton
Padrão de design Pure-Singleton:
Padrão de design Pure-Singleton:
Nesse padrão, um programador que está usando a funcionalidade de uma classe singleton pura não tem permissão para criar uma instância da classe. Um programador só pode chamar métodos e acessar propriedades disponíveis para a classe singleton usando a instância predefinida dessa classe. Nesse padrão, os programadores que usam a funcionalidade de uma classe singleton pura não têm permissão para criar instâncias dessa classe. Os programadores podem chamar métodos e acessar propriedades disponíveis apenas usando uma instância predefinida de uma classe singleton.
O objeto de uma classe singleton pura é criado automaticamente durante a inicialização do aplicativo com parâmetros predefinidos mencionados pelo desenvolvedor que criou essa classe. Durante a inicialização do aplicativo, objetos de classes singleton puras são criados automaticamente usando parâmetros predefinidos mencionados pelo desenvolvedor que criou a classe.
Classes singleton puras devem ser marcadas como finais para evitar confusão de herança. Rapidamente, você também pode usar a estrutura para alcançar o mesmo conceito. Classes singleton puras devem ser marcadas como finais para evitar confusão de herança. Rapidamente, você também pode usar estruturas para implementar o mesmo conceito.
Um programador não pode herdar a classe singleton pura. Ao tentar herdar qualquer classe rapidamente, você deve chamar o construtor da superclasse. Chamar o construtor da superclasse não é possível na classe singleton puro porque todos os construtores da classe singleton puro são sempre marcados como privados. Os programadores não podem herdar classes singleton puras. Ao tentar herdar de qualquer classe rapidamente, você deve chamar o construtor da superclasse. Não é possível chamar o construtor da superclasse na classe singleton puro porque todos os construtores da classe singleton puro são marcados como privados.
Vamos entender esse padrão de design de forma simples com o exemplo abaixo. Vamos entender esse padrão de design de forma simples por meio do exemplo a seguir.
//PureSingletonDesignPatterExample1.swift :
// Hitendra Solanki
// Pure-singleton design pattern Playground example
final class LogManager {
//shared and only one available object
static let logger: LogManager = LogManager(databaseURLEndpoint: "https://www.hitendrasolanki.com/logger/live")
private var databaseURLEndpoint: String
//marked as private, no one is allowed to access this initialiser outside of the class
private init(databaseURLEndpoint: String) {
self.databaseURLEndpoint = databaseURLEndpoint
}
func log(_ value: String...){
//complex code to connect to the databaseURLEndpoint and send the value to server directly
}
}
//This is function in playground which executes our test code
func main(){
LogManager.logger.log("test log from medium blog") //this will log on "/live" endpoint
}
//call main to execute our test code
main()
No exemplo acima, PureSingletonDesignPatterExample1.swift marcamos todos os métodos init como privados da classe LogManger para que ninguém possa criar uma instância dessa classe. Se tentarmos criar uma subclasse do LogManger, o compilador apresentará um erro. No exemplo acima, PureSingletonDesignPatterExample1.swift, marcamos todos os métodos init como métodos privados da classe LogManger, para que ninguém possa criar uma instância desta classe. Se tentarmos criar uma subclasse do LogManger, o compilador apresentará um erro.
UIApplication, AppDelegate são exemplos da classe singleton puro. Você já tentou criar um objeto da classe UIApplication manualmente? Tente fazer isso e execute o aplicativo. [O que aconteceu? O aplicativo travou, certo? -Eu testei esta falha no Swift 5, XCode 10.2] UIApplication e AppDelegate são exemplos de classes singleton puras. Você já tentou criar manualmente um objeto da classe UIApplication? Tente fazer isso e executar o aplicativo. O aplicativo trava, certo? - Testei esse travamento no Swift 5, XCode 10.2]
Limitações do padrão de design Pure-Singleton,
Limitações do padrão singleton puro,
Não podemos testar a classe singleton pura com os dados de teste. No exemplo acima PureSingletonDesignPatterExample1.swift, suponha que você queira testar a classe LogManager apontando-a para algum URL de modo de teste em vez de URL de modo de produção, não podemos fazer isso quando estamos escrevendo casos de teste no destino XCTest. Não podemos testar classes singleton puras com dados de teste. No exemplo acima, PureSingletonDesignPatterExample1.swift, supondo que você queira testar a classe LogManager, aponte-a para algum URL do modo de teste em vez do URL do modo de produção, não podemos fazer isso quando escrevemos casos de teste no destino XCTest.Podemos superar essa limitação convertendo nossa classe singleton puro em classe semi-singleton ou usando o padrão de injeção de dependência. Escreverei um artigo dedicado sobre padrão de injeção de dependência. Por enquanto, vamos continuar com o padrão de design semi-singleton. Podemos superar essa limitação convertendo nossa classe singleton pura em uma classe semi-singleton ou usando o padrão de injeção de dependência. Escreverei um artigo especificamente sobre padrões de injeção de dependência. Agora, vamos continuar usando o padrão de design semi-singleton.
Padrão de design semi-singleton:
Padrão de design semi-singleton:
-
No padrão de design semi-singleton, um programador que está usando a classe pode criar um objeto da classe singleton, se necessário. bem como também tem permissão para chamar métodos e usar propriedades da classe singleton. No padrão de design semi-singleton, o programador que usa a classe pode criar objetos da classe singleton, se necessário. Bem como propriedades que permitem chamar métodos e usar classes singleton.
-
Um programador também pode herdar a classe semi-singleton se o singleton não for marcado como final pelo desenvolvedor da classe singleton. No padrão de design semi-singleton, não é necessário marcar a aula como final. Os programadores também podem herdar de classes semi-singleton se o desenvolvedor da classe singleton não marcar a classe singleton como final. No padrão semi-singleton, não é necessário marcar a aula como final.
//SemiSingletonDesignPatterExample1.swift
// Hitendra Solanki
// Semi-singleton design pattern Playground example
//In semi-singleton design pattern, marking the class as final is optional
final class LogManager {
//shared object
static let logger: LogManager = LogManager(databaseURLEndpoint: "https://www.hitendrasolanki.com/logger/live")
private var databaseURLEndpoint: String
//not marked as private, anyone is allowed to access this initialiser outside of the class
init(databaseURLEndpoint: String) {
self.databaseURLEndpoint = databaseURLEndpoint
}
func log(_ value: String...){
//complex code to connect to the databaseURLEndpoint and send the value to server directly
}
}
//This is function executes our main code
func main(){
LogManager.logger.log("main log from medium blog on live server endpoint") //this will log on "/live" endpoint
}
// This is function executes our TEST MODE code
// Here in playground, Hitendra Solanki created this method for the demostratino purpose only
// Usually we write this kind of test codes, inside the test targe of the XCode-project
func testThatLogManger(){
//we are allowed to create an instace of class LogManager,
//because it follows the Semi-Singleton design patterns
let logManagerTestObject = LogManager(databaseURLEndpoint: "https://www.hitendrasolanki.com/logger/test")
logManagerTestObject.log("test log from medium blog on test server endpoint") //this will log on "/test" endpoint
}
main() //call main
testThatLogManger() //call test execution
- No exemplo acima, SemiSingletonDesignPatterExample1.swift, não marcamos o método init como privado, portanto, podemos criar várias instâncias da classe semi-singleton para remover a dependência da propriedade databaseURLEndpoint. Agora podemos criar um objeto da classe LogManger usando qualquer valor databaseURLEndpoint, agora nossa classe LogManger segue o padrão semi-singleton. No exemplo acima, SemiSingletonDesignPatterExample1.swift, não marcamos o método init como privado, portanto, podemos criar várias instâncias da classe semi-singleton para remover a dependência da propriedade databaseURLEndpoint. Agora podemos criar objetos da classe LogManger usando qualquer valor databaseURLEndpoint e agora nossa classe LogManger segue o padrão semi-singleton.
UserDefault, FileManager, NotificationCenter são exemplos de classes semi-singleton. Podemos usar objetos compartilhados predefinidos de UserDefault, FileManager e NotificationCenter que são UserDefault.standard, FileManager.default e NotificationCenter.default. UserDefault, FileManager e NotificationCenter são exemplos de classes semi-singleton. Podemos usar objetos compartilhados predefinidos como UserDefault, FileManager e NotificationCenter, que são UserDefault.standard, FileManager.default e NotificationCenter.default.
O objeto predefinido de classes puras ou semi-singleton sempre reside na memória e nunca é destruído até que você feche o aplicativo. Um objeto definido pelo programador da classe semi-singleton destruído após a conclusão do escopo do objeto. Objetos predefinidos de classes puras ou semi-singleton sempre existem na memória e não são destruídos até que o aplicativo seja fechado. Um objeto definido pelo programador de uma classe semi-singleton é destruído após a conclusão do escopo do objeto.
Pergunta: Qual é a melhor maneira, “Padrão de design Pure-singleton” ou “Padrão de design semi-singleton”, quando devo usar o primeiro e quando devo usar o outro? Pergunta: Qual é melhor, “Pure Singleton Design Pattern” ou “Semi-Singleton Design Pattern”? Em que circunstâncias deve ser usado?
Isso depende totalmente das responsabilidades da sua turma. Se você criou uma classe singleton em seu projeto e precisa alterar algumas das propriedades em algum momento ou se deseja adicionar mais responsabilidades à classe adicionando novos métodos no futuro e se precisar de seus casos de teste também com dados simulados para métodos recém-adicionados, você deve usar o padrão de design semi-singleton. Tudo depende da funcionalidade da sua classe. Se você criou um projeto de classe singleton e precisa alterar algumas propriedades em algum momento, ou no futuro deseja adicionar novos métodos e precisa usar dados simulados para testar os métodos recém-adicionados, você deve adotar o padrão de design semi-singleton.
Se você criou sua classe, concluiu o teste de unidade e deseja publicá-lo por meio de uma estrutura ou biblioteca, você pode optar por padrões de design singleton puros. Como você criou a classe e algum outro desenvolvedor irá usá-la, o teste unitário de sua classe singleton é de sua responsabilidade antes do lançamento, e não de responsabilidade do desenvolvedor que a está usando. Se você criou sua classe, testou sua unidade e deseja distribuí-la por meio de uma estrutura ou biblioteca, você pode usar o padrão de design Pure Singleton. Como você criou esta classe, alguns outros desenvolvedores irão usá-la, portanto, o teste de unidade da classe singleton antes de liberá-la é de sua responsabilidade, não dos desenvolvedores que a utilizam.
What to read next
Want more posts about Translation?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #Translation?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home