Pregunta

Quiero tener objetos inmutables de Java como esto (muy simplificada):

class Immutable {

    protected String name;

    public Immutable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

En algunos casos, el objeto no sólo debe ser legible, pero mutable, por lo que podría añadir mutabilidad través de la herencia:

public class Mutable extends Immutable {

    public Mutable(String name) {
        super(name);
    }

    public void setName(String name) {
        super.name = name;
    }

}

Si bien esto es técnicamente muy bien, me pregunto si se conforma con programación orientada a objetos y la herencia que mutable también es de tipo inmutable. Quiero evitar el crimen programación orientada a objetos para lanzar UnsupportedOperationException por objeto inmutable, como las colecciones de Java API hace.

¿Qué opinas? Alguna otra idea?

¿Fue útil?

Solución

evitar llamar a los padres "inmutable", ya que se convierte en una mentira en la clase de niño - si hace quiere hacer una inmutable clase, debe ser definitiva también con el fin de prevenir exactamente este problema.

Joda Time utiliza "ReadableXXX" para dar la idea de que "esta clase sólo proporciona acceso de lectura; otras subclases pueden ser mutable". No estoy seguro de si me gusta esa idea, pero no puedo decir que he visto muchas alternativas.

Básicamente el problema es con la expresión de un negativo - Immutable describe lo que no puede do (mutar ella) y que no se puede aplicar con sensatez en las subclases. (Incluso si los campos dentro Immutable eran definitivas, que no deja de tener una subclase sus propios campos mutables.)

Otros consejos

Yo sugeriría que usted debe tener una base hereditaria clase "ReadableFoo", una clase derivada ImmutableFoo sellada, y otras clases MutableFoo derivados. Código que no le importa si un Foo es mutable o no puede aceptar una ReadableFoo. El código que quiere un Foo que se garantiza que no se puede aceptar el cambio de un ImmutableFoo. Código que puede que tenga que cambiar un Foo puede aceptar un MutableFoo.

Tenga en cuenta que los constructores, tanto para ImmutableFoo y MutableFoo deben normalmente aceptar un ReadableFoo. De esta manera, cualquier Foo será convertible en una versión mutable o inmutable.

clases inmutables deben ser final precisamente para evitar mutables subtipos.

Permitir que un subtipo de una clase inmutable romper el contrato inmutable hace que sea bastante inútil para tener la clase sea inmutable en el primer lugar. Puede ser legal en el sentido de que Java permite que lo haga (la inmutabilidad no se cumple en el idioma), pero esa clase no es realmente inmutable como siempre que pueda ser sub-clasificado.

Esta es la razón por cadena es final.

Su subclase es malo porque viola la principio de sustitución de liskov . No lo haga.

Encuentro su código bastante curioso.

Para implementar un comportamiento tal inmutable, preferiría se ha basado en una interfaz Immutable, proporcionando sólo el método getter, whiile el objeto contiene ambos. De esta manera, las operaciones que dependen de los objetos inmutables habría llamado la interfaz, mientras que otros han llamado el objeto.

Y, si realmente no quiere que sus objetos inmutables a ser moldeado como los mutables, a continuación, puede utilizar proxies, y todas las herramientas de la empresa (aspectos, y así sucesivamente). Pero por lo general, confiando en la buena voluntad de otros desarrolladores de es una manera dulce para que sean responsables de sus errores (como echar la inmutable en mudable).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top