Startec

Startec

Design Patterns: Singleton · seujorge

Mai 18, às 05:25

·

3 min de leitura

·

0 leituras

Singleton Design Pattern Motivação Singleton é uma classe a qual somente uma única instância pode exister. O objetivo aqui é garantir que uma classe tenha apenas uma instância e apenas um...
Design Patterns: Singleton · seujorge

Singleton Design Pattern

Motivação

Singleton é uma classe a qual somente uma única instância pode exister. O objetivo aqui é garantir que uma classe tenha apenas uma instância e apenas um ponto de acesso global.

Exemplo de Aplicação Prática

classDiagram
 class Singleton {
 - static instance: Singleton
 - Singleton()
 + statc getInstance(): Singleton
 }

Sendo assim a implementação seria algo do tipo:

package br.com.jorgerabellodev.singleton;
public final class Singleton {
 private static Singleton instance;
 private Singleton() {
 }
 public static Singleton getInstance() {
 if (instance == null) {
 instance = new Singleton(); // teremos apenas uma instância
 }
 return instance;
 }
}

Execução e Uso

package br.com.jorgerabellodev.singleton;
public class Main {
 public static void main(String[] args) {
 Singleton firstSingleton = Singleton.getInstance();
 Singleton secondSingleton = Singleton.getInstance();
 // note que se referem ao mesmo endereço
 System.out.println(firstSingleton);
 System.out.println(secondSingleton);
 // logo serão iguais ao serem comparados com equals()
 System.out.println(firstSingleton.equals(secondSingleton));
 System.out.println(secondSingleton.equals(firstSingleton));
 }
}

Testes Unitários

package br.com.jorgerabellodev.singleton;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.DisplayName.class)
class SingletonTest {
 @Test
 @DisplayName("Deve haver apenas uma instância do singleton")
 void deveHaverApenasUmaInstanciaDoSingleton() {
 Singleton firstInstance = Singleton.getInstance();
 Singleton secondInstance = Singleton.getInstance();
 boolean isEquals = firstInstance.equals(secondInstance);
 Assertions.assertThat(isEquals).isTrue();
 }
}

Note também que como o contrutor é privado, fica impossível instanciar um Singleton com new Singleton() por exemplo. A única forma de se conseguir uma instância é por meio do método estático getInstance(), que por sua vez sempre vai checar se o deve ou não criar uma nova instância.

Caso de Uso

Vamos imaginar uma aplicação onde temos uma classe de configurações e esa classe de configurações deve ler as configurações do arquivo config.properties localizado no projeto.

Queremos que haja apenas uma instância de configuração e logo, para tal, vamos implementar o design pattern singleton.

classDiagram
 class Configuration {
 - static configuration: Configuration
 - static properties: Properties
 - Configuration()
 + statc getInstance(): Configuration
 }
graph LR;
 id1(config.properties\n\nclassdriver\nusername\npassword);

Primeiro crie o arquivo config.properties em /src/main/resources/config.properties, com o seguinte conteúdo:

classDriver=jdbc:mysql://localhost/dbname?userUnicode=true&characterEncoding=utf8
username=yourUsername
password=yourSecretPassword

Agora vamos implementar a classe que lê esse arquivo de configurações, utilizando o design pattern Singleton.

package br.com.jorgerabellodev.singleton;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Configuration {
 private static Configuration configuration;
 private static Properties properties;
 private Configuration() {
 try {
 if (properties == null) {
 properties = new Properties();
 InputStream resourceAsStream = this.getClass().getResourceAsStream("/config.properties");
 properties.load(resourceAsStream);
 }
 } catch (IOException exception) {
 exception.printStackTrace();
 }
 }
 public static Configuration getInstance() {
 if (configuration == null) {
 configuration = new Configuration(); // single instance
 }
 return configuration;
 }
 public static String get(String key) {
 return properties.getProperty(key);
 }
}

Exemplos de Possíveis Testes Unitários

package br.com.jorgerabellodev.singleton;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.DisplayName.class)
class ConfigurationTest {
 @Test
 @DisplayName("Deve haver apenas uma instância do singleton de configuração")
 void deveHaverApenasUmaInstanciaDoSingleton() {
 Configuration firstInstance = Configuration.getInstance();
 Configuration secondInstance = Configuration.getInstance();
 boolean isEquals = firstInstance.equals(secondInstance);
 Assertions.assertThat(isEquals).isTrue();
 }
 @Test
 @DisplayName("Dado que as instâncias são iguais devem sempre recuperar os mesmos dados")
 void dadoQueAsInstanciasSaoIguaisDevemSempreRecuperarOsMesmosDados() {
 Configuration firstInstance = Configuration.getInstance();
 Configuration secondInstance = Configuration.getInstance();
 String firstClassDriver = firstInstance.get("classDriver");
 String firstUserName = firstInstance.get("username");
 String firstPassword = firstInstance.get("password");
 String secondClassDriver = secondInstance.get("classDriver");
 String secondUserName = secondInstance.get("username");
 String secondPassword = secondInstance.get("password");
 Assertions.assertThat(firstClassDriver).isEqualTo(secondClassDriver);
 Assertions.assertThat(firstUserName).isEqualTo(secondUserName);
 Assertions.assertThat(firstPassword).isEqualTo(secondPassword);
 }
}

Código

https://bitbucket.org/jorge_rabello/singleton/src/master/


Continue lendo

Showmetech

Motorola Razr Plus é o novo dobrável rival do Galaxy Z Flip
Após duas tentativas da Motorola em emplacar — novamente — telefones dobráveis, eis que temos aqui a terceira, e aparentemente bem-vinda, tentativa. Estamos falando do Motorola Razr Plus, um smartphone...

Hoje, às 15:20

DEV

Mentoring for the LGBTQ+ Community
Once unpublished, all posts by chetanan will become hidden and only accessible to themselves. If chetanan is not suspended, they can still re-publish their posts from their dashboard. Note: Once...

Hoje, às 15:13

TabNews

IA: mais um arrependido / Déficit de TI / Apple: acusação grave · NewsletterOficial
Mais um pioneiro da IA se arrepende de seu trabalho: Yoshua Bengio teria priorizado segurança em vez de utilidade se soubesse o ritmo em que a tecnologia evoluiria – ele junta-se a Geoffr...

Hoje, às 14:37

Hacker News

The Analog Thing: Analog Computing for the Future
THE ANALOG THING (THAT) THE ANALOG THING (THAT) is a high-quality, low-cost, open-source, and not-for-profit cutting-edge analog computer. THAT allows modeling dynamic systems with great speed,...

Hoje, às 14:25

TabNews

[DISCUSÃO/OPINIÕES] – Outsourcing! O que, para quem, por que sim, por que não! · dougg
Quero tentar trazer nesta minha primeira publicação, uma mistura de um breve esclarecimento sobre o que são empresas de outsourcing, como elas funcionam e ganham dinheiro, mas também, ven...

Hoje, às 13:58

TabNews

Duvida: JavaScript - Desenvolver uma aplicação que vai ler um arquivo *.json · RafaelMesquita
Bom dia a todos Estou estudando javascript e me deparei com uma dificuldade e preciso de ajuda *Objetivo do estudo: *desenvolver uma aplicação que vai ler um arquivo *.json Conteudo do in...

Hoje, às 13:43

Showmetech

Automatize suas negociações com um robô de criptomoedas
Índice Como o robô de criptomoedas Bitsgap funciona?Qual a vantagem de utilizar um robô de criptomoedas?Bitsgap é confiável? O mercado de trading tem se tornado cada vez mais popular e as possibilidades de...

Hoje, às 13:13

Hacker News

Sketch of a Post-ORM
I’ve been writing a lot of database access code as of late. It’s frustrating that in 2023, my choices are still to either write all of the boilerplate by hand, or hand all database access over to some...

Hoje, às 13:11

Showmetech

14 chuveiros elétricos para o banho dos seus sonhos
Índice Chuveiro ou Ducha?Tipos de chuveiro elétrico9 fatores importantes para considerar na hora de comprar chuveiros elétricosMelhores chuveiros elétricosDuo Shower LorenzettiFit HydraAcqua Storm Ultra...

Hoje, às 11:00

DEV

Learn about the difference between var, let, and const keywords in JavaScript and when to use them.
var, let, and const: What's the Difference in JavaScript? JavaScript is a dynamic and flexible language that allows you to declare variables in different ways. You can use var, let, or const keywords to...

Hoje, às 10:21