A documentação para classes orientadas a objetos geralmente envolve uma troca entre dar aos mantenedores da classe flexibilidade para mudar seu design, ao invés de permitir que os consumidores da classe façam pleno uso de seu potencial. Se uma classe imutável irá ter um número de propriedades que terá um determinado exacta relação uns com os outros (por exemplo, a Left
, Right
, eWidth
propriedades de um retângulo alinhado à grade com coordenadas inteiras), pode-se projetar a classe para armazenar qualquer combinação de duas propriedades e calcular a terceira, ou pode-se projetar para armazenar as três. Se nada sobre a interface esclarecer quais propriedades estão armazenadas, o programador da classe poderá alterar o design caso isso seja útil por algum motivo. Por outro lado, se, por exemplo, duas das propriedades são expostas como final
campos e a terceira não, as versões futuras da classe sempre terão que usar as mesmas duas propriedades como sendo a "base".
Se as propriedades não tiverem um relacionamento exato (por exemplo, porque são float
ou double
não int
), pode ser necessário documentar quais propriedades "definem" o valor de uma classe. Por exemplo, mesmo que o Left
plus Width
deva ser igual Right
, a matemática de ponto flutuante geralmente é inexata. Por exemplo, suponha Rectangle
que um que usa tipo Float
aceita Left
e Width
como parâmetros construtores seja construído com Left
dados como 1234567f
e Width
como 1.1f
. A melhor float
representação da soma é 1234568.125 [que pode ser exibida como 1234568.13]; o próximo menor float
seria 1234568.0. Se a turma realmente armazenar Left
eWidth
, ele pode relatar o valor da largura conforme especificado. Se, no entanto, o construtor computasse Right
com base no repasse Left
e Width
, e posteriormente computado com Width
base no Left
e Right
, reportaria a largura 1.25f
mais do que o repasse 1.1f
.
Com classes mutáveis, as coisas podem ser ainda mais interessantes, pois uma alteração em um dos valores inter-relacionados implicará uma alteração em pelo menos um outro, mas nem sempre é claro qual. Em alguns casos, pode ser melhor para evitar ter métodos que "set" uma única propriedade como tal, mas em vez disso quer ter métodos para por exemplo, SetLeftAndWidth
ou SetLeftAndRight
, ou então deixar claro que propriedades estão sendo especificado e que estão mudando (por exemplo MoveRightEdgeToSetWidth
, ChangeWidthToSetLeftEdge
ou MoveShapeToSetRightEdge
) .
Às vezes, pode ser útil ter uma classe que controla quais valores de propriedades foram especificados e quais foram calculados a partir de outros. Por exemplo, uma classe "momento no tempo" pode incluir um horário absoluto, um horário local e um deslocamento de fuso horário. Como em muitos desses tipos, dadas duas informações, uma pode calcular a terceira. Saber quaisuma parte da informação foi calculada, no entanto, às vezes pode ser importante. Por exemplo, suponha que um evento seja registrado como tendo ocorrido às "17:00 UTC, fuso horário -5, horário local 12:00" e depois descobre que o fuso horário deveria ter sido -6. Se alguém souber que o UTC foi gravado em um servidor, o registro deve ser corrigido para "18:00 UTC, fuso horário -6, horário local 12:00"; se alguém digitar a hora local com um relógio, deve ser "17:00 UTC, fuso horário -6, hora local 11:00". Sem saber se a hora global ou local deve ser considerada "mais crível", no entanto, não é possível saber qual correção deve ser aplicada. Se, no entanto, o registro controlasse o horário especificado, as alterações no fuso horário poderiam deixá-lo em paz enquanto o outro era alterado.