Devo expor um valor "computado" como uma propriedade ou um método?

13

Eu tenho uma classe C # que representa um tipo de conteúdo em um sistema de gerenciamento de conteúdo da web.

Temos um campo que permite que um editor de conteúdo da web insira um modelo HTML de como o objeto é exibido. Basicamente, usa a sintaxe do guidão para substituir os valores da propriedade do objeto na string HTML:

<h1>{{Title}}</h1><p>{{Message}}</p>

De uma perspectiva de design de classe, devo expor a string HTML formatada (com substituição) como uma propriedade ou método ?

Exemplo como propriedade:

public class Example
{
  private string _template;
  public string Title { get; set; }
  public string Message { get; set; }
  public string Html 
  {
    get
    {
      return this.ToHtml();
    }
    protected set { }
  }

  public Example(Content content)
  {
    this.Title = content.GetValue("title") as string;
    this.Message = content.GetValue("message") as string;
    _template = content.GetValue("template") as string;
  }

  private string ToHtml()
  {
    // Perform substitution and return formatted string.
  }  
}

Exemplo como método:

public class Example
{
  private string _template;
  public string Title { get; set; }
  public string Message { get; set; }

  public Example(Content content)
  {
    this.Title = content.GetValue("title") as string;
    this.Message = content.GetValue("message") as string;
    _template = content.GetValue("template") as string;
  }

  public string ToHtml()
  {
    // Perform substitution and return formatted string.
  }  
}

Não tenho certeza do ponto de vista do design, isso faz alguma diferença ou existem razões pelas quais uma abordagem é melhor que a outra?

Charles Wesley
fonte
A vantagem das propriedades, elas são serializadas em XML ou JSOn, mas é isso que eu acho.
Knerd
1
Propriedades devem representar informações de estado. Não importa se eles são computados ou não. Torna mais fácil usá-los em expressões. Somente você sabe se o HTML representa um estado do objeto.
Reactgular

Respostas:

18

ATUALIZAÇÃO: Esta questão foi o assunto do meu blog em maio de 2014 . Obrigado pela ótima pergunta!


Para adicionar à resposta de Robert Harvey : uma propriedade deve ser:

  • logicamente uma propriedade da classe, da maneira que diz que sua cor, ano ou modelo são propriedades de um carro.

  • não mais do que, digamos, dez vezes mais lento para calcular do que buscar em um campo.

  • algo que você não se importa de ser computado durante a depuração. O depurador do VS calcula automaticamente as propriedades.

  • incapaz de falhar. Os getters sempre devem retornar um valor, independentemente do estado do objeto.

Não acho que sua Htmlpropriedade proposta atinja nenhum deles. Não faça dele uma propriedade, a menos que atinja todos eles.

Eric Lippert
fonte
"incapaz de falhar. Os getters sempre devem retornar um valor, independentemente do estado do objeto." As propriedades não deveriam lançar uma exceção depois que seu objeto foi descartado?
Stephen
6

ToHtmlé corretamente um método, como você o escreveu nos dois casos. Apenas expô-lo publicamente.

O Knerd faz um bom argumento: as propriedades podem ser serializadas. Você nunca desserializou o HTML, portanto, não faz muito sentido torná-lo uma propriedade dessa perspectiva.

Consistente com a maneira como os objetos do ORM e do repositório funcionam: os campos em um registro ou tupla são representados com propriedades, mas você recupera o registro (ou alguma forma dele) usando um método.

Robert Harvey
fonte