oop - 广泛使用工厂构造函数是个好主意吗?
问题描述
我的问题是关于在处理相对复杂的不可变对象时如何正确使用工厂构造函数。假设我想返回一个更改了某些属性的类的实例。
例子
@immutable
class SomeObject {
final int id;
final String name;
final int upvote;
final int downvote;
final int favorite;
SomeObject({this.id, this.name, this.upvote, this.downvote, this.favorite});
factory SomeObject.upvoted() {
return SomeObject(
upvote: this.upvote + 1 // apparently can't use this keyword here, wrong syntax
);
}
SomeObject.upvoted(SomeObject ref) {
id = ref.id;
// cant change an immutable type
}
SomeObject upvoted() {
return SomeObject(
upvote: upvote + 1,
//... other properties are null, bad idea?
);
}
SomeObject upvotedWithDefaultConstructorUsingReference(SomeObject ref) {
// works but seems like an overkill, especially considering more number of properties
return SomeObject(
id: ref.id,
name: ref.name,
upvote: upvote + 1,
downvote: ref.downvote,
favorite: ref.downvote
);
}
}
SomeObject.upvoted() 将是同一类的一个实例,但它的 upvoted 属性比引用的属性多 +1。还会有更多类似 downvoted()、withNameChanged() 或 copyWith()。
前两个是构造函数,其他只是返回 SomeObject 类实例的方法。这里应该采用什么方法?当类不可变时如何使用工厂构造函数?我也不确定这 4 个例子的区别。
我已经阅读了这个问题的答案,但似乎没有回答我的问题。
解决方案
看起来你想要一个copyWith
类型模式:
class SomeObject {
final int id;
final String name;
final int upVote;
final int downVote;
final int favorite;
SomeObject({this.id, this.name, this.upVote, this.downVote, this.favorite});
SomeObject copyWith({
int id,
String name,
int upVote,
int downVote,
int favorite,
}) {
return SomeObject(
id: id ?? this.id,
name: name ?? this.name,
upVote: upVote ?? this.upVote,
downVote: downVote ?? this.downVote,
favorite: favorite ?? this.favorite,
);
}
}
你可以用任何你喜欢的方式来调整它:递增的upVoted
副本,upVote
其余的保持不变,或者允许它们被改变。
SomeObject upVoted() {
return SomeObject(
id: id, // no need for 'this' here
name: name,
upVote: upVote + 1,
downVote: downVote,
favorite: favorite,
);
}
将两者结合起来,您可以想出无穷无尽的变化:
SomeObject upVoted() => copyWith(upVote: upVote + 1);
SomeObject downVoted() => copyWith(downVote: downVote + 1);
SomeObject upVoteRetracted() => copyWith(upVote: upVote - 1);
...这让你开始怀疑为什么这个类是不可变的。让它保持和改变它的状态似乎更有意义,而不是制作具有不同值的多个副本。
推荐阅读
- oracle - 显示在他们出现的所有科目中获得超过 50 分的所有学生的姓名
- jwt - 如果用户无论如何都需要发送他的凭据一次,JWT 有什么好处?
- sql - 当找不到行时,SET @Var = SELECT(...) 会导致什么结果?
- azure - 如何在 Azure 上使我的 OpenId Connect 重定向 URI HTTPS?
- c# - Visual Studio 可能存在怪异括号行为的错误
- c# - DataGridViewCheckBoxColumn 问题得到查看复选框是否被选中
- google-chrome - 将 acceptInsecureCerts 与 Headless Chrome 和 Selenium Webdriver、macOS、Rails、Capybara 一起使用
- node.js - CURL 到 nodeJS 的转换没有输出
- c++ - Visual Studio 2010 全球 VC++ 目录 Redux
- caching - sitecore如何在内容编辑后清除缓存?