Havendo necessidade de utilizar coleções dentro do seu domínio, você pode se deparar com alguns problemas para garantir a implementação de regras de negócio.
Vamos pegar como exemplo as salas de uma escola, dentro da sala estão contidos vários utensílios como cadeiras, carteiras e lousa, uma forma bem simples de modelar ficaria como abaixo:
public class Sala
{
private float areaLousa;
private List
public Sala()
{
utensilios = new List
}
public float AreaLousa
{
get { return areaLousa; }
set { areaLousa = value; }
}
public List
{
get { return utensilios; }
set { utensilios = value; }
}
}
public abstract class Utensilio
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
}
public class Cadeira : Utensilio
{
private bool almofadada;
public bool Almofadada
{
get { return almofadada; }
set { almofadada = value; }
}
}
public class Lousa : Utensilio
{
private float altura;
private float largura;
public float Altura
{
get { return altura; }
set { altura = value; }
}
public float Largura
{
get { return largura; }
set { largura = value; }
}
public float Area
{
get { return altura * largura; }
}
}
Para adicionar um utensílio a sala, faríamos da seguinte forma:
Lousa lousa = new Lousa();
lousa.Altura = 10;
lousa.Largura = 20;
lousa.Id = 1;
Sala sala = new Sala();
sala.Utensilios.Add(lousa);
Mas vamos começar a aplicar algumas regras simples, como exemplo eu irei aplicar regras somente ao utensílio do tipo lousa:
- A sala só pode ter uma lousa;
- A lousa tem que caber na sala;
Para atender as regras acima a nossa classe Sala ficaria da seguinte forma:
public class Sala
{
private float areaLousa;
private List
private bool temLousa;
public Sala()
{
utensilios = new List
}
public void AdicionarUtensilio(Utensilio utensilio)
{
if (utensilio == null)
throw new ArgumentNullException("utensilio");
if (utensilio is Lousa)
{
if (temLousa)
throw new ArgumentException("Já existe uma lousa para a sala", "utensilio");
if ((utensilio as Lousa).Area > this.areaLousa)
throw new ArgumentException("A lousa não cabe na sala", "utensilio");
temLousa = true;
}
utensilios.Add(utensilio);
}
public float AreaLousa
{
get { return areaLousa; }
set { areaLousa = value; }
}
public List
{
get { return utensilios; }
set { utensilios = value; }
}
public bool TemLousa
{
get { return temLousa; }
}
}
Agora para adicionar um utensílio a sala, temos que realizar o seguinte procedimento:
Lousa lousa = new Lousa();
lousa.Altura = 10;
lousa.Largura = 20;
lousa.Id = 1;
Cadeira cadeira = new Cadeira();
cadeira.Almofadada = false;
Sala sala = new Sala();
sala.AreaLousa = 250;
sala.AdicionarUtensilio(lousa);
sala.AdicionarUtensilio(cadeira);
Mas temos uma brecha no nosso código, a propriedade “Utensílios” permite que criemos outra lista de utensílios e substitua ao da classe, por isso a tornaremos somente leitura:
public List
{
get { return utensilios; }
}
Ainda temos brecha, podemos adicionar um Utensílio na coleção como fizemos no primeiro exemplo sem passar pelo método AdicionarUtensilio e com isso permitindo que sejam burladas as regras para adicionar utensílios.
Para resolver esse problema, temos que fazer com que o atributo “utensilios” também seja exposto somente como readonly, bloqueando o atributo de receber valores sem que seja pelo método AdicionarUtensilio, para que isso seja garantido a propriedade ficará da seguinte forma:
public ReadOnlyCollection
{
get { return utensilios.AsReadOnly(); }
}
Desta forma, o método Add da coleção Utensílios não estará disponível para classes externas, tornando o método AdicionarUtensilios() a única forma de adicionar um Utensílio a classe Sala.
Nenhum comentário:
Postar um comentário