Прошу прощения за упоротость. Как концепций, реализуемых в моем SDK, так и самого вопроса.
Вот есть
class Cat {
...
}
И есть одна особенность. В этом классе есть метод
clone
!
То есть можно сделать так
var cat = new Cat();
cat.color = Colors.BLACK;
var cat2 = cat.clone();
cat2.color = Colors.RED;
И получится действительно 2 кота 2 разных цветов.
Круто придумано, да?
Я думаю, что хоть и спорно (тащить подходы из одного языка в другой), но - удобно.
А теперь о проблеме.
Вот есть класс
CatPair
в нем 2 поля
Cat
var catPair = new CatPair();
catPair.male.color = Colors.BLACK;
Как думаете, что произойдет? Ну по канонам JS, здесь действительно должен измениться цвет одного из котов в паре. Пока что все ОК.
Но нужно сделать еще и класс
CatValue
. В котором тоже будет поле\свойство
Cat
. И вот оно должно работать иначе.
Задача класса
CatValue
- это:
1. Дать пользователю возможность заполнить поля формы, для создания кота.
CatValue
при этом будет лежать в React state и хранить состояния полей формы. И при onchange полей он будет пытаться сформировать кота, а если это не выходит, то возвращать ошибки, которые также будут класться в стейт, чтобы тут же отобразить их пользователю.
2. После того, как все заполнено верно и делается submit формы,
CatValue
должен вернуть кота, то есть экземпляр класса
Cat
, и дальнейшая работа будет уже с ним.
В общем,
CatValue
хранится в стейте и поэтому должен быть иммутабельным.
Это означает, что
нельзя сделать так:
const { catValue } = this.state
catValue.cat.colors = Color.BLACK
А только как-то так:
const { catValue } = this.state
const newValue = catValue.changeColor(e.target.value)
setState({ catValue: newValue })
Как это сделать? Поскольку нормальных readonly-полей в JS не завезли, то наверно надо просто:
class CatValue{
...
get cat() {
return this._cat.clone()
}
...
}
ОК, но пользователь-то не знает, что там клонирование. (Это написано в доке, но он не читал.) И нам надо как-то сделать, чтобы пользователь понимал, что это так не работает, что не стоит пытаться это мутировать!
Поэтому думаю, что в данном случае надо сделать не геттер, а метод, причем назвать его так, чтобы попытка мутировать выглядела странно. Например так:
catValue.buildCat().color = Colors.BLACK;
Но есть проблема. То, что это ложь. Метод не билдит кота. А лишь клонирует. ОК, так и назовем:
catValue.cloneCat().color = Colors.BLACK;
Теперь норм. Но не норм с той т\з, что при нормальном получении сбилденного кота непонятно, зачем его клонировать. И как тогда назвать метод?
И норм ли это с учетом того, что все остальное в проекте сделано на основе свойств, а не методов?