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

HttpUtility.HtmlEncode / Декодируют
HttpUtility.UrlEncode / Декодируют

, можно добавить ссылку на System.Web блок, если это не доступно в проекте

9
задан Silent Warrior 16 August 2009 в 17:22
поделиться

8 ответов

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

Что касается использования классов со всеми статическими методами, это не вариант в большинстве случаев, когда можно использовать неизменяемость. Возьмите этот пример из RPG:

public class Weapon
{
    final private int attackBonus;
    final private int accuracyBonus;
    final private int range;

    public Weapon(int attackBonus, int accuracyBonus, int range)
    {
        this.attackBonus = attackBonus;
        this.accuracyBonus = accuracyBonus;
        this.range = range;
    }

    public int getAttackBonus() { return this.attackBonus; }
    public int getAccuracyBonus() { return this.accuracyBonus; }
    public int getRange() { return this.range; }
}

Как именно вы бы реализовать это с помощью класса, содержащего только статические методы?

5
ответ дан 4 December 2019 в 11:07
поделиться

Как правило, именованные каналы работают в сети. Однако, используя именованные каналы с WCF, вы ограничены взаимодействием на компьютере. Вот почему ваша первая и последняя ссылки верны.

Это огромная проблема, скажем, с java.util.Date . Он изменяемый, поэтому вы не можете вернуть его напрямую из метода. Это означает, что вы в конечном итоге выполняете все виды защитного копирования . Это увеличивает распространение объектов.

Другое важное преимущество состоит в том, что неизменяемые объекты по определению не имеют проблем синхронизации . Вот где и возникают проблемы масштабируемости . Написание многопоточного кода затруднительно. Неизменяемые объекты - хороший способ (в основном) обойти проблему.

Что касается «статических классов», в вашем комментарии я понимаю классы с фабричными методами , как это обычно описывается. Это несвязанный паттерн. И изменяемые, и неизменяемые классы могут иметь общедоступные конструкторы или частные конструкторы со статическими фабричными методами. Это не влияет на (им) изменчивость класса, поскольку изменяемый класс - это тот, состояние которого может быть изменено после создания, тогда как состояние неизменяемого класса не может быть изменено после создания экземпляра.

Статические фабричные методы могут иметь и другие преимущества. Идея состоит в том, чтобы инкапсулировать создание объекта.

12
ответ дан 4 December 2019 в 11:07
поделиться

As cletus said, immutable classes simplify class design and handling in synchronized methods.

They also simplify handling in collections, even in single-threaded applications. An immutable class will never change, so the key and hashcode won't change, so you won't screw up your collections.

But you should keep in mind the lifecycle of the thing you're modeling and the "weight" of the constructor. If you need to change the thing, immutable objects become more complex to deal with. You have to replace them, rather than modify them. Not terrible, but worth considering. And if the constructor takes nontrivial time, that's a factor too.

1
ответ дан 4 December 2019 в 11:07
поделиться

Одна вещь, на которую следует обратить внимание: если вы собираетесь использовать экземпляры класса в качестве ключей в HashMap или если вы собираетесь поместить их в HashSet, безопаснее сделать их неизменяемыми.

HashMap и HashSet рассчитывают на то, что хеш-код объекта остается постоянным, пока объект находится на карте или в наборе. Если вы используете объект в качестве ключа в HashMap или помещаете его в HashSet, а затем изменяете состояние объекта так, чтобы hashCode () возвращал другое значение, вы сбиваете с толку HashMap или HashSet и вы получите странные вещи; например, когда вы перебираете карту или устанавливаете, что объект есть, но когда вы пытаетесь получить его, это как будто его там нет.

Это связано с тем, как HashMap и HashSet работают внутри - они организуют объекты по хешу код.

1
ответ дан 4 December 2019 в 11:07
поделиться

Consider string objects, as an example. Some languages or class libraries provide mutable strings, some don't.

A system that uses immutable strings can do certain optimizations that one with mutable strings cannot. For example, you can ensure that there is only one copy of any unique string. Since the size of the object "overhead" is generally much smaller than the size of any non-trivial string, this is a potentially massive memory savings. There are other potential space savings, like interning substrings.

Besides the potential memory savings, immutable objects can improve scalability by reducing contention. If you have a large number of threads accessing the same data, then immutable objects don't require elaborate synchronization processes for safe access.

0
ответ дан 4 December 2019 в 11:07
поделиться

Just one more consideration about the subject. Using immutable object allow you to cache them and not re-create them everytime (ie Strings) it helps a lot on your application performance.

0
ответ дан 4 December 2019 в 11:07
поделиться

Я думаю, если вы хотите поделиться один и тот же объект среди разных переменных, он должен быть неизменным.

Например:

String A = "abc";
String B = "abc";

Строковый объект в Java является неизменяемым. Теперь оба A и B указывают на одну и ту же строку «abc». Теперь

A = A + "123";
System.out.println(B);

он должен вывести:

abc

Поскольку String является неизменяемым, A просто укажет на новый строковый объект «abc123» вместо изменения предыдущего строкового объекта.

0
ответ дан 4 December 2019 в 11:07
поделиться

Неизменяемость обычно используется для достижения масштабируемости, поскольку неизменяемость является одним из факторов, способствующих параллельному программированию на java. Таким образом, хотя, как вы указываете, в «неизменяемом» решении может быть больше объектов, это может быть необходимым шагом для улучшения параллелизма.

Другое, не менее важное использование неизменяемости - это использование намерения проекта. ; тот, кто создал неизменяемый класс, намеревался поместить изменяемое состояние в другое место. Если вы начинаете видоизменять экземпляры этого класса, вы, вероятно, нарушаете первоначальный замысел дизайна - и кто знает, каковы могут быть последствия.

0
ответ дан 4 December 2019 в 11:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: