Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

details

Libere esse material sem enrolação!

Craque NetoCraque Neto

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Projetando classes
Apresentação
Em programação e na orientação a objetos, existem elementos importantes que refletem no 
comportamento dos objetos. A classe é um tipo abstrato de dados (TAD), utilizada para abstrair um 
conjunto de objetos que sejam representados por características similares.
Para desenvolvermos aplicações utilizando o paradigma de orientação a objetos, podemos definir 
que projetar classes é um importante desafio. Segundo Horstmann (2009), classes são coleções de 
objetos; portanto, precisamos começar a atividade de programação identificando os objetos e as 
classes às quais eles pertencem.
Nesta Unidade de Aprendizagem, você vai estudar os conceitos de coesão e acoplamento, que são 
importantes para formar uma estrutura de classes consistente. Além disso, vai estudar o conceito 
de pacotes, que são uma forma de organizar as classes do nosso projeto.
Bons estudos.
Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados:
Identificar objetos e definir a quais classes eles pertencem.•
Definir coesão e acoplamento.•
Usar pacotes para organizar classes.•
Desafio
Projetar uma classe pode ser um bom desafio, mas, quando seguimos algumas regras e padrões, 
nosso trabalho se torna menos árduo.
Analise o seguinte cenário:
Você trabalha como analista/programador em uma fábrica de softwares. Seu gerente solicitou que 
você atuasse em um projeto para o novo cliente, criando uma aplicação eficiente para atender às 
necessidades de controle de uma oficina mecânica. O principal objetivo é projetar uma aplicação 
capaz de: 
• automatizar o processo de manutenção de veículos; 
• realizar o cadastro de clientes; 
• controlar a entrada de veículos no setor de manutenção.
O módulo do sistema desenvolvido para cadastro de cliente precisa atender aos seguintes 
requisitos: 
• CPF; 
• nome do cliente; 
• endereço do cliente; 
• telefone do cliente; 
• e-mail do cliente.
O módulo do sistema desenvolvido para cadastro de veículos precisa atender aos seguintes 
requisitos de armazenamento de dados: 
• placa do veículo; 
• modelo do veículo; 
• ano do veículo; 
• fabricante do veículo; 
• cor do veículo.
Para executar essa tarefa, você precisará fazer o seguinte: 
• Criar um pacote chamado "modelo" – no qual serão armazenadas as classes “modelo”. 
• Criar um pacote chamado "controle" – no qual será armazenado o método main. 
 
A classe deve ser nomeada como “Principal” e será utilizada para instanciar as classes modelo e 
iniciar o programa. Seu gerente sugeriu o uso de uma linguagem de programação orientada a 
objetos (POO). Também sugeriu o uso da plataforma Java, utilizando o IDE NetBeans. Você precisa 
encaminhar o arquivo em formato .zip até o final do dia para oficializar a execução do projeto, 
seguindo todas as instruções. 
Infográfico
Os conceitos básicos sobre classes devem ser conhecidos pelos desenvolvedores que desejam 
desenvolver com base em linguagens orientadas a objetos. Entre os princípios que evitam 
problemas no uso de classes estão a coesão e o acoplamento. Ambos estão relacionados com os 
módulos de um sistema e associados aos conceitos de classes e à sua aplicação à POO.
 
Enquanto a coesão é o grau de responsabilidade única bem definida para uma classe, o 
acoplamento é o grau com o qual um módulo define sua dependência em relação aos demais, para 
garantir sua funcionalidade.
 
Veja, no Infográfico, uma descrição sobre escolha de classes e os princípios de coesão e 
acoplamento. Em seguida, você será desafiado com um quiz sobre as relações entre essas classes.
 
A imagem a seguir possui audiodescrição.
Aponte a câmera para o 
código e acesse o link do 
conteúdo ou clique no 
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/c1cff10f-8312-47ae-966a-1b8a47689529/223ed332-e425-4ca3-9ada-6611dcca5dec.png
Um projeto utilizando o modelo de orientação a objetos é estruturado em pacotes que armazenam 
classes semelhantes. Portanto, compreender os conceitos de classe é fundamental. Você está 
pronto? Para concluir o infográfico, você vai ser desafiado por meio de um teste.
A imagem a seguir possui audiodescrição.
Conteúdo interativo disponível na plataforma de ensino!
 
Conteúdo do Livro
Construir classes adequadas é fundamental no desenvolvimento de software orientado a objetos. 
Uma classe bem projetada encapsula um conjunto de atributos e métodos que representam uma 
entidade ou um conceito no domínio do problema. Uma boa classe deve ter uma responsabilidade 
única e bem definida, seguindo o princípio da coesão. Isso significa que cada classe deve ser focada 
em realizar uma tarefa específica, facilitando a compreensão, a manutenção e a reutilização do 
código. Ao instanciar objetos de uma classe, estamos criando instâncias únicas e independentes 
dessa classe. Além disso, escolher, nomear e estruturar bem as classes de uma aplicação, assim 
como organizá-las em pacotes, é de extrema importância. Portanto, o domínio desses conceitos se 
torna vital para o desenvolvimento de softwares.
Nesse capítulo do livro, você vai aprender como utilizar os conceitos de classes, métodos, atributos 
e instanciar objetos na prática, utilizando a linguagem Java. Além disso, vai entender como é 
importante ter alta coesão e baixo acoplamento em seus projetos, para que eles promovam uma 
boa qualidade de software e sejam fáceis de serem mantidos. Por fim, você vai aprender mais sobre 
pacotes e como utilizá-los para organizar seus projetos em Java.
Boa leitura.
Os elementos gráficos deste capítulo possuem audiodescrição. Para acessar o recurso, 
clique aqui 
https://creator-files.plataforma.grupoa.education/undefined/9108_Audiodescricao_Capitulo-2026-04-11T11:02:53-03:00.pdf
PROGRAMAÇÃO 
ORIENTADA A 
OBJETOS COM 
BANCO DE DADOS
OBJETIVOS DE APRENDIZAGEM
 > Identificar objetos e definir a quais classes eles pertencem.
 > Definir coesão e acoplamento.
 > Usar pacotes para organizar classes.
Introdução
Projetar boas classes é um aspecto fundamental no desenvolvimento de 
software. Uma classe bem projetada é coesa, ou seja, tem uma única respon-
sabilidade claramente definida. A coesão garante que a classe seja focada 
e específica, facilitando sua compreensão, manutenção e reutilização. Além 
disso, ao instanciar objetos a partir de classes, podemos criar instâncias úni-
cas e independentes, permitindo a manipulação de dados e a execução de 
funcionalidades específicas. Por meio dos atributos, podemos armazenar e 
representar o estado dos objetos, enquanto os métodos nos permitem definir 
o comportamento desses objetos. 
Nesse âmbito, é importante entender a relação entre as classes e como 
elas se comunicam entre si. O acoplamento entre classes deve ser gerenciado 
adequadamente, evitando dependências excessivas para garantir um sistema 
mais flexível e mais fácil de manter e modificar. Por meio dos pacotes, podemos 
organizar e agrupar classes relacionadas, controlando a visibilidade e evitando 
conflitos de nomes. 
Neste capítulo, você vai aprender o que são objetos, como instanciá-los e 
como acessar seus atributos e métodos. Além disso, vai aprender a diferenciar 
princípios de coesão e acoplamento de classes. Por fim, vai entender como 
organizar as classes de um projeto ao fazer uso de pacotes. A compreensão 
Projetando classes
Nicolli Souza Rios Alves
desses conceitos é essencial para desenvolver um código modular, legível e de 
fácil manutenção, resultando em um software de alta qualidade e eficiência.
Objetos
Na programação orientada a objetos, as classes desempenham um papel fun-
damental. Uma classe é uma estrutura que define um conjunto de propriedades 
(atributos) e comportamentos (métodos) que os objetos desse tipo podem 
ter (HORSTMANN, 2008). Ela funciona como um modelo ou uma planta para a 
criação de objetos. Por meio da classe, podemos definir as características e 
funcionalidades que os objetos terão.
Uma vez que a classe tenha sido definida, podemos criar instânciasdela, 
que são chamadas de objetos. Os objetos são as entidades reais que existem 
em tempo de execução, e podem interagir uns com os outros (HORSTMANN, 
2008). Eles possuem um estado (representado pelos valores de seus atributos) 
e podem realizar ações (invocando seus métodos).
Os objetos são criados com base na classe e herdam suas propriedades e 
comportamentos. Cada objeto pode ter valores diferentes para seus atributos, 
o que permite representar diferentes instâncias do mesmo tipo. Se tivermos, 
por exemplo, uma classe chamada Carro, podemos criar vários objetos desse 
tipo, como Carro1 e Carro2, cada qual com suas próprias características 
específicas, como cor, modelo, ano, etc.
A programação orientada a objetos permite modelar o mundo real de 
forma mais precisa, organizando o código em entidades independentes e 
reutilizáveis. As classes fornecem uma abstração para representar conceitos 
e entidades, enquanto os objetos permitem a criação de instâncias únicas 
com suas próprias características e comportamentos (SCHILDT, 2015). Essa 
abordagem promove modularidade, encapsulamento, reutilização de código 
e simplificação do desenvolvimento de software.
Em Java, para instanciar um objeto, vamos precisar seguir os seguintes 
passos (FINEGAN; LIGUORI, 2018):
Passo 1
Essa etapa diz respeito à definição da classe. Primeiramente, precisamos ter 
uma classe definida. Vamos supor que temos uma classe chamada Carro, 
com alguns atributos e métodos:
Projetando classes2
public class Carro {
 private String marca;
 private String modelo;
 public Carro(String marca, String modelo) {
 this.marca = marca;
 this.modelo = modelo;
 }
 public void setMarca(String marca) {
 this.marca = marca;
 }
 public String getMarca() {
 return marca;
 }
 public void setModelo(String modelo) {
 this.modelo = modelo;
 }
 public String getModelo() {
 return modelo;
 }
 public void acelerar() {
 // Implementação do método acelerar
 }
 public void frear() {
 // Implementação do método frear
 }
}
Projetando classes 3
Passo 2
Esta etapa diz respeito à criação de uma instância. Assim, podemos criar 
uma instância (objeto) dessa classe utilizando o operador new, seguido do 
nome da classe e dos parâmetros necessários para o construtor, se houver. 
Por exemplo:
Carro meuCarro = new Carro(“Toyota”, “Corolla”);
Nesse exemplo, criamos um objeto chamado meuCarro, que é uma instân-
cia da classe Carro. O construtor da classe Carro recebe dois parâmetros 
(marca e modelo) e os valores passados durante a criação do objeto são 
"Toyota" e "Corolla".
Agora, podemos usar o objeto meuCarro para acessar seus atributos e 
métodos. Por exemplo:
System.out.println(meuCarro.getMarca()); // Saída: Toyota
System.out.println(meuCarro.getModelo()); // Saída: Corolla
meuCarro.acelerar(); // Chamada do método acelerar
meuCarro.frear(); // Chamada do método frear
Dessa forma, podemos instanciar objetos em Java, criar várias instâncias 
da mesma classe com diferentes valores para seus atributos e utilizar os 
métodos definidos na classe para interagir com esses objetos. 
Em Java, para acessar métodos e atributos de uma classe, precisamos ter 
uma instância (objeto) da classe e usar o operador ponto (.) para referenciar 
o objeto e acessar seus membros. Vamos entender como fazer isso (ARNOLD; 
GOSLING; HOLMES, 2005).
Passo 1
A primeira etapa diz respeito a acessar atributos. Se o atributo for público 
(declaração com o modificador public), podemos acessá-lo diretamente 
usando o operador ponto. Por exemplo:
 Carro meuCarro = new Carro();
 meuCarro.marca = "Toyota";
 meuCarro.modelo = "Corolla";
Projetando classes4
Se o atributo for privado (declaração com o modificador private), é 
recomendado o uso de métodos de acesso (getters e setters) para ler e 
alterar o valor do atributo. Por exemplo:
 public class Carro {
 private String marca;
 private String modelo;
 // getters
 public String getMarca() {
 return marca;
 }
 public String getModelo() {
 return modelo;
 }
 // setters
 public void setMarca(String marca) {
 this.marca = marca;
 }
 public void setModelo(String modelo) {
 this.modelo = modelo;
 }
 }
E então podemos acessar os atributos usando os métodos de acesso:
 Carro meuCarro = new Carro();
 meuCarro.setMarca("Toyota");
 meuCarro.setModelo("Corolla");
 System.out.println(meuCarro.getMarca()); // Saída: Toyota
 System.out.println(meuCarro.getModelo()); // Saída: Corolla
Projetando classes 5
Passo 2
A segunda etapa diz respeito a acessar métodos. Para acessar um método 
de uma classe, também precisamos de uma instância (objeto) da classe. Use 
o operador ponto (.) para chamar o método. Por exemplo:
 Carro meuCarro = new Carro();
 meuCarro.acelerar();
 meuCarro.frear();
Se o método tiver parâmetros, precisamos passar os valores corretos 
durante a chamada. Por exemplo:
 public class Carro {
 // ...
 public void ligarMotor(int cilindradas) {
 // Implementação do método ligarMotor
 }
 }
E então podemos chamar o método e passar o valor do parâmetro da 
seguinte forma, por exemplo:
 Carro meuCarro = new Carro();
 meuCarro.ligarMotor(2000);
Essas são as formas básicas de acessar métodos e atributos de uma 
classe em Java. Lembre-se de que os modificadores de acesso (como vimos 
public e private) afetam a forma como os membros da classe podem ser 
acessados de outras partes do código.
Até aqui, exploramos alguns conceitos fundamentais da programação 
orientada a objetos. Aprendemos o que são objetos, como instanciá-los e como 
acessar seus atributos e métodos. Vimos como criar classes que definem a 
estrutura e o comportamento dos objetos. Na próxima seção, vamos dar um 
passo adiante e mergulhar nos princípios de coesão e acoplamento de classes.
Projetando classes6
Ao nomear classes, atributos, métodos e objetos em programação 
orientada a objetos, é importante seguir algumas boas práticas para 
garantir um código claro, legível e fácil de entender. Eis algumas diretrizes para 
nomeação (ARNOLD; GOSLING; HOLMES, 2005):
 � Nomeclatura descritiva: escolha nomes que sejam descritivos e reflitam cla-
ramente a finalidade e o papel do elemento no código. Evite nomes genéricos 
ou abreviações confusas. Prefira nomes completos e claros que facilitem a 
compreensão.
 � Atente-se à capitalização consistente: siga uma convenção de capitalização 
consistente ao nomear suas classes, atributos, métodos e objetos. Utilize o for-
mato camelCase para nomes compostos, começando com uma letra maiúscula 
para cada palavra subsequente (exemplo: minhaClasse, meuAtributo).
 � Evite abreviações excessivas: embora algumas abreviações possam ser acei-
táveis e amplamente reconhecidas na comunidade de desenvolvimento, 
evite abreviações excessivas que possam tornar o código difícil de entender. 
Priorize nomes completos e claros.
 � Use substantivos e verbos: normalmente, as classes e os objetos são nomea-
dos com substantivos, representando entidades ou conceitos no domínio do 
problema. Os atributos representam características ou propriedades dessas 
entidades e também devem ser nomeados com substantivos descritivos. Já 
os métodos, que representam ações ou comportamentos, devem ser nome-
ados com verbos ou expressões verbais que indiquem o que o método faz.
 � Tenha consistência em convenções de nomes: siga as convenções de nomes 
estabelecidas pela linguagem de programação que você está utilizando. Em 
Java, por exemplo, a convenção geralmente é utilizar camelCase para nomes 
de atributos e métodos, e PascalCase para nomes de classes.
 � Evite nomes ambíguos: evite usar nomes que possam causar confusão ou 
ambiguidade. Escolha nomes que sejam distintos o suficiente para evitar 
confusões durante a leitura e a manutenção do código.
 � Evite nomes muito longos: embora seja importante fornecer nomes descritivos, 
evite nomes excessivamentelongos que dificultem a leitura e a digitação. 
Procure um equilíbrio entre a clareza e a concisão.
 � Evite prefixos ou sufixos desnecessários: a menos que exigido por conven-
ções específicas ou para evitar conflitos de nomes, evite o uso de prefixos 
ou sufixos desnecessários em seus nomes. Os nomes devem ser claros o 
suficiente por si só.
Lembrando que essas são diretrizes gerais e podem variar dependendo das 
práticas específicas da linguagem de programação ou do framework utilizado. 
Projetando classes 7
Princípios de coesão e acoplamento
A manutenibilidade de software é a capacidade de um sistema ser facilmente 
mantido e modificado ao longo do tempo. Um software bem mantido é aquele 
que permite correções de erros, melhorias e inclusão de novas funcionalidades 
de forma eficiente, sem introduzir problemas ou causar impactos indesejados 
em outras partes do sistema (SCHACH, 2010). Agora vamos compreender dois 
critérios úteis para analisar a qualidade da interface pública de uma classe: 
a coesão e o acoplamento, que são conceitos fundamentais na programação 
orientada a objetos e que desempenham um papel importante na manute-
nibilidade do software.
Coesão
Em programação orientada a objetos, a coesão refere-se à organização interna 
de uma classe, ou seja, o quão bem seus membros estão relacionados e traba-
lham juntos para cumprir uma única responsabilidade. Uma classe coesa tem 
uma responsabilidade clara e específica, e todos os seus atributos e métodos 
estão diretamente relacionados a essa responsabilidade. Isso resulta em 
um código mais organizado, legível e de fácil compreensão (SCHACH, 2010).
A coesão desempenha um papel fundamental na manutenibilidade do 
software, pois uma classe coesa é mais fácil de ser mantida e modificada 
ao longo do tempo. Quando os membros de uma classe estão intimamente 
relacionados e trabalham em conjunto para cumprir uma única responsabili-
dade, as alterações numa parte específica da classe têm um impacto mínimo 
nas outras partes do sistema (SCHACH, 2010). Isso reduz o risco de efeitos 
colaterais indesejados e facilita a identificação e correção de erros.
Além disso, a coesão também facilita a reutilização de código. Uma classe 
coesa contém um conjunto claro de funcionalidades relacionadas, o que torna 
mais fácil identificar e extrair partes do código que possam ser reutilizadas 
em outros contextos. Isso promove a modularidade e reduz a duplicação de 
código, tornando o sistema mais flexível e manutenível.
Ao desenvolver um software, é importante buscar a coesão em todas 
as classes do sistema. Isso envolve identificar a responsabilidade única de 
cada classe e garantir que seus membros estejam diretamente relacionados 
a essa responsabilidade (SCHACH, 2010). É uma prática recomendada manter 
as classes pequenas, focadas e coesas, permitindo que sejam facilmente 
compreendidas e modificadas quando necessário.
Projetando classes8
Vamos considerar um exemplo de uma classe chamada Calculadora, que 
possui métodos para realizar operações matemáticas simples. Essa classe 
apresenta a seguinte implementação:
public class Calculadora {
 public int somar(int a, int b) {
 return a + b;
 }
 public int subtrair(int a, int b) {
 return a - b;
 }
 public int multiplicar(int a, int b) {
 return a * b;
 }
 public double dividir(int a, int b) {
 return (double) a / b;
 }
}
Nesse exemplo, a classe Calculadora está coesa, já que todos os méto-
dos estão relacionados à sua responsabilidade única de realizar operações 
matemáticas. Cada método representa uma operação específica, como soma, 
subtração, multiplicação e divisão.
A classe Calculadora é coesa por vários motivos:
 � Responsabilidade única: a classe tem uma única responsabilidade, que 
é realizar operações matemáticas. Todos os métodos da classe estão 
diretamente relacionados a essa responsabilidade.
 � Funcionalidades relacionadas: todos os métodos realizam operações 
matemáticas e estão relacionados ao propósito da classe. Eles traba-
lham em conjunto para cumprir a responsabilidade da classe.
 � Legibilidade: a classe é fácil de entender e de ler. Os nomes dos mé-
todos são claros e descritivos, indicando a operação matemática que 
eles realizam.
Projetando classes 9
 � Manutenibilidade: essa classe coesa facilita a manutenção do código. 
Se houver a necessidade de adicionar uma nova operação matemática, 
basta criar um novo método relacionado à responsabilidade da classe. 
Não é necessário alterar outros métodos existentes ou adicionar fun-
cionalidades não relacionadas.
Vamos ver agora uma versão modificada da classe Calculadora, dessa 
vez de tal modo que ela não está coesa:
public class Calculadora {
 public int somar(int a, int b) {
 //implementação método somar
 }
 public int subtrair(int a, int b) {
 // implementação método subtrair
 }
 public int multiplicar(int a, int b) {
 // implementação método multiplicar
 }
 public double dividir(int a, int b) {
 // implementação método dividir
 }
 public void escreverLog(String mensagem) {
 // Método para escrever uma mensagem de log no sistema
 System.out.println("Log: " + mensagem);
 }
 public boolean validarEntradas(int a, int b) {
 // Método para validar as entradas antes de realizar 
as operações
 return a >= 0 && b >= 0;
 }
Projetando classes10
 public int calcularPotencia(int base, int expoente) {
 // Método para calcular a potência de um número
 return (int) Math.pow(base, expoente);
 }
}
Nesta versão modificada, a classe Calculadora não está coesa, uma vez 
que possui métodos que vão além de sua responsabilidade principal, que 
é realizar operações matemáticas. Podemos perceber essa falta de coesão 
nos seguinte métodos:
 � escreverLog: este método não está diretamente relacionado à 
responsabilidade da classe de realizar operações matemáticas. Ele 
lida com a funcionalidade de escrever mensagens de log, que é uma 
preocupação à parte.
 � validarEntradas: embora seja importante validar as entradas, esse 
método não faz parte da responsabilidade principal da classe. A vali-
dação das entradas pode ser tratada em um contexto diferente, como 
em um serviço de entrada de dados.
 � calcularPotencia: este método calcula a potência de um número, 
que é uma operação matemática, mas não é uma operação básica como 
soma, subtração, multiplicação e divisão. A inclusão desse método à 
classe Calculadora introduz uma funcionalidade adicional e não 
relacionada à responsabilidade principal da classe.
Essa falta de coesão torna a classe menos legível e mais difícil de entender 
e de manter. Também pode levar a uma maior dependência de outras partes do 
sistema, pois a classe lida com funcionalidades não relacionadas. Além disso, 
qualquer alteração em determinada parte da classe pode afetar inadvertida-
mente outras partes, aumentando a complexidade e a fragilidade do código.
É importante buscar a coesão em todas as classes do sistema, garantindo 
que cada uma delas tenha uma responsabilidade clara e bem definida (SCHACH, 
2010). Dessa forma, é possível obter um código mais organizado, legível e de 
fácil manutenção.
Projetando classes 11
Acoplamento
O acoplamento refere-se ao quanto as classes estão interconectadas e de-
pendentes umas das outras. Ele descreve o nível de conhecimento que uma 
classe tem sobre outras e como elas se comunicam entre si (SCHACH, 2010). 
Um alto acoplamento indica uma forte dependência entre as classes, enquanto 
um baixo acoplamento indica uma independência maior entre elas, como 
ilustra a Figura 1.
Figura 1. Níveis de acoplamento entre as classes: (a) alto; (b) baixo. 
A B
Quando duas classes estão acopladas, uma alteração em uma delas pode 
ter um impacto direto na outra. Isso ocorre porque as classes acopladas estão 
intimamente ligadas e compartilham informações e dependências. Quando 
uma classe é modificada, é necessário verificar se isso afeta outras classes 
que dela dependem,o que pode levar a alterações em várias partes do sistema.
Desse modo, um alto acoplamento pode levar a vários problemas (SCHACH, 
2010). Primeiramente, isso torna o código mais difícil de ser compreendido, 
mantido e reutilizado, já que as alterações em uma classe podem ter efeitos 
colaterais em outras partes do sistema, exigindo um esforço adicional para 
garantir que todas as dependências sejam atualizadas corretamente. Além 
disso, um alto acoplamento dificulta os testes unitários, pois fica mais difícil 
isolar as classes para testá-las de forma independente.
Por outro lado, um baixo acoplamento é desejável, pois indica uma maior 
independência entre as classes. Cada classe tem uma responsabilidade bem 
definida e se comunica com outras classes apenas por meio de interfaces 
específicas. Isso permite que as classes sejam modificadas de forma isolada, 
Projetando classes12
sem afetar o funcionamento de outras partes do sistema. Além disso, um 
baixo acoplamento facilita a reutilização de código, pois as classes podem 
ser extraídas e utilizadas em diferentes contextos sem arrastar consigo 
muitas dependências.
Para reduzir o acoplamento entre classes em um sistema, podemos 
adotar as seguintes práticas (ARNOLD; GOSLING; HOLMES, 2005; 
SCHACH, 2010): 
 � Princípio da responsabilidade única: devemos garantir que cada classe tenha 
uma única responsabilidade bem definida. Evitemos que uma classe realize 
múltiplas tarefas, pois isso aumenta o acoplamento com outras classes. 
Dividimos as responsabilidades em classes separadas para manter um aco-
plamento baixo.
 � Injeção de dependência: em vez de criar dependências diretamente dentro 
de uma classe, devemos injetá-las por meio de construtores, métodos ou 
propriedades. Isso permite que as dependências sejam fornecidas externa-
mente, facilitando a substituição e o teste de componentes independentes. 
A utilização de frameworks de injeção de dependência pode ajudar nesse 
processo.
 � Interfaces e abstrações: devemos utilizar interfaces e abstrações para inte-
ragir com outras classes. Isso permite que escrevamos código dependente 
de interfaces em vez de implementações concretas. Dessa forma, é possível 
substituir facilmente as implementações subjacentes sem afetar o código 
que as utiliza, reduzindo o acoplamento.
 � Padrões de projeto (design patterns): devemos utilizar padrões de projeto, 
como o Observer ou o Strategy, para reduzir o acoplamento entre classes. 
Esses padrões promovem a comunicação indireta e flexível entre objetos, 
diminuindo o acoplamento direto.
 � Camadas e módulos: devemos organizar seu código em camadas ou módulos 
bem definidos, pois isso ajuda a limitar a comunicação e a dependência entre 
classes pertencentes a diferentes camadas ou módulos. Nesse caso, o reco-
mendado é utilizar interfaces ou serviços para estabelecer a comunicação 
entre essas camadas, reduzindo o acoplamento direto.
 � Refatoração: devemos regularmente revisar e refatorar nosso código para 
reduzir o acoplamento. Para isso, é preciso identificar as dependências des-
necessárias e maneiras de reduzi-las. Isso pode envolver a reorganização 
do código, a extração de interfaces, a criação de classes intermediárias ou 
a aplicação de padrões de projeto.
Projetando classes 13
Vamos analisar agora um exemplo de uma classe em Java com alto 
acoplamento:
public class Pedido {
 private Cliente cliente;
 private Estoque estoque;
 private NotificacaoService notificacaoService;
 public Pedido(Cliente cliente) {
 this.cliente = cliente;
 this.estoque = new Estoque();
 this.notificacaoService = new NotificacaoService();
 }
 public void adicionarItem(ItemPedido item) {
 if (estoque.verificarDisponibilidade(item.getPro-
duto(), item.getQuantidade())) {
 estoque.atualizarEstoque(item.getProduto(), item.
getQuantidade());
 notificacaoService.enviarMensagem(cliente.getE-
mail(), "Item adicionado ao pedido.");
 } else {
 notificacaoService.enviarMensagem(cliente.getE-
mail(), "Item não disponível em estoque.");
 }
 }
}
Neste exemplo, a classe Pedido está acoplada de forma significativa 
a outras classes, como Cliente, Estoque e NotificacaoService. Isso 
pode ser considerado um alto acoplamento, já que a classe Pedido tem 
dependências diretas dessas classes e as utiliza internamente para realizar 
suas operações.
O acoplamento ocorre porque a classe Pedido cria instâncias das classes 
Estoque e NotificacaoService dentro do construtor e faz chamadas 
diretas aos métodos dessas classes no método adicionarItem(). Essa 
dependência direta torna a classe Pedido fortemente acoplada a essas 
classes específicas.
Projetando classes14
Esse alto acoplamento pode ser problemático, porque qualquer modifica-
ção nas classes Estoque ou NotificacaoService pode exigir alterações 
na classe Pedido. Além disso, a classe Pedido não pode ser facilmente 
substituída por outra implementação que utiliza classes diferentes para 
estoque ou notificações, o que reduz a flexibilidade e reutilização do código.
Para reduzir o acoplamento nesse exemplo, seria possível aplicar princípios 
como a injeção de dependência (dependency injection) (HORSTMANN, 2008). 
Ao invés de instanciar diretamente as dependências dentro da classe Pedido, 
as instâncias das classes Estoque e NotificacaoService poderiam ser 
passadas como parâmetros no construtor do Pedido, permitindo uma maior 
flexibilidade e desacoplamento entre as classes.
Vamos analisar agora um exemplo de uma classe em Java com baixo 
acoplamento:
public class CarrinhoCompras {
 private List itens;
 private ServicoEstoque servicoEstoque;
 private ServicoNotificacao servicoNotificacao;
 public CarrinhoCompras(ServicoEstoque servicoEstoque, 
ServicoNotificacao servicoNotificacao) {
 this.itens = new ArrayList();
 this.servicoEstoque = servicoEstoque;
 this.servicoNotificacao = servicoNotificacao;
 }
 public void adicionarItem(ItemProduto item) {
 if (servicoEstoque.verificarDisponibilidade(item.
getProduto(), item.getQuantidade())) {
 servicoEstoque.atualizarEstoque(item.getProduto(), 
item.getQuantidade());
 servicoNotificacao.enviarMensagem("Item adicionado 
ao carrinho.");
 itens.add(item);
Projetando classes 15
 } else {
 servicoNotificacao.enviarMensagem("Item não dis-
ponível em estoque.");
 }
 }
 // Restante da implementação da classe
}
Neste exemplo, a classe CarrinhoCompras tem baixo acoplamento, pois 
suas dependências (ServicoEstoque e ServicoNotificacao) são passadas 
para ela através do construtor. Isso permite que a classe seja independente 
das implementações específicas dessas dependências, o que aumenta sua 
flexibilidade e reutilização.
A classe CarrinhoCompras não instancia diretamente as dependências, 
mas recebe-as como argumentos no construtor (dependency injection). Dessa 
forma, a classe não está fortemente acoplada às implementações concretas 
dos serviços de estoque e notificação.
Essa abordagem de baixo acoplamento facilita a substituição das imple-
mentações de ServicoEstoque e ServicoNotificacao por outras classes 
que implementam as mesmas interfaces ou superclasses. Além disso, ela 
permite que a classe CarrinhoCompras seja facilmente testada de forma 
isolada, usando implementações de teste para os serviços de estoque e 
notificação.
Agora que entendemos a importância da coesão e do baixo acoplamento 
no design de classes, estamos prontos para avançar para o próximo tópico: 
pacotes.
Pacotes 
Um dos princípios fundamentais na programação orientada a objetos é a 
organização e estruturação do código de forma eficiente e modular. Uma das 
maneiras de alcançar isso é pelo uso de pacotes. Os pacotes são unidades 
lógicas de agrupamento de classes e outros elementos relacionados, pro-
porcionando uma maneira de organizar e gerenciar o código em projetos de 
software (ARNOLD; GOSLING; HOLMES, 2005).
Projetando classes16
Um pacote é umaforma de agrupar classes e outros elementos relacio-
nados numa única unidade. Ele proporciona uma maneira de organizar e 
estruturar o código, facilitando a reutilização, manutenção e colaboração 
entre desenvolvedores (SCHACH, 2010).
Os pacotes ajudam a evitar conflitos de nomes, pois permitem a definição 
de namespaces (mecanismo utilizado em programação para evitar conflitos 
de nomes entre diferentes entidades, como classes, funções, variáveis, etc.) 
separados para diferentes partes do código. Isso significa que podemos ter 
classes com o mesmo nome em pacotes diferentes sem causar conflitos. 
A Figura 2 mostra a organização de um projeto-exemplo com nome MARATONA-
-JAVA-DEVDOJO, que tem a disposição dos arquivos-fonte da biblioteca, que 
corresponde à disposição de seus pacotes.
Figura 2. Organização de pastas e pacotes de um projeto Java no Visual Studio Code.
Além disso, os pacotes fornecem um mecanismo para controlar a visi-
bilidade dos elementos dentro deles. Podemos especificar quais classes 
e membros são visíveis para outras partes do código, definindo-os como 
públicos, protegidos, privados ou com acesso de pacote. Isso ajuda a garantir 
o encapsulamento e a modularidade do código.
Os pacotes também oferecem vantagens em termos de reutilização de 
código. Ao agrupar classes relacionadas em um pacote, fica mais fácil iden-
tificar e utilizar as classes necessárias em diferentes partes do projeto (PE-
CINOVSKÝ, 2013). Além disso, pacotes bem definidos e organizados podem 
ser empacotados em bibliotecas ou módulos independentes, que podem ser 
compartilhados e reutilizados em outros projetos.
Projetando classes 17
Em linguagens como Java, os pacotes são representados por diretórios 
no sistema de arquivos. Cada pacote tem um nome único que segue uma 
convenção de nomenclatura em formato de nome de domínio reverso, como 
com.example.mypackage. Essa estrutura de diretórios reflete a hierarquia 
dos pacotes e facilita a localização e organização das classes correspondentes.
Para utilizar pacotes e organizar as classes de um projeto, você pode seguir 
os seguintes passos (PECINOVSKÝ, 2013; SCHILDT, 2015):
1. Definir uma estrutura de diretórios: começamos criando uma estrutura 
de diretórios correspondente aos pacotes em seu sistema de arquivos. 
Se, por exemplo estivermos usando Java e houver um pacote chamado 
com.example.projeto, criamos um diretório com, dentro do qual 
haverá outro diretório chamado exemplo e, dentro deste, um diretório 
chamado projeto.
2. Nomear pacotes: devemos escolher nomes significativos e descritivos 
para nossos pacotes, seguindo uma convenção de nomenclatura em 
formato de nome de domínio reverso. Se, por exemplo, nosso projeto 
é um aplicativo de vendas, podemos ter pacotes como com.example.
projeto.clientes, com.example.projeto.produtos, etc.
3. Organizar as classes em pacotes: devemos mover nossas classes para 
os diretórios correspondentes aos pacotes que definimos. É preciso 
garantir que cada arquivo fonte esteja localizado no diretório correto, 
de acordo com sua declaração de pacote no início do arquivo. Se, por 
exemplo, a classe pertencer ao pacote com.example.projeto.clien-
tes, movemos o arquivo para o diretório com/example/projeto/
clientes.
4. Gerenciar as dependências entre pacotes: é preciso garantir que os pa-
cotes tenham dependências claras e limitadas entre si. Isso significa que 
as classes em um pacote devem depender apenas de classes em outros 
pacotes quando necessário, evitando dependências desnecessárias. 
Devemos manter a coesão em mente, agrupando classes relacionadas 
em pacotes para facilitar o entendimento e a manutenção do código.
5. Definir a visibilidade dos membros: dentro de cada pacote, definimos 
a visibilidade dos membros (classes, métodos, atributos) de acordo 
com as necessidades. Use os modificadores de acesso adequados, 
como public, protected ou private, para controlar a visibilidade 
e garantir o encapsulamento adequado.
Projetando classes18
6. Importar classes de outros pacotes: ao utilizar uma classe de outro 
pacote no nosso código, vamos precisar importá-la usando a decla-
ração import. Isso permite que a gente consiga acessar as classes 
de outros pacotes sem precisar digitar o nome completo do pacote 
sempre que usá-las.
Ao organizar nossas classes em pacotes, precisamos seguir uma estrutura 
lógica e coerente, agrupando classes relacionadas em pacotes adequados. 
Essa abordagem facilitará a navegação, a manutenção e a reutilização do 
código em nosso projeto, tornando-o mais modular e coeso. Além disso, o uso 
correto de pacotes ajuda a evitar conflitos de nomes e melhora a legibilidade 
e a escalabilidade do projeto.
Nesse capítulo, pudemos explorar diversos conceitos fundamentais da 
programação orientada a objetos. Aprendemos a instanciar objetos a par-
tir de uma classe, utilizando o operador new para criar instâncias únicas e 
independentes. Com isso, pudemos acessar os métodos e atributos desses 
objetos, permitindo a manipulação dos dados e a execução das funcionalidades 
definidas na classe. Além disso, compreendemos a importância da coesão 
e do acoplamento, de forma a aumentar a legibilidade, a flexibilidade e a 
manutenibilidade do código. Por fim, conhecemos os pacotes, que permitem 
agrupar classes relacionadas, controlar a visibilidade e evitar conflitos de 
nomes. Conhecer esse conceito é fundamental para manter um código es-
truturado, facilitar a colaboração entre desenvolvedores e promover o reuso. 
Todos esses conceitos estudados são essenciais para desenvolver projetos 
de software mais robustos, eficientes e de fácil manutenção.
Referências
ARNOLD, K..; GOSLING, J.; HOLMES, D. The Java programming language. 4th ed. Boston: 
Addison Wesley Professional, 2005.
FINEGAN, E.; LIGUORI, R. OCA Java SE 8: guia de estudos para o exame 1Z0-808. Porto 
Alegre: Bookman, 2018. 
HORSTMANN, C. Conceitos de computação com Java: compatível com Java 5 & 6. 5. ed. 
Porto Alegre: Bookman, 2008.
PECINOVSKÝ, R. OOP: learn object oriented thinking & programming. Živonín: Tomáš 
Bruckner, 2013.
SCHACH, S. R. Engenharia de software: os paradigmas clássico e orientado a objetos. 
7. ed. Porto Alegre: AMGH, 2010.
SCHILDT, H. Java para iniciantes: crie, compile e execute programas Java rapidamente. 
6. ed. Porto Alegre: Bookman, 2015. 
Projetando classes 19
Leituras recomendadas
BLOCH, J. Effective Java. 3rd ed. Boston: Addison-Wesley Professional, 2018.
ESTEVÃO. Como criar minha primeira classe em Java. [S. l.]: DevMedia, 2019. Disponivel 
em: https://www.devmedia.com.br/como-criar-minha-primeira-classe-em-java/38940. 
Acesso em: 14 jun. 2023.
REGES, S.; STEPP, M. Building Java programs: a back to basics approach. 3rd ed. New 
York: Pearson, 2014.
RONALDO. Aprender Java: boas práticas para um bom projeto de software. [S. l.]: 
DevMedia, 2013. Disponível em: https://www.devmedia.com.br/aprender-java-boas-
-praticas-para-um-bom-projeto-de-software/29713. Acesso em: 14 jun. 2023. 
Os links para sites da web fornecidos neste capítulo foram todos 
testados, e seu funcionamento foi comprovado no momento da 
publicação do material. No entanto, a rede é extremamente dinâmica; suas 
páginas estão constantemente mudando de local e conteúdo. Assim, os edito-
res declaram não ter qualquer responsabilidade sobre qualidade, precisão ou 
integralidade das informações referidas em tais links.
Projetando classes20
Dica do Professor
Para começarmos um projeto, o primeiro passo é identificar quais objetos devem ser criados para a 
aplicação. As classes servem para classificar os objetos, como o próprio nome diz.
Existem diversos recursos que precisam ser utilizados dentro de um programa, como os métodos, 
que definem quais as ações serão executadas. Da mesma forma, as boas práticas de nomeação de 
classes devem ser adotadas para padronizar a estrutura de um programa.
Nesta Dica do Professor, você vai ver aspectos importantes da POO, selecionando práticas e 
requisitos que devem ser analisadosna fase de planejamento de um programa.
Os elementos gráficos deste capítulo possuem audiodescrição. Para acessar o recurso, 
clique aqui 
 
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://creator-files.plataforma.grupoa.education/undefined/9108_Audiodescricao_Dica_Professor-2026-04-11T11:22:30-03:00.pdf
https://fast.player.liquidplatform.com/pApiv2/embed/cee29914fad5b594d8f5918df1e801fd/a15f37c0a4bfd79bc5edabc748b90e84
Exercícios
1) É importante que o desenvolvedor compreenda a importância de manter as tarefas a serem 
executadas na construção de um código de maneira organizada. Assim como as boas 
práticas, os processos também devem ser conduzidos na ordem correta, considerando 
também a importância de cada um deles. 
Em orientação a objetos, como devemos começar as atividades de programação?
A) Identificando os atributos.
B) Identificando os métodos.
C) Identificando os requisitos funcionais da aplicação.
D) Identificando objetos e as classes às quais eles pertencem.
E) Identificando nomes de classes.
2) Ao criar um aplicativo, podem ser criadas diferentes classes, o que também traz maior 
coesão ao programa. Se uma classe com o nome “Cadastro” for criada, ainda não estará claro 
qual será sua responsabilidade, mas, se uma segunda classe, denominada “Cliente”, for 
criada, é evidente que seu objetivo será tratar da criação do objeto “Cliente”.
Considerando as informações sobre as classes, o que é correto afirmar?
A) Nomearmos uma classe utilizando um verbo que define o objetivo dessa classe.
B) Uma classe deve ser criada para representar vários conceitos do domínio do problema.
C) Se você não pode afirmar, a partir do nome da classe, o que um objeto da classe 
supostamente deve fazer, provavelmente você não está no caminho certo.
D) Uma categoria útil de classes pode ser descrita como atores. Essas classes servem para iniciar 
um programa.
E) Uma prática comum é nomear métodos com algum substantivo.
3) 
No contexto de desenvolvimento de software, em diversas situações, os desenvolvedores 
passam por problemas ou encontram bugs que precisam ser corrigidos, por influenciarem 
negativamente a funcionalidade de um aplicativo. Para evitar tais defeitos, alguns princípios 
podem ser aplicados, em conjunto com as boas práticas de programação.
Referente a coesão e acoplamento, o que se pode afirmar?
A) Uma classe coesa representa uma solução bem estruturada no que se refere à criação do 
objeto.
B) A interface pública de uma classe é coesa se abrange todos os requisitos funcionais do 
sistema.
C) Quando a interface pública de uma classe referencia vários conceitos, é um bom sinal de que 
pode ser hora de utilizar classes separadas.
D) Acoplamento refere-se à dependência que as classes têm em relação aos seus métodos.
E) Se muitas classes de um programa dependerem umas das outras, dizemos que o acoplamento 
entre as classes é baixo.
4) É uma boa prática evitar conflitos gerados pela nomeação incorreta de classes. Existem 
recursos que facilitam a escrita do código e auxiliam no processo de manter os objetos e 
todos os outros componentes atualizados. Os pacotes facilitam a busca ou pesquisa de 
classes, interfaces e enumerações.
Ainda sobre os pacotes, o que é correto afirmar?
A) São uma forma de organizar os métodos.
B) São um modificador de acesso.
C) Servem para iniciar programas.
D) Criamos objetos a partir das definições de um pacote.
E) São um conjunto de classes relacionadas.
Analise o código abaixo: 
 
/* 
package media; 
5) 
public class calcularMedia { 
 
private double nota1; 
private double nota2; 
private double media; 
private int matricula; 
private String nome; 
 
 
public void calcularMedia(double nota1, double nota2){ 
this.nota1 = nota1; 
this.nota2 = nota2; 
media = (nota1 + nota2)/2; 
 
} 
 
public void cadastrarAluno(int cod, String matricula){ 
this.cod=cod; 
this.matricula = matricula; 
} 
 
} 
*/ 
 
O que é correto afirmar?
A) A classe “calcularMedia” segue a regra geral para nomes de classes.
B) O método “calcularMedia” não irá executar a expressão aritmética.
C) Essa classe não está dentro de nenhum pacote.
D) Essa classe não apresenta coesão.
E) A classe está totalmente escrita de forma correta.
Na prática
A POO é um modelo de programação de software em que os objetos manipulados são abstrações 
de objetos do mundo real. Os objetos são as classes abstraídas do mundo real. Desse modo, um 
projeto que utiliza o modelo de orientação a objetos é estruturado em pacotes que armazenam 
classes semelhantes, exigindo que você conheça como é a relação entre essas classes.
Nesta Na Prática, você irá aprender como os pacotes funcionam.
A imagem a seguir possui audiodescrição.
Aponte a câmera para o 
código e acesse o link do 
conteúdo ou clique no 
código para acessar.
https://statics-marketplace.plataforma.grupoa.education/sagah/730c72d3-404f-4c28-932a-b4fc3cabee9c/e194dd0b-093a-4fcf-ad0a-c062d6162caa.png
Saiba mais
Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor:
Como criar uma classe com atributos
Veja este vídeo, que ensina a criar uma classe simples utilizando o eclipse, para que você possa 
praticar. O vídeo aborda dicas importantes para criação de um projeto.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
Java: declaração e utilização de classes
O texto aborda a sintaxe para declaração de uma classe. São trazidos exemplos de como utilizar 
uma classe em Java. Você também verá exemplos de instanciação de uma classe.
Aponte a câmera para o código e acesse o link do conteúdo ou clique no código para acessar.
https://www.youtube.com/embed/dauyBWO9-Vs
https://www.devmedia.com.br/java-declaracao-e-utilizacao-de-classes/38374

Mais conteúdos dessa disciplina