我应该使用 class 继承吗?
Should i use class inheritance or not?
我必须为客户管理会费。我制作了一个名为 Due 的 class。它存储两类客户 X、Y 的会费。它是这样的。
public abstract class Due {
private CustomerType customerType; //can be either X or Y
protected DueType dueType;
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(CustomerType type) {
this.customerType = type;
}
//getters , setters goes here.
}
另外 DueType 对于 X 和 Y 都是不同的。因此我创建了一个名为 DueType 的接口和枚举 XDueType, YDueType 实现了它。
public interface DueType {
}
public enum XDueType implements DueType {
A, B;
}
public enum YDueType implements DueType {
C, D;
}
我有两个不同的 classes,每个都专门针对 X 和 Y 的到期日。像这样
public class XDue extends Due {
public XDue() {
super(CustomerType.X);
}
public XDueType getDueType() {
return (XDueType) this.dueType;
}
}
public class YDue extends Due {
public YDue() {
super(CustomerType.Y);
}
public YDueType getDueType() {
return (YDueType) this.dueType;
}
}
我必须对 Due 进行大量操作,无论其类型如何(这些操作对于 XDue 或 YDue).
我的问题是我是否应该像上面那样在这里使用继承。我本可以只做一个 class Due。那本来可以简单地为我完成工作。但是前一种方法对我来说似乎在语义上更正确。此外,向前 XDue、YDue 可能会变得不那么相似。因此,我认为最好从现在开始将它们分开。我对么?
听起来 class 需要一些重构 - 目前它是继承和组合的混合体。我建议完全单向或另一种方式
完全继承会将所有条件逻辑移动到派生类中,并且任何 "types" 返回都是无状态单例(枚举对此很有用)。理想情况下,通过进一步重构,您也可以将任何类型依赖代码移动到派生的 classes 中。
public enum DueType { X, Y }
public enum CustomerType {X,Y}
public abstract class Due {
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(CustomerType type) {
this.customerType = type;
}
abstract DueType getDueType();
abstract CustomerType getCustomerType();
}
public class XDue extends Due {
@Override public DueType getDueType() {
return DueType.X;
}
@Override public CustomerType getCustomerType() {
return CustomerType.X;
}
}
或者进行完整组合,其中 Due 是最终的,并将其决定推迟到包含的策略类型。同样,任何打开类型的逻辑通常都可以移入策略 classes.
public interface DueType /* Really a strategy now */ {
void doSomeThing(Due d);
}
public interface CustomerType /* Really a strategy now */ {
void doSomething(Due d);
}
public final class Due {
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
DueType dueType;
CustomerType customerType;
public Due(CustomerType type, DueType dueType) {
this.customerType = type;
this.dueType = dueType
}
}
public class XDueType implements DueType {
...
}
public clasx XCustomerType implements CustomerType {
...
}
组合优于继承的优势在于,它可以更清晰地实现不相关的 DueType 和 Customer 类型的其他变体,即具有 CustomerTypeA
和 DueTypeB
的 Due
对象,而无需需要创建 DueAB
class。 (但如果这在您的情况下是不可能的,那么这种潜在的差异是一件坏事)。
另一个优点是您可以在 运行 时更改策略,而无需创建全新的 Due
对象。但同样,这可能不是需要/想要的东西。
是的,您的方向是正确的。这是模板模式之王。
你可以使用泛型的一件事,因为你有相同类型的到期和客户:
public abstract class Due<T, U> {
private U customerType; //can be either X or Y
protected T dueType;
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(Utype) {
this.customerType = type;
}
//getters , setters goes here.
}
我必须为客户管理会费。我制作了一个名为 Due 的 class。它存储两类客户 X、Y 的会费。它是这样的。
public abstract class Due {
private CustomerType customerType; //can be either X or Y
protected DueType dueType;
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(CustomerType type) {
this.customerType = type;
}
//getters , setters goes here.
}
另外 DueType 对于 X 和 Y 都是不同的。因此我创建了一个名为 DueType 的接口和枚举 XDueType, YDueType 实现了它。
public interface DueType {
}
public enum XDueType implements DueType {
A, B;
}
public enum YDueType implements DueType {
C, D;
}
我有两个不同的 classes,每个都专门针对 X 和 Y 的到期日。像这样
public class XDue extends Due {
public XDue() {
super(CustomerType.X);
}
public XDueType getDueType() {
return (XDueType) this.dueType;
}
}
public class YDue extends Due {
public YDue() {
super(CustomerType.Y);
}
public YDueType getDueType() {
return (YDueType) this.dueType;
}
}
我必须对 Due 进行大量操作,无论其类型如何(这些操作对于 XDue 或 YDue).
我的问题是我是否应该像上面那样在这里使用继承。我本可以只做一个 class Due。那本来可以简单地为我完成工作。但是前一种方法对我来说似乎在语义上更正确。此外,向前 XDue、YDue 可能会变得不那么相似。因此,我认为最好从现在开始将它们分开。我对么?
听起来 class 需要一些重构 - 目前它是继承和组合的混合体。我建议完全单向或另一种方式
完全继承会将所有条件逻辑移动到派生类中,并且任何 "types" 返回都是无状态单例(枚举对此很有用)。理想情况下,通过进一步重构,您也可以将任何类型依赖代码移动到派生的 classes 中。
public enum DueType { X, Y }
public enum CustomerType {X,Y}
public abstract class Due {
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(CustomerType type) {
this.customerType = type;
}
abstract DueType getDueType();
abstract CustomerType getCustomerType();
}
public class XDue extends Due {
@Override public DueType getDueType() {
return DueType.X;
}
@Override public CustomerType getCustomerType() {
return CustomerType.X;
}
}
或者进行完整组合,其中 Due 是最终的,并将其决定推迟到包含的策略类型。同样,任何打开类型的逻辑通常都可以移入策略 classes.
public interface DueType /* Really a strategy now */ {
void doSomeThing(Due d);
}
public interface CustomerType /* Really a strategy now */ {
void doSomething(Due d);
}
public final class Due {
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
DueType dueType;
CustomerType customerType;
public Due(CustomerType type, DueType dueType) {
this.customerType = type;
this.dueType = dueType
}
}
public class XDueType implements DueType {
...
}
public clasx XCustomerType implements CustomerType {
...
}
组合优于继承的优势在于,它可以更清晰地实现不相关的 DueType 和 Customer 类型的其他变体,即具有 CustomerTypeA
和 DueTypeB
的 Due
对象,而无需需要创建 DueAB
class。 (但如果这在您的情况下是不可能的,那么这种潜在的差异是一件坏事)。
另一个优点是您可以在 运行 时更改策略,而无需创建全新的 Due
对象。但同样,这可能不是需要/想要的东西。
是的,您的方向是正确的。这是模板模式之王。 你可以使用泛型的一件事,因为你有相同类型的到期和客户:
public abstract class Due<T, U> {
private U customerType; //can be either X or Y
protected T dueType;
private String dueId;
private BigDecimal dueAmount;
private Date dueDate;
public Due(Utype) {
this.customerType = type;
}
//getters , setters goes here.
}