Pergunta

O artigo da Wikipédia sobre Lei de Deméter diz:

A lei pode ser declarada simplesmente como “use apenas um ponto”.

Contudo um exemplo simples de um interface fluente pode ser assim:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

Então isso vai junto?

Foi útil?

Solução

Bem, a definição curta da lei a encurta demais.A verdadeira "lei" (na realidade, conselhos sobre um bom design de API) diz basicamente:Acesse apenas objetos que você mesmo criou ou que foram passados ​​para você como argumento.Não acesse objetos indiretamente por meio de outros objetos.Os métodos de interfaces fluentes geralmente retornam o próprio objeto, portanto, não violam a lei, se você usar o objeto novamente.Outros métodos criam objetos para você, portanto também não há violação.

Observe também que a "lei" é apenas um conselho de práticas recomendadas para APIs "clássicas".Interfaces fluentes são uma abordagem completamente diferente para o design de APIs e não podem ser avaliadas com a Lei de Demeter.

Outras dicas

Não necessariamente.“Use apenas um ponto” é um resumo impreciso da Lei de Deméter.

A Lei de Deméter desencoraja o uso de múltiplos pontos quando cada ponto representa o resultado de um objeto diferente, por exemplo:

  • O primeiro ponto é um método chamado de ObjectA, retornando um objeto do tipo ObjectB
  • Próximo ponto é um método disponível apenas em ObjectB, retornando um objeto do tipo ObjectC
  • Próximo ponto é uma propriedade disponível apenas em ObjectC
  • ao infinito

No entanto, pelo menos na minha opinião, a Lei de Deméter não é violada se o objeto de retorno de cada ponto ainda for do mesmo tipo que o chamador original:

var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();

No exemplo acima, FindAll() e Sort() retornam o mesmo tipo de objeto da lista original.A Lei de Deméter não é violada:a lista só conversou com seus amigos imediatos.

Dito isto De jeito nenhum interfaces fluentes violam a Lei de Demeter, desde que retornem o mesmo tipo que seu chamador.

Sim, embora seja necessário aplicar algum pragmatismo à situação.Sempre tomo a Lei de Deméter como uma diretriz e não como uma regra.

Certamente você pode querer evitar o seguinte:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

talvez substitua por:

CurrentCustomer.Orders[0].EmailManufacturer(text);

À medida que mais de nós usamos o ORM, que geralmente apresenta todo o domínio como um gráfico de objeto, pode ser uma ideia definir um "escopo" aceitável para um objeto específico.Talvez devêssemos usar a lei de Deméter para sugerir que você não deveria mapear o gráfico inteiro como alcançável.

O espírito da Lei de Deméter é que, dada uma referência de objeto ou classe, você deve evitar acessar as propriedades de uma classe que esteja a mais de uma subpropriedade ou método de distância, pois isso unirá fortemente as duas classes, o que pode ser não intencional e pode causar problemas de manutenção.

Interfaces fluentes são uma exceção aceitável à lei, pois são significou deve ser pelo menos um tanto fortemente acoplado, já que todas as propriedades e métodos são os termos de uma minilinguagem que são compostas juntas para formar sentenças funcionais.

1) Não viola nada.

O código é equivalente a

var a = new ZRLabs.Yael.Pipeline("cat.jpg");
a = a.Rotate(90);
a = a.Watermark("Monkey");
a = a.RoundCorners(100, Color.Bisque);
a = a.Save("test.png");

2) Como diz o bom e velho Phil Haack: A lei de Deméter não é um exercício de contagem de pontos

Não há problema com o seu exemplo.Afinal, você está girando, marcando água, etc...sempre a mesma imagem.Acredito que você esteja conversando com um objeto Pipeline o tempo todo, portanto, desde que seu código dependa apenas da classe do Pipeline, você não está violando o LoD.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top