Encapsulamento vs Persistência

Pessoal,

Apesar desta ser minha primeira mensagem, já acompanho o fórum a uns 6 meses.

Gostaria de tirar uma dúvida e ao mesmo saber se meu raciocínio está correto.

Um dos grandes pilares da Orientação a Objetos é o Encapsulamento.

Mas como encapsular todos os atributos de uma classe se temos que persisti-la? (acho que agora não tem acento)

Não importa se utilizamos um DAO ou um Repository e etc.

Como garantir que apenas este tipo de classe tenha acesso a informação que não quero que seja exposta para o resto do sistema?

Não sei se entendi, mas vamos lá.

Me parece que o ORM acessa os atributos do objeto mesmo estando encapsulados, caso não queira este comportamento basta configurar para ele utilizar os set e get ao fazer o acesso.

flws

E bem vindo ao GUJ.

Olá

Entendo o que você quer dizer. Isso acontece porque geralmente o pessoal costuma “empacotar” as classes por camada, onde no final a classe Usuario e a classe UsuarioDAO ficam em pacotes diferentes.

Se você seguir a boa prática de empacotar por funcionalidade, não por camada, Usuario e UsuarioDAO ficarão no mesmo pacote e você pode dar visibilidade default aos setters que não são públicos. Pra quem tá acostumado a empacotar por camada é um pouco difícil se acostumar, mas no final compensa.

Outra sugestão é usar Hibernate. Com ele, você não precisa expor seus atributos para cuidar da persistência deles.

Obrigado.

[quote=fantomas]Não sei se entendi, mas vamos lá.

Me parece que o ORM acessa os atributos do objeto mesmo estando encapsulados, caso não queira este comportamento basta configurar para ele utilizar os set e get ao fazer o acesso.

flws

[/quote]

É verdade, o Hibernate (no meu caso nHibernate) faz isso. Mas e se eu não usar nenhum ORM? Tenho um sistema que não posso usar nenhum framework, por isso é que esta dúvida surgiu.

Leia minha mensagem anterior. Abraços

Então…

O tnaires indicou uma saida interessante, mas ainda existe uma outra idéia que pode ser combinada e pode até sanar sua dúvida ela só não é bonita, vamos lá:

Estando em camadas ou não e se a idéia geral for não permitir o acesso direto ao modelo você poderia utilizar DTOs com ASSEMBLERs (algumas pessoas não gostam da idéia). Em uma atividade que envolve alterações a camada mais “externa” ajusta o DTO e envia para as camadas mais “internas” chagando lá vc aplica as regras, se os dados do DTO estiverem seguros você aplica os ajustes no modelo; dessa forma vc consegue encapsular o modelo evitando o contato direto. Uma alternativa ao DTO seria aplicar o pattern ADAPTER.

flws

Desculpe pelo sumiço.

Gostei das sugestões. Tenho certeza que vou gostar de participar deste fórum.

[quote=aplnas]Pessoal,

Apesar desta ser minha primeira mensagem, já acompanho o fórum a uns 6 meses.

Gostaria de tirar uma dúvida e ao mesmo saber se meu raciocínio está correto.

Um dos grandes pilares da Orientação a Objetos é o Encapsulamento.

Mas como encapsular todos os atributos de uma classe se temos que persisti-la? (acho que agora não tem acento)

Não importa se utilizamos um DAO ou um Repository e etc.

Como garantir que apenas este tipo de classe tenha acesso a informação que não quero que seja exposta para o resto do sistema?
[/quote]

Simples, use o padrão Memento.

Básicamente a sua classe persistivel tem uma classe irma ( o memento) no mesmo pacote.
O memento tem acesso ao interior do objeto porque está no mesmo pacote. Ele então copia/escreve esse estado quando necessário.

O seu sistema de persistencia persiste mementos. Eles podem implementar algum tipo de interface genérica para que o sistema de persistencia os entenda ( algo como Persistable get/setValue(String nomeDoCampo))

Claro que vc pode fazer o sistema de persistencia criar o memento dinamicamente via reflection. Assim, ele apenas têm que consulta o objeto original usando get/set padrão do objeto e copiar para o memento dinamico. Em ultimissimo caso pode usar leitura directa dos atributos, mas cuidado que isso viola o encapsulamento ( que é o que vc não quer fazer. E está certo em não querer)

O Hibernate utiliza o padrão memento dinamico através da criação de um proxy do objeto original ( o memento é o proxy da classe que é uma copia do objeto original).

Esta é uma dúvida bem pertinente.

O problema aqui é que para alguns cenários -como persistência ou interface com usuário- precisamos expôr a estrutura interna (geralmente os dados) de um objeto. Em termos de Orientação a Objetos não existe muita resposta para sua dúvida, o paradigma não prevê estes casos simples. As duas soluções mais utilizadas são ou expôr estes dados de alguma forma (e.g. getters) ou “ensinar” um sistema como o Hibernate como serializar o estado da sua classe (dizendo onde e como pegar os dados via configuração). O padrão memento citado neste tópico é uma solução que eu recomendo apenas como medida drástica, porque geralmente utilizar um ORM é o melhor caminho.