Является ли объект, содержащий фиксированный набор изменяемых объектов, изменяемым?

Изменчивость до сих пор время от времени смущает меня.

Если у меня есть объект, содержащий фиксированный набор изменяемых объектов. Считаете ли вы этот объект изменчивым?

Пример. У меня есть объект под названием «Головоломка», который содержит фиксированный набор фигур. Части изменчивы. Например, они могут быть перевернутыми и их ориентация может меняться. Предполагая, что в этом примере вы не можете потерять части (если бы это было правдой в реальной жизни...), я полагаю, что объект Puzzle все еще неизменяем, верно?


person MWB    schedule 11.12.2016    source источник


Ответы (3)


Из википедии: В объектно-ориентированном и функциональном программировании неизменяемый объект (неизменяемый объект) — это объект, состояние которого нельзя изменить после его создания. Это отличается от изменяемого объекта (changeable object), который можно изменить после его создания.

В вашем примере объект Puzzle является изменяемым, поскольку вы можете изменить состояние одной из его частей.

person Nikola Stojiljkovic    schedule 11.12.2016
comment
Итак, неизменяемый объект не может содержать изменяемые объекты? Здесь присутствует какая-то наследственность. Следовательно, добиться неизменности гораздо сложнее, чем я думал. Спасибо! - person MWB; 11.12.2016
comment
Верный. Если вы хотите, чтобы объект был неизменным, он не может содержать изменяемые объекты. Технически можно сделать эти изменяемые объекты приватными и инкапсулировать их таким образом, чтобы их нельзя было изменить, и вы достигли бы неизменности, но это действительно зависит от варианта использования. - person Nikola Stojiljkovic; 11.12.2016

Нет. Объект будет изменчивым. Важной особенностью неизменяемости является то, что (чистые) функции, принимающие объект в качестве параметра, возвращают одно и то же значение при каждом вызове. Этого не будет, если объект содержит изменяемые свойства. Рассмотрим этот пример:

Изменяемый класс:

class Counter {
    private int count = 0;

    public int getCount() {
        return count++;
    }
}

«Неизменяемый» класс:

class Container {
    private final Counter theCounter = new Counter();

    public Counter getCounter() { return theCounter; }
}

И, казалось бы, чистая функция, работающая с Container:

public int getCount(Container container) {
    return container.getCounter().getCount();
}

Таким образом, если бы Container было неизменяемым, вы могли бы ожидать, что getCount() вернет одно и то же значение, если одно и то же Container было передано ему дважды. Но это не так.

Container container = new Container();
getCount(container); // Returns 0.
getCount(container); // Returns 1.
person marstran    schedule 11.12.2016

Нет, объект не может быть неизменяемым, если он содержит хотя бы один изменяемый объект. Здесь части изменчивы. Так что головоломка не может быть неизменной.

Если вы хотите сделать головоломку неизменной, то каким-то образом сделайте части неизменяемыми в соответствии с требованиями.

person Hari Krishna Bobba    schedule 11.12.2016
comment
В моем примере, я думаю, не так просто сделать части неизменяемыми. Во-первых, игрок должен иметь возможность вращать фигуры. - person MWB; 11.12.2016
comment
Вместо того, чтобы изменять фактическую часть, вы можете иметь функцию rotate, которая возвращает новую часть, которая повернута. Всегда есть способ сделать класс неизменяемым. - person marstran; 11.12.2016
comment
Наверное... но почему-то мое внутреннее чувство подсказывает, что это неправильный путь. Возможно, я слишком привязан к настоящим головоломкам, в которых вы не создаете новые части, когда вращаете часть. Итак, я думаю, мой дополнительный вопрос к вам: да, это возможно, но вы бы? - person MWB; 11.12.2016