Estou com um problema de design em relação às propriedades do .NET.
interface IX
{
Guid Id { get; }
bool IsInvalidated { get; }
void Invalidate();
}
Problema:
Essa interface possui duas propriedades somente leitura Id
e IsInvalidated
. O fato de serem somente leitura, no entanto, não é, por si só, garantia de que seus valores permanecerão constantes.
Digamos que era minha intenção deixar bem claro que ...
Id
representa um valor constante (que pode, portanto, ser armazenado em cache com segurança), enquantoIsInvalidated
pode alterar seu valor durante a vida útil de umIX
objeto (e, portanto, não deve ser armazenado em cache).
Como eu poderia modificar interface IX
para tornar esse contrato suficientemente explícito?
Minhas próprias três tentativas de solução:
A interface já está bem projetada. A presença de um método chamado
Invalidate()
permite que um programador deduza que o valor da propriedade com nome semelhanteIsInvalidated
pode ser afetado por ele.Esse argumento é válido apenas nos casos em que o método e a propriedade são nomeados de maneira semelhante.
Aumente essa interface com um evento
IsInvalidatedChanged
:bool IsInvalidated { get; } event EventHandler IsInvalidatedChanged;
A presença de um
…Changed
evento paraIsInvalidated
afirma que essa propriedade pode alterar seu valor e a ausência de um evento semelhante paraId
é uma promessa de que essa propriedade não alterará seu valor.Gosto dessa solução, mas há muitas coisas adicionais que podem não ser usadas.
Substitua a propriedade
IsInvalidated
por um métodoIsInvalidated()
:bool IsInvalidated();
Isso pode ser uma mudança muito sutil. Supõe-se que seja um indício de que um valor é calculado sempre a cada vez - o que não seria necessário se fosse uma constante. O tópico do MSDN "Escolhendo entre propriedades e métodos" tem a dizer sobre isso:
Use um método, em vez de uma propriedade, nas seguintes situações. […] A operação retorna um resultado diferente cada vez que é chamada, mesmo que os parâmetros não sejam alterados.
Que tipo de respostas eu espero?
Estou mais interessado em soluções totalmente diferentes para o problema, juntamente com uma explicação de como elas venceram minhas tentativas acima.
Se minhas tentativas são logicamente falhas ou têm desvantagens significativas ainda não mencionadas, de tal forma que resta apenas uma solução (ou nenhuma), eu gostaria de ouvir sobre onde errei.
Se as falhas forem mínimas e mais de uma solução permanecer após a consideração, por favor, comente.
No mínimo, gostaria de receber um feedback sobre qual é a sua solução preferida e por qual motivo.
class Foo : IFoo { private bool isInvalidated; public bool IsInvalidated { get { return isInvalidated; } } public void Invalidate() { isInvalidated = true; } }
InvalidStateException
s, por exemplo, mas não tenho certeza se isso é teoricamente possível. Seria bom, no entanto.
IsInvalidated
precisa de umprivate set
?