Quebra de encapsulamento

27 respostas
A

Galera, outro dia presenciei a discussa aqui no guj uma discussao sobre quebra de encapsulamento. Exemplo, uma modelagem para um site de vendas de qualquer coisa. Eu teria uma interface IProduto uma implementacao concreta Produto com algumas funcionalidades implementadas e alguma coisa tipo carro que herda de produto. Isso eh quebra de encapsulamento? Compor a classe com a classe produto seria correto? me parece estranho. Alguem tem algo a acrescentar? Queria saber mais sobre isso. Qualquer coisa eh valida.

Alberto

27 Respostas

Rubem_Azenha

Acho bobagem vc ter uma interface IProduto. Por mim, colocava tudo na classe concreta produto. Afinal, por um acaso vc vai ter várias implementações diferentes da interface produto?
Ou eu estou errado?

pcalcado

Antes de mais anda esqueça essa nomenclatura IProduto, em chama não é padrão utilizar I antes do identificador de uma interface.

Provavelmente você está se referindo a uma discussão apagada no acidente sobre mentawai e VRaptor2.

No caso a discussão era sobre se uma classe filha utilizar atributos protected de uma classe mãe era quebra de encapsulamento. De maneira geral eu responderia não.

A classe superior deve tratar suas classes inferiores como seus clientes e seus membros protected fazem parte da API, devendo ter os mesmos cuidados que membros públicos.

Fabricio_Cozer_Marti

Olá,
tem quem diga que é uma boa prática utilizar interfaces para todas as implementações possíveis, o padrão estrutural Bridge, por exemplo tenta separar esses segmentos (interface da implementação).
Isso IMHO, só seria válido caso você precise de um ‘engine’ ou algum processamento mais abstrato, que boa parte da lógica seria implementada a base de interfaces e não de classes.

Enfim, depende do problema específico colocar ou não uma interface para Produto, e também concordo que esse nome ‘IProduto’ não ficou claro, eu particularmente nomeio as interfaces com palavras que expressam um comportamento, tipo o padrão da sun, …able.

O java sendo uma linguagem O.O. permite que vc utilize a herança, e permite também que você sobreescreva os métodos da classe pai, isso é um conceito O.O., então cabe ao projetista arquitetural da aplicação decidir se o programador vai poder sobrescrever ou não tal método.

T

os OO mais puristas vao fazer vc criar interfaces para tudo (e ateh concordo nisso) e acessar os objetos somente pela interface (ou seja, nunca saber a implementacao que esta sendo usada no momento)…
mais que isso, os mais puristas vao ainda te falar para nao usar heranca, fazendo classes concretas por composicao e delegates (uma vez, perguntaram ao J.Gosling o que ele mudaria se fizesse o JAVA de novo, e ele disse que tiraria a heranca), mas acho um tanto quanto exagerado essa exigencia…
lembrando ainda que vc deve adaptar as regras a sua realidade (prazo, pessoal capacitado, etc)…

Fabricio_Cozer_Marti

onde vc viu isso ?

pcalcado

takeshi10:
os OO mais puristas vao fazer vc criar interfaces para tudo (e ateh concordo nisso)

mais que isso, os mais puristas vao ainda te falar para nao usar heranca, fazendo classes concretas por composicao e delegates (uma vez, perguntaram ao J.Gosling o que ele mudaria se fizesse o JAVA de novo, e ele disse que tiraria a heranca), mas acho um tanto quanto exagerado essa exigencia…

De quais ‘puristas’ você está falando?

Interfaces têm uso, acesso direto à classe concreta também. Geralmente o que se é recomendado é que se trabalhe com interfaces quando se lida com especificações.

T

achei nos meus links:
http://www.javaworld.com/javaone01/j1-01-gosling_p.html

T

procure nos livros como o ‘Effective JAVA’ e ali vc vai encontrar puristas…
tambem acho que, algumas vezes, eh interessante ter acesso as classes concretas, mas mais por simplicidade e facilidade…

louds

Eu acho que desenvolver usando interfaces muito mais facil que o contrario, ainda mais se usarmos mocks e stubs para os vários tipos de testes do sistema.

pcalcado

takeshi10:
achei nos meus links:
http://www.javaworld.com/javaone01/j1-01-gosling_p.html

takeshi10:
procure nos livros como o ‘Effective JAVA’ e ali vc vai encontrar puristas…
tambem acho que, algumas vezes, eh interessante ter acesso as classes concretas, mas mais por simplicidade e facilidade…

Nem o Gosling no seu link nem o Effective java falam em:

takeshi10:
os OO mais puristas vao fazer vc criar interfaces para tudo (e ateh concordo nisso) e acessar os objetos somente pela interface (ou seja, nunca saber a implementacao que esta sendo usada no momento)…

E o dia que James Gosling for purista de OO é sinal de que o mundo está acabando :wink:

Como falei existem casos para interfaces e existem casos para implementações.

T

fala philip…
vc misturou meus dois posts… o primeiro era a entrevista do Gosling q eu tinha dito no post anterior…

agora quanto a acessar somente pela interface, repare q essa eh a maneira pela qual normalmente acessamos as coisas um pouco mais complexas (como as collections)…
eu tinha lido em algum livro (e acho qera no effective java) q, idealmente, deveriamos acessar td somente pela interface, mas no sentido amplo da palavra (e nao somente a interface de java)…
meu livro esta emprestado, mas assim que me devolverem, eu olho melhor para nao falar besteira…

T

soh para constar, tah no item 34 do livro:
“Refer to objects by their interfaces”

pcalcado

takeshi10:
soh para constar, tah no item 34 do livro:
“Refer to objects by their interfaces”

Acho que você precisa reler este item.

Colando do resumo da Bani:

Está muito bem resumido mas vou colar alguns trechos do livro também:

O que eu quis dizer com isso: Joshua Bloch não diz que você deve usar interfaces apra todos os objetos, dia que trabalhar com interfaces torna seu programa flexível e deve ser feito sempre que fizer sentido.

Existem objetos, como ele cita no livro, que são criados para terem múltiplas implementações. Outras vezes nós lidamos com conceitos que são implementados, não com classes. Nestes dois casos interfaces são ideais.

Fabricio_Cozer_Marti

Phiilp, e vc viria alguma situação em que interfaces não ajudaria ?

T

ola philip,
por essa passagem, eu entendo que o ideal eh se criar e se utilizar interfaces sempre que possivel, evitando nos casos citados, mas talvez a minha interpretacao esteja equivocada…
porem, leia o trecho:

para mim, me parece que ele sugere a utilizacao de interfaces sempre (embora nao diga explicitamente que se deva criar interfaces, jah que ele fala sobre classes preexistentes)…

saoj

Eu já programei usando interfaces para os meus beans.

Eu tinha uma interface Profile e eu fazia algo assim:

public interface Profile extends Persistent {


}

public class DBProfile extends DBBean implements Profile {


}

// carrega um profile do banco:

Profile p = ProfileFactory.getDBProfile();
p.setId(2);
p.load();

Sei lá. Hoje estou achando isso mó loucura. Trabalhoso e chato tb. Eu só parti pra esse lado pois eu tinha meu próprio mecanismo de persistencia para meus beans. Se depois eu mudasse o mecanismo de persistencia, eu não precisaria mexer no código que utilizava meus profiles. Poderia até ter um Profile vindo do banco, outro vindo de um arquivo, etc misturados que não haveria problema. Tudo seria a interface Profile.

Mais sei lá. Acho isso overkill hoje em dia. Melhor usar o bom e velho DAO mesmo com IoC. E fazer os beans concretos mesmo. O que se ganharia fazendo eles como Interface ? Vc dobraria o número de suas classes e ainda teria mais trabalho de manutenção e organização. Teria que criar factories, tb. Não sei se o custo-benefício vale a pena aqui.

pcalcado

O que ele diz (e não quer dizer que esteja absolutamente certo mas Joshua Bloch é uma referência cheia de crdibilidade) é que você deve utilizar interfaces quando disponíveis (e eu acrescento: quando fizerem sentido!). O exemplo dado é bem claro: em vez de usar ArrayList, use List mas para String use String mesmo.

Esse é exatamente o tipo de caso em que não se usa itnerfaces. Objetos de negócio só devem ser manipulados unicamente por interfaces se:

  • Possuem diversas implementações
  • Você está manipulando um conceito, não uma implementação. Ok, vamos a um exemplo simples sobre esse ponto.

(notem que sou ignorante em contabilidade, é apenas um exemplo ilustrativo)

Temos o conceito de MovimentacaoFinanceira no nosso sistema. O que é isso? É uma quantidade de capital que entrou ou saiu da empresa, algo que tem um valor total, uma data, se é entrada ou saída e está relacionado a uma pessoa (emrpesa ou pessoa mesmo). Isso é um conceito abstrato e vamos implementá-lo por uma interface:

interface MovimentacaoFinanceira {
 
 BigDecimal getValorTotal();
 Pessoa getPessoaRelacionada();
 Date getData();
 TipoMovimentação getTipo();
}

Na parte de vendas do sistema, temos a classe Venda que representa uma movimentação financeira. Neste caso é um capital entrando relacionado a um cliente.

class Venda implements MovimentacaoFinanceira {
 //METODOS ESPECIFICOS DESTA CLASSE...

 public BigDecimal getValorTotal(){
    //some o preço de todos os itens vendidos e retorne
 }
 
 public Pessoa getPessoaRelacionada(){ return this.getCliente(); }

 public Date getData(){return this.data;}

 public TipoMovimentação getTipo(){return TipoMovimentação.ENTRADA;}
}

Agora, quando usamos a classe e quando usamos a interface?

Se você está alterando o sistema de vendas, você não tem tanto interesse no conceito de movimentação financeira. Use a classe.

Se você está fazendo o sistema que contabiliza as operações e cospe um relatório contábil, para consolidar tudo você não quer saber se é uma venda, uma devolução, pagamento da conta de luz ou se é despesa de viagem do programador que você mandou para o RioJavaSummit 2006, dia 6 de Maio, no Rio de Janeiro. O que te interessa é que no fim das contas todas estas operações são movimentações financeiras, então você trabalha com a interface.

E porque MovimentaçaoFinanceira é uma interface e não uma classe abstrata?

Porque ela representa um conceito apenas, não uma implementação. A linha entre ambas é sutil e não é toda linguagem que oferece interfaces e classes (em java eu creio que a existência de interfaces como coisas separadas só se deu porque não existe herança múltipla).

Utilize classes abstratas quando você tem uma implementação parcial de um conceito que deve ser extendida. Utilize interfaces quando você tem apenas uma especificação do conceito.

T

ok talvez eu tenha entendido mal o livro (e sim, ele nao pode ser considerado a verdade absoluta, mas eh um otimo livro de qualquer maneira)…
mas ainda sim, a meu ver, quando ele fala que devemos usar a interface relevante sempre que possivel, quando estamos em fase de desenvolvimento, isso significa sempre (jah que sempre podemos desenvolver as interfaces, certo?)…

concordo em parte com vc, sergio, e o uso citado por vc pode parecer um overkill, mas acho q a flexibilidade oferecida (nesse caso) compensa, mas isso eh apenas a minha humilde opiniao…

Rubem_Azenha

Não podemos ser dogmaticos demais.
Conclusão: use Interfaces quando for algum serviço (persistência, por exemplo) e Classes Concretas quando for lógica de negócio. Afinal o mais importante e o que menos deveria mudar é a lógica de negócio.

pcalcado

microfilo:
Não podemos ser dogmaticos demais.
Conclusão: use Interfaces quando for algum serviço (persistência, por exemplo) e Classes Concretas quando for lógica de negócio. Afinal o mais importante e o que menos deveria mudar é a lógica de negócio.

Meio irreal isso.

Lógica de negócio é algo que mais muda num sistema grande (inclusive devo apresentar algo sobre isso em breve). O cliente muda fluxos, faz promoções loucas, compra outras empresas, disponibilizam outros serviços, altera forma de pagamento, pede para tal coisa ser feita de jeito diferente…

Em três anos cuidando basicamente de ‘produtos’ eu nunca vi nada mudar tanto. Projetos mudam, mudam, dae você entrega e geralmente alguém fica com a manutenção. Produtos fazem projetos constantemente para alterar tudo.

Flexibilidade para regras de negócio é muito importante.

Fabricio_Cozer_Marti

E falando um pouco de aplicações orientadas a serviços ? Por exemplo, teríamos interfaces que seriam como uma linha fina entre as especificações dinâmicas e a implementação específica, assim facilmente o sistema seria manipulado pelas assinaturas e comportamentos na interface, representando neste caso os serviços que deverão ser providos a um determinado domínio de negócio da aplicação.

Sim, regras de negócios na sua ideal existência deveria ser plugável e configurável, estamos entrando hoje numa fase em que a tendência modular prevalece na luta pela sobrevivência agressiva no mercado, e para isso, uma forma estratégica seria em pouco tempo você mudar a forma como seu sistema vai agir, sem mudar o comportamento principal,a ‘engine’ do sistema deve permancer quase imutável, isso hoje é muito bem factível utilizando interfaces na modelagem de classes, porém para isso é necessário que a pessoa tenha um certo pensamento abstrato do negócio, e que infelizmente é difícil encontrar.

Paulo_Silveira

pcalcado:
O que ele diz (e não quer dizer que esteja absolutamente certo mas Joshua Bloch é uma referência cheia de crdibilidade) é que você deve utilizar interfaces quando disponíveis (e eu acrescento: quando fizerem sentido!). O exemplo dado é bem claro: em vez de usar ArrayList, use List mas para String use String mesmo.

Muita gente, e a api do java desde o 1.4, costuma referir String por CharSequence, sempre preferindo a interface, aceitando assim StringBuffer/Builder, e se precisar de String basta um toString.

Eu leio mais como o takeshi: use interface sempre que possivel, mesmo que nesse momento nao faca sentido. Mas se ela tem interface, e da para usa-la, mesmo sem parecer util no momento, use.

Um dos refactorings do eclipse é “substituir pelo uso de interface whenever possible” ou algo assim.

Mas tambem sou contra criar uma interface para qualquer classe.

pcalcado

Paulo Silveira:
Muita gente, e a api do java desde o 1.4, costuma referir String por CharSequence, sempre preferindo a interface, aceitando assim StringBuffer/Builder, e se precisar de String basta um toString.

Eu nunca vi um código que não fosse um framework (como Rife) ou algo do tipo utilizar CharSequence mas não duvido que exista.

Paulo Silveira:

Eu leio mais como o takeshi: use interface sempre que possivel, mesmo que nesse momento nao faca sentido. Mas se ela tem interface, e da para usa-la, mesmo sem parecer util no momento, use

Mas tambem sou contra criar uma interface para qualquer classe.

:wink:

PadrE

Esse assunto pode ir longe hein !

Mas vou por minha opinião…

Pra mim, o uso de Interface serve para que se possa ter um certo pardrão entre os objetos de sua aplicação… no qual facilita futuras alterações…

Em uma interface vc especifica os métodos que seus “filhos” deverão implementar…

Uma coisa legal nisso, eh que vc pode implementar os métodos de formas diferentes para cada objeto e tb pode adicionar novos atributos…
(nada de novidade neh?)

Agora… a maneira de como se utilizar esse monte de classes fica TOTALMENTE a sua escolha…

Não eh um manual ou um artigo que irá te falar qual a melhor opção ou qual a melhor forma de se modelar um sistema…

Acho estranho ficarmos nos bazeando nos que certas pessoas falam… quel disse que eles estão certos ? quem disse que essa eh a melhor maneira ??? quem pode provar que eh melhor utilizar uma herança, uma composição ou uma agregação ??

O cara que criou a linguagem ?? Os analistas mais falados do mundo ??

Bah! Se nos formos ver os padrões de modelagem especificados em vários lugares… são tantos padrões que fica dificil escolher um…

Camdas então… ! Nossa… vc pode fazer uma modelagem em tantas camadas que acabam deixando o desenvolvedor doido… ^^

Os conceitos de O.O n são regras… são sugestões que vc pode utilizar… cabe a vc utiliza-las, e cabe a vc fazer com que funcionem…

Quebra de encapsulamento ?? Se isso ocorre, não eh porque a idéia esta errada, mas sim porque n foi bem aplicada… Se uma Interface oferece quebra ou não… isso eh vc q define… vc que deve controlar…

Como controlar isso ??? Vc escolhe, n será um padrão ipipoca que vai te mostrar isso… n existe uma maneira correta de se utilizar encapsulamento… existem várias… qual a melhor ?? qual funciona de verdade ??
Qual segue as regras ?? Regras ?? Quem disse que existem regras ??

Kraca… n qnto mais digitar !

Fui !

pcalcado

Não entendi seu ponto. O que você quer dizer com isso?

Por isso que:

Mas mesmo assim, desprezar referências como Joshua Bloch é, na muito melhor das hipóteses, reiventar a roda e, na maioria das vezes, aplicar péssimas práticas.

Lendo os diversos pontos de vista e diversos trabalhos de autores clássicos ou não você ganha conhecimento apra tomar suas decisões. São anos e anos de experiência que você não vai viver o suficiente para conseguir por si só compilados em livros e artigos. Nem Bertrand meyer que é talvez o maior ícone atual de OOP (e o mais arrogante) diz que o que ele aplica são regras (pelo menos não abertamente).

J

Galera e qual a forma de se escrever corretamente um Interface?

Exemplo:

  • Tenho a classe Carro
  • e as interfaces IMecanico e IUsuario

como nomeio elas?

rodrigo_ctba

Bom dia Srs.

Estou com uma dúvida. É o seguinte, tenho um classe Pessoa e nela tenho alguns objetos pertinentes a pessoa encapsulados. Bom tem “outros” que eventualmente iram acontecer, tais como o objeto Estrangeiro e Reservista.

Estava pensando em criar uma forma de realizar um encapsulamento sobre demanda, utilizando métodos dentro da Pessoal, que ao serem chamados instanciariam o objeto Reservista por exemplo. Mas para eu criar isso teria que passar alguma coisa para o objeto Reservista, pois não tenho como saber se tal objeto, Reservista, pertence ao objeto Pessoa…

Estou viajando, ou tem outra forma mais prática pra fazer isso !!!

Valeu …

Criado 2 de abril de 2006
Ultima resposta 11 de mai. de 2007
Respostas 27
Participantes 11