您能做什么取决于您如何约束 API。
如果Name 对象通常由第三方代码创建并传递,并且在存储在Person 对象中时预计会保留其身份,那么您无能为力。所以我不会那样设计 Person 对象。
相反,我会说Person 对象的Name 对象与该对象相关联,设置Person 的name 与设置两个名称部分相同。
例子:
class Person {
_PersonName _name;
Person(...) : ... {
_name = _PersonName(this);
}
...
void set name(Name name) {
_name.fname = name.fname;
_name.lname = name.lname;
notifyListeners();
}
Name get name => _name;
}
class _PersonName extends Name {
final Person _owner;
_PersonName(this._owner);
void set fname(String fname) {
super.fname = fname;
_owner.notifyListeners();
}
void set lname(String lname) {
super.lname = lname;
_owner.notifyListeners();
}
}
这样做的缺点是提取的_PersonName 永远链接到Person 对象,即使您尝试编写不同的Name 对象也是如此。
另一种选择是在每个商店创建一个新的_PersonName 新名称对象,然后将旧对象与Person 分离:
class Person {
_PersonName _name = _PersonName;
Person(...) : ... {
_name = _PersonName(this, null, null);
}
void set name(Name name) {
_name.owner = null;
_name = _PersonName(this, name.fname, name.lname);
notifyListeners();
}
Name get name => _name;
}
class _PersonName extends Name {
Person _owner;
_PersonName(this._owner, String fname, String lname) {
super.fname = fname;
super.lname = lname;
}
void set fname(String fname) {
super.fname = fname;
owner?.notifyListeners();
}
void set lname(String lname) {
super.lname = lname;
owner?.notifyListeners();
}
}
这种方法的行为主要类似于名称对象的普通存储,除非你这样做:
var p = Person();
var n = 名称();
p.name = n;
打印(相同(n,p.name)); // 假的?
您不会保留存储到 Person 对象中的 Name 对象的身份。
没有办法这样做,而且还改变了使用person.name.fname = ...直接在名称上设置字符串的行为,所以必须牺牲一些东西。