У меня есть одноэлементный класс, содержащий кучу управляющих данных, которые необходимо синхронизировать с остальной частью моего приложения. В результате я часто хочу, чтобы другой класс мог читать информацию, но не изменять ее. В настоящее время этот синглтон-класс имеет много открытых переменных. Я не хочу использовать функции получения и установки, потому что они многословны и раздражают. Также есть много переменных.
Если мой одноэлементный класс называется ControlData, я мог бы создать второй и создать второй класс с именем ImmutableControlData, в котором он содержит все те же члены, но они объявлены как окончательные. Затем при извлечении моего синглтона я бы возвращал ImmutableControlData, а не объект ControlData. Однако это означает, что мне нужно постоянно поддерживать класс ImmutableControlData, а также класс ControlData (раздражает …)
Если бы у меня были const-указатели, я бы просто вернул const-указатель на мой объект ControlData. Что я могу сделать в Java, вместо этого?
Java не имеет правильной константности, как C ++.
Вы можете создать интерфейс, который объявляет методы для чтения данных, но не методы для изменения данных. Сделайте класс, содержащий данные, реализующим этот интерфейс. Методы в других местах вашей программы, которые должны только читать данные, должны принимать интерфейс, а не класс, как тип параметра. Например:
public interface ReadablePerson {
String getName();
}
public class Person implements ReadablePerson {
private String name;
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// Elsewhere...
public void someMethod(ReadablePerson p) {
System.out.println(p.getName());
}
Конечно, в someMethod
вы все еще можете подорвать это, бросая p
в Person
, но, по крайней мере, это требует определенных сознательных усилий (добавление приведения), которые должны предупредить программиста о том, что он делает то, чего не должен делать.
Преимущество этого решения заключается в том, что вам не нужно делать защитную копию данных.
Первое: если в вашем классе так много участников, вы должны попытаться разделить класс на более мелкие. Может быть, вы можете суммировать некоторые переменные, например.
ControlflowVariables
StateVariables
Если вы хотите ограничить доступ к переменным, вы должны использовать getter. IDE может создавать геттеры и сеттеры для вас. Доступ к переменным одинаков:
singletonClass.variable
не хуже то singletonClass.getVariable()
Если вы хотите ограничить доступ только в некоторых точках своего кода, создайте окончательную копию переменной
final int variable = singletonClass.getInstance().variable;
Лично я бы не пытался контролировать доступ таким способом. Вы ничего не можете сделать, чтобы плохие программисты не использовали ваш класс неправильно. Даже в C ++ они могли бы использовать простой const_cast
убрать свою «защиту» и модифицировать синглтон так, как им нравится.
Вместо этого я реструктурировал бы код, чтобы другим было легко делать правильные вещи, а другим — неправильно. Разделите интерфейс для ControlData на два отдельных интерфейса: один для чтения объекта и один для его обновления. Затем просто предоставьте два интерфейса там, где они нужны.