如何在 Kotlin 中对数据 class 实现空对象模式?
How to implement Null Object pattern on data class in Kotlin?
我有一个 Kotlin 数据 class:
data class PaymentAccount(
val accountId: Int,
val accountNumber: String,
val title: String
)
这就是我在 Java 中所做的:
创建摘要class:
public abstract class PaymentAccount {
protected int accountId;
protected String accountNumber;
protected String title;
public PaymentAccount(int accountId,
String accountNumber,
String title) {
this.accountId = accountId;
this.accountNumber = accountNumber;
this.title = title;
}
}
创建空对象并扩展抽象class:
public class NullPaymentAccount extends PaymentAccount {
public NullPaymentAccount() {
super(-1,
"Invalid account number",
"Invalid title");
}
}
创建一个真实对象并扩展抽象 class:
public class RealPaymentAccount extends PaymentAccount {
public RealPaymentAccount(int accountId,
String accountNumber,
String title) {
super(accountId,
accountNumber,
title);
}
}
如何在Kotlin中正确实现空对象模式?有不止一种方法吗?如果是这样,最简洁优雅的方式是什么?
在 Kotlin 中你可以做同样的事情,只是代码行更少:
interface Account {
val accountId: Int
val accountNumber: String
val title: String
}
object EmptyAccount : Account {
override val accountId: Int = 1
override val accountNumber: String = ""
override val title: String = ""
}
data class PaymentAccount(
override val accountId: Int,
override val accountNumber: String,
override val title: String): Account
请注意,我们还制作了 EmptyAccount
单调以提高效率。
虽然您得到的解决方案已经很好,但如果您的默认值不是全有或全无,您可能不需要明确的 class 来表示空状态。我认为为所有字段提供默认值 是 空对象模式。
例如,您可以这样写 class:
data class PaymentAccount(
val accountId: Int = -1,
val accountNumber: String = "Invalid Account Number",
val title: String = "Invalid Title"
)
当你构建它们时:
PaymentAccount(1, "Acct2", "Checking") // Actual data
PaymentAccount() // Default values, therefore a "null" object.
唯一真正的问题是当您只指定一些值时,但那可能是 ok/desirable:
PaymentAccount(1) // accountNumber and title have defaults
另一种方法是为此定义辅助构造函数:
data class PaymentAccount(
val accountId: Int,
val accountNumber: String,
val title: String
){
constructor() : this(-1,
"Invalid account number",
"Invalid title")
}
我有一个 Kotlin 数据 class:
data class PaymentAccount(
val accountId: Int,
val accountNumber: String,
val title: String
)
这就是我在 Java 中所做的:
创建摘要class:
public abstract class PaymentAccount {
protected int accountId;
protected String accountNumber;
protected String title;
public PaymentAccount(int accountId,
String accountNumber,
String title) {
this.accountId = accountId;
this.accountNumber = accountNumber;
this.title = title;
}
}
创建空对象并扩展抽象class:
public class NullPaymentAccount extends PaymentAccount {
public NullPaymentAccount() {
super(-1,
"Invalid account number",
"Invalid title");
}
}
创建一个真实对象并扩展抽象 class:
public class RealPaymentAccount extends PaymentAccount {
public RealPaymentAccount(int accountId,
String accountNumber,
String title) {
super(accountId,
accountNumber,
title);
}
}
如何在Kotlin中正确实现空对象模式?有不止一种方法吗?如果是这样,最简洁优雅的方式是什么?
在 Kotlin 中你可以做同样的事情,只是代码行更少:
interface Account {
val accountId: Int
val accountNumber: String
val title: String
}
object EmptyAccount : Account {
override val accountId: Int = 1
override val accountNumber: String = ""
override val title: String = ""
}
data class PaymentAccount(
override val accountId: Int,
override val accountNumber: String,
override val title: String): Account
请注意,我们还制作了 EmptyAccount
单调以提高效率。
虽然您得到的解决方案已经很好,但如果您的默认值不是全有或全无,您可能不需要明确的 class 来表示空状态。我认为为所有字段提供默认值 是 空对象模式。
例如,您可以这样写 class:
data class PaymentAccount(
val accountId: Int = -1,
val accountNumber: String = "Invalid Account Number",
val title: String = "Invalid Title"
)
当你构建它们时:
PaymentAccount(1, "Acct2", "Checking") // Actual data
PaymentAccount() // Default values, therefore a "null" object.
唯一真正的问题是当您只指定一些值时,但那可能是 ok/desirable:
PaymentAccount(1) // accountNumber and title have defaults
另一种方法是为此定义辅助构造函数:
data class PaymentAccount(
val accountId: Int,
val accountNumber: String,
val title: String
){
constructor() : this(-1,
"Invalid account number",
"Invalid title")
}