Modelagem de Classes. Palpites?

21 views
Skip to first unread message

tucaz

unread,
Feb 3, 2010, 3:17:02 PM2/3/10
to .Net Architects
Seguinte,

tenho a seguintes tabelas

[User]
Id
Name

[Role]
Id
Name

[UserRole]
UserId
RoleId
IsActive

Como traduzir isso pra um modelo bacana de classes? A idéia de criar
uma classe pra resolver essa dependência não me agrada muito. Idéias?

Att.,
Tuca

Sergio Azevedo

unread,
Feb 3, 2010, 3:20:44 PM2/3/10
to dotnetar...@googlegroups.com
Oi Tuca,

  Acredito que o melhor seria vc ter classes apenas para os seus objetos de dominio, ou seja User e Role.
  A tabela UserRole existe por que o bancos relacionais soh conseguem resolver relacionamentos muitos para muitos deste jeito.

  Segue um link de um post interessante sobre este assunto. O post diz que nosso modelo de classes nao dever ser um cópia do nosso modelo de objetos. 


Grande Abraço,

--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com
Para mais opções visite o grupo em http://groups.google.com/group/dotnetarchitects?hl=pt-br

tucaz

unread,
Feb 3, 2010, 3:23:28 PM2/3/10
to .Net Architects
Sergio,

acho que você deixou passar a property IsActive. Esse é meu
problema. :)

On Feb 3, 2:20 pm, Sergio Azevedo <sergior...@gmail.com> wrote:
> Oi Tuca,
>
>   Acredito que o melhor seria vc ter classes apenas para os seus objetos de
> dominio, ou seja User e Role.
>   A tabela UserRole existe por que o bancos relacionais soh conseguem
> resolver relacionamentos muitos para muitos deste jeito.
>
>   Segue um link de um post interessante sobre este assunto. O post diz que
> nosso modelo de classes nao dever ser um cópia do nosso modelo de objetos.
>

> http://www.sagadoprogramador.com.br/2009/07/nosso-modelo-de-objetos-n...
>
> Grande Abraço,
>
> Sergio Juniorhttp://www.sagadoprogramador.com.br/
>
> 2010/2/3 tucaz <tuca...@gmail.com>


>
> > Seguinte,
>
> > tenho a seguintes tabelas
>
> > [User]
> > Id
> > Name
>
> > [Role]
> > Id
> > Name
>
> > [UserRole]
> > UserId
> > RoleId
> > IsActive
>
> > Como traduzir isso pra um modelo bacana de classes? A idéia de criar
> > uma classe pra resolver essa dependência não me agrada muito. Idéias?
>
> > Att.,
> > Tuca
>
> > --
> > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > hospedado no Google Groups.
> > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > Para sair do grupo envie uma mensagem para

> > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>

Marcus Alexandre Silva

unread,
Feb 3, 2010, 3:25:27 PM2/3/10
to dotnetar...@googlegroups.com
IsActive não deveria ser propriedade de User?
--
Marcus Alexandre

http://twitter.com/marcusbetim
PrimeSystems - Inteligencia em Mobilidade
Talk/Msn/Mail: inf.marcu...@gmail.com
blog: http://sourcerule.wordpress.com/
ultimo post: Clean Code Tips for C# – Nomes devem descrever objetivos

tucaz

unread,
Feb 3, 2010, 3:30:29 PM2/3/10
to .Net Architects
Não. Representa se aquela Role está ativa para aquele Usuário.

On Feb 3, 2:25 pm, Marcus Alexandre Silva


<inf.marcusalexan...@gmail.com> wrote:
> IsActive não deveria ser propriedade de User?
>

> > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>


>
> > > > Para mais opções visite o grupo em
> > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> > --
> > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > hospedado no Google Groups.
> > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > Para sair do grupo envie uma mensagem para
> > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>
> > Para mais opções visite o grupo em
> >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> --

> Marcus Alexandre
>
> http://twitter.com/marcusbetim
> PrimeSystems - Inteligencia em Mobilidade

> Talk/Msn/Mail: inf.marcusalexan...@gmail.com

Vinicius Quaiato

unread,
Feb 3, 2010, 3:31:41 PM2/3/10
to dotnetar...@googlegroups.com
Se a Role não está ativa para o usuário, ele deveria estar nela? É como estar numa role e não estar... é isso?

2010/2/3 tucaz <tuc...@gmail.com>

tucaz

unread,
Feb 3, 2010, 3:33:34 PM2/3/10
to .Net Architects
Esse não é meu caso real, mas uma maneira de simplificá-lo. Além de
IsActive tenho algumas outras properties que pertencem a relacao entre
duas classes, ou seja, definem como a relação entre as duas vai
funcionar.

Imagine que vc tem a Role admin, mas pq foi um mau menino vou
desabilita-la por um dia ao inves de remove-la, pois pra remover eu
preciso de aprovação do meu chefe.

Att.,
Tuca

On Feb 3, 2:31 pm, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:


> Se a Role não está ativa para o usuário, ele deveria estar nela? É como
> estar numa role e não estar... é isso?
>

> 2010/2/3 tucaz <tuca...@gmail.com>

> > > > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>
> > <dotnetarchitects%252Buns...@googlegroups.com<dotnetarchitects%25252Bun...@googlegroups.com>


>
> > > > > > Para mais opções visite o grupo em
> > > > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> > > > --
> > > > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > > > hospedado no Google Groups.
> > > > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > > > Para sair do grupo envie uma mensagem para
> > > > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>
> > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>
>
> > > > Para mais opções visite o grupo em
> > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> > > --

> > > Marcus Alexandre
>
> > >http://twitter.com/marcusbetim
> > > PrimeSystems - Inteligencia em Mobilidade
> > > Talk/Msn/Mail: inf.marcusalexan...@gmail.com
> > > blog:http://sourcerule.wordpress.com/
> > > ultimo post: Clean Code Tips for C# – Nomes devem descrever objetivos
>
> > --
> > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > hospedado no Google Groups.
> > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > Para sair do grupo envie uma mensagem para

Alexandre Monteiro

unread,
Feb 3, 2010, 3:27:51 PM2/3/10
to dotnetar...@googlegroups.com
Tuca,

Não entendi o que significa o IsActive.

O que é ativo? O papel que usuário possui?
Num relacionamento N-N você simplesmente exclui a linha que faz essa atribuição.
Se o usuário está ativo, este atributo deve estar na entidade usuário.

[]s

Alexandre

Alexandre Monteiro

unread,
Feb 3, 2010, 3:45:01 PM2/3/10
to dotnetar...@googlegroups.com
Quanto mais regra de negócio precisar colocar no seu modelo de dados, mais complicado ele será. Se você precisa colocar um prazo de validade de uma permissão, é interessante manter um histórico de que no dia tal, o usuário tal, foi mal menino (o motivo) e teve a sua permissão revogada. Eu criaria uma outra tabela para isso.

Você pretende colocar a permissão de  exclusão no banco de dados ou na camada de negócio? Se for na camada de negócio, pode excluir de um cache

Alexandre Monteiro

unread,
Feb 3, 2010, 3:48:43 PM2/3/10
to dotnetar...@googlegroups.com
Desculpe, não terminei:

Você pretende colocar a permissão de  exclusão no banco de dados ou na camada de negócio? Se for na camada de negócio, pode excluir de um cache singleton thread-safe (double-checked locking) que faria a interface com a aplicação em vez do repositório, mas sempre pensaria em log dos motivos do mal comportamento que revocou a permissão.

tucaz

unread,
Feb 3, 2010, 5:01:02 PM2/3/10
to .Net Architects
Este cenário da revogação temporária é um exemplo. Preciso representar
no meu modelo propriedades que existem apenas quando existe a relação.
Imagine que além do IsActive eu tenha uma coluna com o Id
(AuthorizedBy) de quem autorizou que o usuário tivesse essa Role.

Enfim, o que preciso é de algo como uma classe que represente a tabela
N pra N porque tenho propriedades que são válidas neste contexto, mas
que não seja uma classe N pra N.

On Feb 3, 2:48 pm, Alexandre Monteiro <monteiro...@gmail.com> wrote:
> Desculpe, não terminei:
>
> Você pretende colocar a permissão de  exclusão no banco de dados ou na
> camada de negócio? Se for na camada de negócio, pode excluir de um cache
> singleton thread-safe (double-checked locking) que faria a interface com a
> aplicação em vez do repositório, mas sempre pensaria em log dos motivos do
> mal comportamento que revocou a permissão.
>
> Em 3 de fevereiro de 2010 18:45, Alexandre Monteiro

> <monteiro...@gmail.com>escreveu:


>
> > Quanto mais regra de negócio precisar colocar no seu modelo de dados, mais
> > complicado ele será. Se você precisa colocar um prazo de validade de uma
> > permissão, é interessante manter um histórico de que no dia tal, o usuário
> > tal, foi mal menino (o motivo) e teve a sua permissão revogada. Eu criaria
> > uma outra tabela para isso.
>
> > Você pretende colocar a permissão de  exclusão no banco de dados ou na
> > camada de negócio? Se for na camada de negócio, pode excluir de um cache
>

> >> > > > > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>
> >> <dotnetarchitects%252Buns...@googlegroups.com<dotnetarchitects%25252Bun...@googlegroups.com>
>
> >> > > <dotnetarchitects%252Buns...@googlegroups.com<dotnetarchitects%25252Bun...@googlegroups.com>
> >> <dotnetarchitects%25252Bun...@googlegroups.com<dotnetarchitects%2525252Bu...@googlegroups.com>


>
> >> > > > > > > Para mais opções visite o grupo em
> >> > > > > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> >> > > > > --
> >> > > > > Você recebeu esta mensagem porque faz parte do grupo .Net
> >> Architects
> >> > > > > hospedado no Google Groups.
> >> > > > > Para postar envie uma mensagem para
> >> dotnetar...@googlegroups.com
> >> > > > > Para sair do grupo envie uma mensagem para
> >> > > > > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>
> >> <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>
>
> >> > > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>
> >> <dotnetarchitects%252Buns...@googlegroups.com<dotnetarchitects%25252Bun...@googlegroups.com>
>
> >> > > > > Para mais opções visite o grupo em
> >> > > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> >> > > > --

Sergio Azevedo

unread,
Feb 3, 2010, 5:17:44 PM2/3/10
to dotnetar...@googlegroups.com
Entendi Tuca. Desculpe por nao ter visto.

  Eu colocaria isActive na classe Role. Sei que isso implicaria em um pouco mais de trabalho, pois o ORM sozinho nao vai fazer isso sem vc ter uma classe que represente a associação.
  Mas com isActive em Role vc ganharia expressividade no seu modelo. Eu compraria esse barulho, e incluiria em meu projetos a classe (ou as classes) necessária(s) para a montagem do objeto Role.

Abraços.

Sergio Junior
http://www.sagadoprogramador.com.br/


2010/2/3 tucaz <tuc...@gmail.com>
Sergio,

tucaz

unread,
Feb 3, 2010, 5:24:04 PM2/3/10
to .Net Architects
Sergio,

IsActive só existe quando um usuário se relaciona com uma Role. Essa
prop não existe com uma Role sozinha. Any more ideas?

On Feb 3, 4:17 pm, Sergio Azevedo <sergior...@gmail.com> wrote:
> Entendi Tuca. Desculpe por nao ter visto.
>
>   Eu colocaria isActive na classe Role. Sei que isso implicaria em um pouco
> mais de trabalho, pois o ORM sozinho nao vai fazer isso sem vc ter uma
> classe que represente a associação.
>   Mas com isActive em Role vc ganharia expressividade no seu modelo. Eu
> compraria esse barulho, e incluiria em meu projetos a classe (ou as classes)
> necessária(s) para a montagem do objeto Role.
>
> Abraços.
>

> > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>

João Carlos Clementoni Silva

unread,
Feb 3, 2010, 5:31:31 PM2/3/10
to dotnetar...@googlegroups.com
Sergio Junior: " Eu colocaria isActive na classe Role"

Pelo que entendi o IsActive é do Role do User e não do Role.

Eduardo Miranda

unread,
Feb 3, 2010, 5:45:28 PM2/3/10
to dotnetar...@googlegroups.com
Curioso que ninguém discutiu o relacionamento entre as duas classes. Além de impactar na questão do IsActive, também traz alguns impactos na solução final.

Vinicius Quaiato

unread,
Feb 3, 2010, 6:07:21 PM2/3/10
to dotnetar...@googlegroups.com
Fazendo uma análise superficial eu tentaria trabalhar com uma entidade RoleDeUsuario. E esta sim conteria as propriedades da relação. Não sei se há muito como fugir disso.

Att,
Vinicius Quaiato.

2010/2/3 Eduardo Miranda <dud...@gmail.com>

Juan Pedro A. Lopes

unread,
Feb 3, 2010, 6:25:59 PM2/3/10
to dotnetar...@googlegroups.com
Apenas um devaneio. Será que não existe uma forma de criar uma UserRole que herde de Role, em vez de agregá-la?

2010/2/3 Vinicius Quaiato <vinicius...@gmail.com>

Thiago Alves

unread,
Feb 3, 2010, 7:04:01 PM2/3/10
to dotnetar...@googlegroups.com
Pois é... essa é uma limitação do modelo Orientado a Objetos. Não existem relacionamentos  (associações) de classes com atributos.

Não sou adepto da solução de representar um relacionamento n x n simples (sem atributos) sem representar a tabela de relacionamento como uma entidade, como sugeriu o colega Sérgio.

O motivo é muito simples: se um relacionamento n x n simples é um caso particular de um relacionamento n x n com atributos, porque eu deveria me preocupar em ter duas implementações diferentes?

E se eu percebo no meio do projeto que meu relacionamento n x n tem um atributo que eu esqueci de colocar no modelo de dados? Vou ter que mudar a forma como represento isso no modelo de objetos? E se eu já tiver escrevido código baseado neste modelo e depois eu perceber que preciso criar uma nova classe só para representar o(s) atributo(s) novos?

Esse é um exemplo de quando digo que nem sempre o que é dito por aí como sendo "correto" deve ser aplicado cegamente nos projetos. A teoria serve como uma boa base inicial... mas a partir do momento que o arquiteto já conhece bem a teoria ele pode se dar ao luxo de discordar dela e fazer de um jeito diferente na prática.

Abraço,
Thiago Alves

2010/2/3 Vinicius Quaiato <vinicius...@gmail.com>

Sidney Lima Filho

unread,
Feb 3, 2010, 7:39:03 PM2/3/10
to dotnetar...@googlegroups.com
Tucaz, fazendo uma analise reversa do N x N, sabemos que toda situação que exige um relacionamento N x N deriva de duas necessidades 1 x N e N x 1  logo, porque não cria-se uma classe RoleSpecial que herda de Role para representar as UserRoles que o usuário tem.
 
Então essa RoleSpecial (não gostei do nome, mas foi o que veio antes de dormir) teria apenas o relacionamento com o User, como herda de Role tem acesso ao que a Role é, podendo ter os atributos inerentes a ela.
 
 
User -----o UserRoles o------- Role
 
                    Role
                       Î
User -----o RoleSpecial               
 
Isso é apenas uma ideia.

Sidney Lima Filho  ---------------------------------------------------------------------
Vivina Softhouse
(0xx21) 7867-2321
55*10*68934
http://www.vivina.com.br
http://twitter.com/sidneyfilho


2010/2/3 Thiago Alves <thiag...@gmail.com>

Luiz Augusto Moreira Costa

unread,
Feb 3, 2010, 7:54:01 PM2/3/10
to dotnetar...@googlegroups.com
Oi Tucaz,

Acho que falta um conceito para ser representado no seu domínio. A relação de Usuário e Role por si só não demandam a criação de uma nova classe, mas no seu modelo de dados, existe um atributo que é fruto desta relação. Bem não vejo outra solução para isso a não ser representar esta relação através de uma classe. Mas o ponto chave disso em um modelo de domínio é: O que representa esse no novo conceito?
Segundo DDD, todos os conceitos do seu domínio, devem estar explícitos no seu código. Logo, se existe a necessidade de se ter o controle se uma role está ativa para um usuário, isso não é uma anomalia do seu modelo OO, é um problema de negócio que tem quer representado através de uma classe. Então eu representaria isso através de uma nova classe. Agora é uma questão de design saber se esta nova classe tem uma relação com Role e Usuário, ou se Usuário tem uma relação com esta classe.
Agora outra pergunta, qual seria o nome desta classe? Se vc está utilizando DDD ou algo que represente seu domínio, provavelmente vai encontrar um nome para representar o conceito.

Então minha sugestão é:

UsuarioEmUmaRole (Deve existir um nome melhor no seu domínio)
       - Usuario
       - Role
       + EstaAtivo

Usuario
   + GetRoles() : List<UsuarioEmUmaRole>
   

Até,
Luiz Costa

2010/2/3 tucaz <tuc...@gmail.com>

Denis Ferrari

unread,
Feb 3, 2010, 9:35:39 PM2/3/10
to dotnetar...@googlegroups.com
Pessoal,

Pra mim é muito claro que o cenário pede uma terceira classe:

Usuário 1 ------------- * Participacao * -------------- 1 Grupo

Se a classe InformaçõesDeVinculo possui dados adicionais ela faz parte do domínio, e não vejo pecado da classe existir.

Acho complicado para esse problema trabalhar com herânça, na minha visão não faz sentido.

Abraços!

Denis Ferrari
http://www.heroisdati.com/
http://twitter.com/denisferrari
http://meadiciona.com/denisferrari

"Faça pouco, faça sempre e faça direito"


2010/2/3 Luiz Augusto Moreira Costa <gutom...@gmail.com>

Phillip Calçado

unread,
Feb 4, 2010, 2:53:33 AM2/4/10
to dotnetar...@googlegroups.com
Oi,

2010/2/4 Thiago Alves <thiag...@gmail.com>:


> Pois é... essa é uma limitação do modelo Orientado a Objetos. Não existem
> relacionamentos  (associações) de classes com atributos.

Isso não é uma limitação de Orientação a Objetos, mas sim das
linguagens de programação. UML, por exemplo, é uma linguagem de
modelagem (não de programação) que suporta relacionamentos como
cidadãos de primeira classe.

Ignorando a pergunta mais importante do tema -que seria: por que
estamos começando a modelagem por tabelas e não por classes?- a
solução típica para o problema proposto é uma classe associativa que
conteria uma referência para User, uma para Role e o atributo
desejado. Claro que isto pode ser um canhão para matar moscas, outras
opções incluem utilizar um mapa com assinatura <Role, bool> ou fazer
User conter duas listas, uma de Roles e uma de Roles ativos.

Qual a melhor solução? Assumindo que todos concordemos que
Domain-Driven Design é algo importante, a melhor solução é a que fizer
mais sentido para o especialista no domínio.

[]s

--
Phillip Calçado
http://fragmental.tw
http://www.fragmental.com.br

Ricardo Rocha

unread,
Feb 4, 2010, 6:17:46 AM2/4/10
to dotnetar...@googlegroups.com
Tucaz,

IMHO, quando precisamos mais dados do que as duas chaves de outras tabelas, a tabela (classe) não é mais de relaciosamento. No teu caso há a necessidade de mais informações e isso é representado por uma nova classe.

Vc poderia fazer isso herdando de roles, adicionando as propriedades que precisa e relacionando com User ou simplesmente fazer o relacionamento e obter os dados via Joins. A diferença neste sentido vai ser na obtenção das informações. Se as informações da Role são importantes ao obter os dados desta terceira classe, vc pode fazer via herança, porém se elas não te interessam eu faria por relacionamento.

Não consigo ver alternativa para vc fugir desta terceira classe porque ela tem dados e não só relacionamento entre outras 2 classes.

[]'s


Ricardo José Alves da Rocha
Porto Alegre - RS


Denis Ferrari

unread,
Feb 4, 2010, 6:50:38 AM2/4/10
to dotnetar...@googlegroups.com
Pessoal,

Não é por que você pode fazer com herança que você deve fazer com herança. Está clara a necessidade de uma terceira classe, não é pecado representar o domínio como ele é.


Abraços!

Denis Ferrari
http://www.heroisdati.com/
http://twitter.com/denisferrari
http://meadiciona.com/denisferrari

"Faça pouco, faça sempre e faça direito"


2010/2/4 Ricardo Rocha <ricardor...@gmail.com>

Ricardo Rocha

unread,
Feb 4, 2010, 7:00:46 AM2/4/10
to dotnetar...@googlegroups.com
      No caso dele acho que usar herança é aplicável se ele PRECISA das informações da role TODA vez que acessar a UserRole ... se não precisar, é uma classe nova só com o relacionamento mesmo !!




Ricardo José Alves da Rocha
Porto Alegre - RS


Régis Soares

unread,
Feb 4, 2010, 7:17:14 AM2/4/10
to dotnetar...@googlegroups.com
Certamente resolveria esse problema da seguinte forma:
 
class User {
int id;
string name;
List<UserRole> roles;
}
class Role {
int id;
string name;
List<UserRole> users; // opcional
}
class UserRole {
User user;
Role role;
bool isActive;
}
 
O livro UML Distilled (Fowler) tem um ótimo exemplo de classe associativa.

2010/2/3 tucaz <tuc...@gmail.com>

Diego Caxito

unread,
Feb 4, 2010, 7:19:59 AM2/4/10
to dotnetar...@googlegroups.com
@tucaz também vou com o Vinicius Quaiato. 

Se fosse apenas uma relação entre classes pura e simples, bastaria User conter Roles ou o contrário.

Porém sua relação tem propriedades específicas para a relação, como o IsActive e outros apontados por você, assim deve existir a classe dessa relação UserRole com as propriedades mapeadas, já que essas dizem respeito à relação, não apenas ao User ou ao Role, mas aos dois.

2010/2/3 Vinicius Quaiato <vinicius...@gmail.com>



--
Diego Caxito

Denis Ferrari

unread,
Feb 4, 2010, 7:20:04 AM2/4/10
to dotnetar...@googlegroups.com
Oi,

Uma coisa é o Grupo, outra é a Associação ao Grupo. Uma associação não é um Grupo (Sei que o conceito de herança não se resume a "é um").

Diego Caxito

unread,
Feb 4, 2010, 7:21:02 AM2/4/10
to dotnetar...@googlegroups.com
Ilustrou :)

2010/2/4 Régis Soares <regis...@gmail.com>



--
Diego Caxito

tucaz

unread,
Feb 4, 2010, 2:50:19 PM2/4/10
to .Net Architects
Hmm...boas opiniões. Gostei :)

Respondendo ao que o Phillip perguntou, comecei pelo modelo de dados
porque invariavelmente é a maneira mais fácil de exemplificar meu
problema e porque ele está intimamente ligado ao banco de dados, visto
que a estrutura de dados já existe e não posso modifica-la.

A solução que eu buscava era um misto do que vocês todos falaram mais
a possibilidade de mapear com NHibernate.

Como vocês falaram, é legitima a existência dessa nova classe de
associação apesar de eu achar "feio". Mas eu acho feio porque não
tenho um nome pra ela e infelizmente, neste momento, não tenho contato
direto com um User/BA pra me ajudar a contextualiza-la e conceitua-la.

Herança, do ponto de vista de modelagem é interessante porque de fato
a propriedade IsActive só é necessária no momento em que eu fizesse
uma associação da Role com o User e apesar do propósito da herança não
ser esse, me atenderia muito bem. No entanto, eu acho herança um
negócio traiçoeiro e gosto do principio de usar composição ao invés de
herança.

Portanto, o que acabei implementando foi a classe associativa mesmo
composta pela Role e pelo User que acabei chamando de RoleAssignement.
Numa oportunidade futura vou conversar com um User/BA pra ver se ele
me ajuda a deixar isso mais interessante.

Também coloquei essa pergunta no StackOverflow e me responderam uma
coisa que achei interessante, apesar de não me atender, que não
sugeriram aqui: modelar isso como uma query de um repositorio ou coisa
parecida. O unico problema dessa abordagem é que não vai me oferecer a
persistência pro banco então o que estou pensando em fazer é mapear
minha classe associativa como uma propriedade private de User e expor
na API com métodos.

Att.,
Tuca

On Feb 4, 6:21 am, Diego Caxito <diegocax...@gmail.com> wrote:
> Ilustrou :)
>

> 2010/2/4 Régis Soares <regissoa...@gmail.com>


>
>
>
> > Certamente resolveria esse problema da seguinte forma:
>
> > class User {
> > int id;
> > string name;
> > List<UserRole> roles;
> > }
> > class Role {
> > int id;
> > string name;
> > List<UserRole> users; // opcional
> > }
> > class UserRole {
> > User user;
> > Role role;
> > bool isActive;
> > }
>
> > O livro UML Distilled (Fowler) tem um ótimo exemplo de classe associativa.
>

> > 2010/2/3 tucaz <tuca...@gmail.com>


>
> >> Seguinte,
>
> >> tenho a seguintes tabelas
>
> >> [User]
> >> Id
> >> Name
>
> >> [Role]
> >> Id
> >> Name
>
> >> [UserRole]
> >> UserId
> >> RoleId
> >> IsActive
>
> >> Como traduzir isso pra um modelo bacana de classes? A idéia de criar
> >> uma classe pra resolver essa dependência não me agrada muito. Idéias?
>
> >> Att.,
> >> Tuca
>
> >> --
> >> Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> >> hospedado no Google Groups.
> >> Para postar envie uma mensagem para dotnetar...@googlegroups.com
> >> Para sair do grupo envie uma mensagem para

> >> dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>


> >> Para mais opções visite o grupo em
> >>http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> >  --
> > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > hospedado no Google Groups.
> > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > Para sair do grupo envie uma mensagem para

> > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>

Frederico Albuquerque

unread,
Feb 4, 2010, 3:25:05 PM2/4/10
to dotnetar...@googlegroups.com
Tuca,

Na minha opinião, acredito que a solução do Regis Soares está simples e resolve o problema.
Dica: Verifique se vc não está complicando as coisas desnecessáriamente. YAGNI e KISS!

Porém, se estiverem explícitos os requisitos:

- Um usuário deve poder ser punido com a suspensão temporária de um de seus papéis ("role").

- O sistema deve manter registrado um log com a informação de qual usuário gerenciou (atribuiu, excluiu, aplicou suspensão, etc) os papéis de um outro usuário.

Nesse caso, eu não incluiria essas informações na relação entre User e Role e sim em outros lugares, que teriam como responsabilidades gerenciar suspensões de papéis e manter o log de gerenciamento sobre papéis, respectivamente.

Exemplo:

using System.Collections.Generic;
using System.Linq;
using System;

public class Role
{
}

public class User
{
    internal List<Role> Roles;
}

public class RoleSuspension
{
    // Registra quando e por quem foi criada a suspensão.
    public User CreatedBy;
    public DateTime CreationDate;

    public User SuspendedUser;
    public Role RevokedRole;
    public DateTime StartingAt;
    public DateTime EndingAt;
}

public class RolesManager
{
    private List<RoleSuspension> Suspensions;

    /// <summary>
    /// Verifica se um usuário possui um papel.
    /// Se o papel estiver suspenso, retornará falso.
    /// </summary>
    public bool IsUserInRole(User user, Role targetRole)
    {
        if (user.Roles.Exists(role => role.Equals(targetRole)))
        {
            if (Suspensions.Exists(susp => susp.RevokedRole.Equals(targetRole) &&
                                           susp.SuspendedUser.Equals(user) &&
                                           susp.StartingAt.CompareTo(DateTime.Now) > 0 &&
                                           susp.EndingAt.CompareTo(DateTime.Now) <= 0))
            {
                // O usuário possui o papel mas está suspenso.
                return false;
            }
            else
            {
                // O usuário possui o papel e não existe suspensão para ele.
                return true;
            }
        }
        // O usuário não possui o papel.
        return false;
    }
}

Hahahah! Acho que eu mesmo não iria aceitar essa minha sugestão, mas.... taí mais um ponto de vista.

Abraços a todos!
Fred

2010/2/4 tucaz <tuc...@gmail.com>

tucaz

unread,
Feb 4, 2010, 3:28:42 PM2/4/10
to .Net Architects
Fred,

não tem requisito de manter registro associado. Meu cenário real na
verdade nem é esse, mas é equivalente.

:)

Valeu, anyway.

On Feb 4, 2:25 pm, Frederico Albuquerque <frederico.zvei...@gmail.com>
wrote:

> 2010/2/4 tucaz <tuca...@gmail.com>

> > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>


>
> > > >> Para mais opções visite o grupo em
> > > >>http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> > > >  --
> > > > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > > > hospedado no Google Groups.
> > > > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > > > Para sair do grupo envie uma mensagem para
> > > > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsu...@googlegroups.com>

> > <dotnetarchitects%2Bunsu...@googlegroups.com<dotnetarchitects%252Buns...@googlegroups.com>


>
> > > > Para mais opções visite o grupo em
> > > >http://groups.google.com/group/dotnetarchitects?hl=pt-br
>
> > > --
> > > Diego Caxito
>
> > --
> > Você recebeu esta mensagem porque faz parte do grupo .Net Architects
> > hospedado no Google Groups.
> > Para postar envie uma mensagem para dotnetar...@googlegroups.com
> > Para sair do grupo envie uma mensagem para

Thiago Alves

unread,
Feb 4, 2010, 5:04:24 PM2/4/10
to dotnetar...@googlegroups.com
Olá Phillip,

Isso não é uma limitação de Orientação a Objetos, mas sim das
linguagens de programação. UML, por exemplo, é uma linguagem de
modelagem (não de programação) que suporta relacionamentos como
cidadãos de primeira classe.

Até onde eu sei, UML suporta relacionamentos como cidadãos de primeira classe, como você disse, mas não suporta atributos como relacionamentos (como o modelo E-R suporta).
Isso para mim é uma limitação.

Qual a melhor solução? Assumindo que todos concordemos que
Domain-Driven Design é algo importante, a melhor solução é a que fizer
mais sentido para o especialista no domínio.

Concordo com você. Porém durante a implementação do sistema prefiro modificar o meu design inicial para facilitar a implementação a simplesmente ser "purista" sem nenhum motivo específico.
Quando as bases de dados relacionais não forem mais usadas, e todo mundo usar bancos de dados O-O, isso não será mais um problema e boa parte desta discussão vai perder o sentido.

Abraço,
Thiago Alves


2010/2/4 Phillip Calçado <pcal...@gmail.com>

Thiago Alves

unread,
Feb 4, 2010, 5:11:49 PM2/4/10
to dotnetar...@googlegroups.com
Exatamente, Régis!

Eu resolveria da mesma forma

Abraço

2010/2/4 Régis Soares <regis...@gmail.com>

Phillip Calçado

unread,
Feb 4, 2010, 5:33:06 PM2/4/10
to dotnetar...@googlegroups.com
Oi,

2010/2/5 Thiago Alves <thiag...@gmail.com>:


>> Isso não é uma limitação de Orientação a Objetos, mas sim das
>> linguagens de programação. UML, por exemplo, é uma linguagem de
>> modelagem (não de programação) que suporta relacionamentos como
>> cidadãos de primeira classe.
>
> Até onde eu sei, UML suporta relacionamentos como cidadãos de primeira
> classe, como você disse, mas não suporta atributos como relacionamentos
> (como o modelo E-R suporta).
> Isso para mim é uma limitação.

Apesar de UML ser apenas um exemplo que utilizei e não representar OO
por si só, creio que você está enganado. Em UML um Relacionamento é
uma entidade que pode e é estendida por diversos outros elementos.
Como um exemplo, a relação de estende DirectedRelationship (que, por
sua vez, estende Relationship) e adiciona um atributo:

Attributes
• isSubstitutable: Boolean [0..1] Indicates whether the specific
classifier can be used wherever the general classifier can be used. If
true, the execution traces of the specific classifier will be a
superset of the execution traces of the general classifier.

> Qual a melhor solução? Assumindo que todos concordemos que
> Domain-Driven Design é algo importante, a melhor solução é a que fizer
> mais sentido para o especialista no domínio.
>
> Concordo com você. Porém durante a implementação do sistema prefiro
> modificar o meu design inicial para facilitar a implementação a simplesmente
> ser "purista" sem nenhum motivo específico.

Pelo visto você não segue a premissa que mencionei, de que concordemos
que DDD é uma coisa valiosa. Assim sendo eu entendo sua crítica, porém
recomendo que leia mais sobre DDD para entender o porque não é
"simplesmente ser 'purista' sem nenhum motivo específico", muito pelo
contrário.

Ricardo Serradas

unread,
Feb 4, 2010, 10:38:10 PM2/4/10
to dotnetar...@googlegroups.com
Poxa... Essa discussão deu o que falar hein :-)

Seguindo o raciocínio de que a associação entre usuário e papel tem
propriedades, ela se torna um objeto e tem que entrar no modelo.

Pelo que entendi, essa associação pode ou não estar ativa; pode ter prazo de
validade, etc etc... Ou seja, tem propriedades e até, quiçá :-),
comportamentos... Então...

Eu modelaria com as 3 classes: User, Role e UserRole. Não acho que dá pra
fugir muito disso mesmo não...

[]'s

Oi,

[]s

--

Thiago Alves

unread,
Feb 5, 2010, 6:34:12 AM2/5/10
to dotnetar...@googlegroups.com
Oi Phillip,

Acho que estamos falando de coisas diferentes. Queria esclarecer umas coisas:

Quis dizer na mensagem anterior que o UML (mais especificamente o diagrama de classes) e o paradigma Orientado a Objetos não prevêem atributos em relacionamentos, apenas em classes, ao contrário do modelo E-R. Por isso existe essa incompatibilidade que o Tuca mencionou. Esta afirmação está correta para você?

Outro ponto que quis dizer é que enquanto eu utilizar bancos de dados relacionais em meus projetos, eu vou criar meus modelos visando os melhores resultados pra mim e pra minha equipe. Isso pra mim passa por adaptar o modelo O-O para ficar mais acoplado ao modelo E-R, ou mesmo fazer a modelagem partindo do modelo E-R em direção ao modelo O-O.

No exemplo dado pelo Tuca eu não vejo nenhuma vantagem em evitar a todo custo o uso de uma classe extra para representar um relacionamento n x n (ou seja, evitar a criação da classe UserRole). O fato de a classe UserRole não existir no domínio do problema não significa não haja necessidade de criá-la (neste caso por causa do atributo IsActive que pertence ao relacionamento, e não às entidades do domínio).

E na minha opinião essa necessidade (criar uma classe extra) existe por uma limitação do modelo O-O, que não prevê atributos em relacionamentos.

Se você, ou qualquer outro aqui, possui uma visão diferente, tranquilo pra mim. Sempre que mando mensagem aqui é sempre com intenção de fazer vocês pensarem (mesmo que não mudem de idéia). Assim como sempre que venho aqui ler as mensagens acabo olhando as coisas por um outro ponto de vista. Às vezes mudo de ideia, às vezes não, mas só o fato de gerar uma reflexão já é muito válido e tem me ajudado muito.

Abraço,
Thiago Alves



2010/2/4 Phillip Calçado <pcal...@gmail.com>
Oi,

Allan Clempe

unread,
Feb 5, 2010, 11:24:08 AM2/5/10
to dotnetar...@googlegroups.com
Phillip,

Lendo seu e-mail de ontem, fiquei com uma grande curiosidade quando vc citou
"outras op��es incluem utilizar um mapa com assinatura <Role, bool>".
Como voc� implementaria isso? � possivel mapear isso no hibernate?

Valeu
[]'s

--------------------------------------------------
From: "Phillip Cal�ado" <pcal...@gmail.com>
Sent: Thursday, February 04, 2010 5:53 AM


To: <dotnetar...@googlegroups.com>
Subject: Re: [dotnetarchitects] Re: Modelagem de Classes. Palpites?

> Oi,
>
> 2010/2/4 Thiago Alves <thiag...@gmail.com>:
>> Pois �... essa � uma limita��o do modelo Orientado a Objetos. N�o existem
>> relacionamentos (associa��es) de classes com atributos.
>
> Isso n�o � uma limita��o de Orienta��o a Objetos, mas sim das
> linguagens de programa��o. UML, por exemplo, � uma linguagem de
> modelagem (n�o de programa��o) que suporta relacionamentos como
> cidad�os de primeira classe.


>
> Ignorando a pergunta mais importante do tema -que seria: por que

> estamos come�ando a modelagem por tabelas e n�o por classes?- a
> solu��o t�pica para o problema proposto � uma classe associativa que
> conteria uma refer�ncia para User, uma para Role e o atributo
> desejado. Claro que isto pode ser um canh�o para matar moscas, outras
> op��es incluem utilizar um mapa com assinatura <Role, bool> ou fazer


> User conter duas listas, uma de Roles e uma de Roles ativos.
>

> Qual a melhor solu��o? Assumindo que todos concordemos que
> Domain-Driven Design � algo importante, a melhor solu��o � a que fizer
> mais sentido para o especialista no dom�nio.
>
> []s
>
> --
> Phillip Cal�ado

> Voc� recebeu esta mensagem porque faz parte do grupo .Net Architects

> hospedado no Google Groups.
> Para postar envie uma mensagem para dotnetar...@googlegroups.com
> Para sair do grupo envie uma mensagem para
> dotnetarchitec...@googlegroups.com

> Para mais op��es visite o grupo em
> http://groups.google.com/group/dotnetarchitects?hl=pt-br

Phillip Calçado

unread,
Feb 6, 2010, 1:40:51 AM2/6/10
to dotnetar...@googlegroups.com
Oi,

2010/2/5 Thiago Alves <thiag...@gmail.com>:


> Quis dizer na mensagem anterior que o UML (mais especificamente o diagrama
> de classes) e o paradigma Orientado a Objetos não prevêem atributos em
> relacionamentos, apenas em classes, ao contrário do modelo E-R. Por isso
> existe essa incompatibilidade que o Tuca mencionou. Esta afirmação está
> correta para você?

Eu acho que o problema pode ser a concepção errônea de que UML é uma
notação de modelagem. Não é. UML é uma linguagem complexa -complexa
até demais- e formal. Recomendo a leitura da especificação da
linguagem, que foi de onde tirei minhas afirmações anteriores. Esta
pode ser gratuitamente obtida em
http://www.omg.org/technology/documents/formal/uml.htm

Na linguagem UML existe um mecanismo de extensão de relacionamentos
que possibilita que estes tenham atributos. Alguns dos relacionamentos
padrão, como a Generalization que mencionei antes, inclusive já
utilizam este recurso e possuem atributos. O que isso quer dizer, em
termos mais práticos, é que em UML você pode criar um tipo de
relacionamento que estende o tipo de relacionamento padrão e adiciona
atributos, exatamente como faz Generalization.

Por isso que mencionei UML como uma linguagem que possibilita que
relações possuam atributos. Se uma ferramenta de desenho de diagramas
diz suportar UML mas não suporta esta extensão, a limitação não é da
linguagem, muito menos do paradigma, e sim da ferramenta.

> Outro ponto que quis dizer é que enquanto eu utilizar bancos de dados
> relacionais em meus projetos, eu vou criar meus modelos visando os melhores
> resultados pra mim e pra minha equipe. Isso pra mim passa por adaptar o
> modelo O-O para ficar mais acoplado ao modelo E-R, ou mesmo fazer a
> modelagem partindo do modelo E-R em direção ao modelo O-O.

Será? Eu trabalhei em projetos com bancos de dados orientados a objeto
e não só o banco geralmente era um problema por si só bem como não
trazia nenhuma vantagem concreta ao uso de uma engine de ORM
sofisticada como o (N)Hibernate.

Além disso, o banco de dados é apenas um dos muitos aspectos de uma
aplicação desenvolvida em uma linguagem como C# que não é OO: O
sistema de arquivos não é OO, HTML não é OO, XML não é OO e por aí
vai. Não é porque nosso modelo de objetos precisa ser traduzido para
modelos não OO -seja uma classe persistida em uma tabela relacional ou
a mesma classe sendo renderizada num browser usando HTML- que
precisamos deixar que estas outras partes afetem o modelo em si, basta
usarmos mapeadores.

> Se você, ou qualquer outro aqui, possui uma visão diferente, tranquilo pra
> mim.

O problema não é a visão ser diferente, o problema é que acredito que
você está atribuindo ao paradigma limitações de uma linguagem
específica.

Phillip Calçado

unread,
Feb 6, 2010, 1:45:01 AM2/6/10
to dotnetar...@googlegroups.com
Oi,

2010/2/6 Allan Clempe <allan....@gmail.com>:


> Lendo seu e-mail de ontem, fiquei com uma grande curiosidade quando vc citou

> "outras opções incluem utilizar um mapa com assinatura <Role, bool>".
> Como você implementaria isso? É possivel mapear isso no hibernate?

O NHibernate faz mapeamento de coleções:
http://nhforge.org/doc/nh/en/index.html#collections

Thiago Alves

unread,
Feb 7, 2010, 11:31:04 PM2/7/10
to dotnetar...@googlegroups.com
Bacana, Phillip,

Seus comentários foram bastante esclarecedores. Obrigado.

Mas ainda prefiro modelar um relacionamento n x n usando três classes, mesmo se o relacionamento não tiver atributos. Não vejo vantagem em ter dois jeitos diferentes de lidar com o mesmo tipo de relacionamento, só para eliminar uma classe.

Talvez não seja a forma mais "correta", mas sempre me deu menos trabalho na hora de implementar.

Abraço,
Thiago Alves



2010/2/6 Phillip Calçado <pcal...@gmail.com>
Reply all
Reply to author
Forward
0 new messages