Итак, у меня есть программа, в которой многим объектам нескольких разных классов необходимо считывать некоторые (многие) переменные из объекта «класса X», чтобы дать ему имя. Быстрый и простой способ сделать это - создать синглтон, который будет не сам X, а классом, к которому он имеет доступ. Я сделал это, и позже это начало чувствовать себя грязным, и многие, кажется, соглашаются, поэтому я хотел бы изменить свой дизайн для этого. Однако я не нашел идей заменить этот шаблон, просто «не делайте этого» и «передавайте данные». Я хотел бы, чтобы мои данные были доступны только для чтения. Я не нашел упоминаний ни о каких других шаблонах.
Лучшее, чем я могу поделиться с этими переменными, доступными только для чтения, что мне кажется вполне приемлемым, - это иметь класс SharedVars
для обмена данными, но в форме внутреннего класса. Он находится внутри Data
, который является внешним классом, который может изменять SharedVars
, инкапсулируя то, что предназначено только для чтения для других классов. По сути, любой класс, который хочет прочитать эти переменные, нуждается в объекте Data.SharedVars
:
public class Data {
public static class SharedVars {
private int encapsulatedData;
public int getData() {
return encapsulatedData;
}
}
// no one should touch this but Data:
static private SharedVars sharedData;
Data() {
sharedData = new SharedVars();
}
public SharedVars getDataRef() {
return sharedData;
}
// here's where this class (and only this class, whenever it's told)
// modifies the encapsulated data:
void manipulateData() {
sharedData.encapsulatedData = 5;
}
}
Один из классов, который зависит от этого, примет следующую форму:
public class Client {
// This class can't access the data directly
// so it'll use Data's getter:
Data.SharedVars vars;
public Client(Data.SharedVars vars) {
this.vars = vars;
// vars.encapsulatedData = 5; // is not allowed, since the field is private (which is what I want)
}
public void go() {
// the proper way to get its hand on the data:
int data = vars.getData();
System.out.println("The data is " + data);
}
}
Main не требуется в этом примере, но я все равно оставлю это здесь:
public class Main {
static Data dataControl;
static Client client;
public static void main(String[] args) {
dataControl = new Data();
client = new Client(dataControl.getDataRef());
dataControl.manipulateData();
client.go();
}
}
Это правильно? Или каковы риски здесь? Обратите внимание, я не хочу, чтобы объекты копировали их для себя, так как они будут постоянно меняться, и мне не совсем нравится идея иметь ссылку на «класс X», который я упоминал ранее.