我必须为客户管理会费。我做了一个名为Due的课程。它存储两种类型的客户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 的接口和enums XDueType , YDueType 实现它。
public interface DueType {
}
public enum XDueType implements DueType {
A, B;
}
public enum YDueType implements DueType {
C, D;
}
我有两个不同的类,每个类专门用于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 的操作相同)。
我的问题是我应该像上面一样使用继承。我本可以只创建一个 Due 类。那可能只是为我完成了这份工作。但是前一种方法对我来说在语义上更正确。此外,前进 XDue , YDue 可能会变得不那么相似。因此,我认为最好将它们与现在分开。我对么?
答案 0 :(得分:0)
听起来这个类需要一些重构 - 它是目前继承和组合的混合体。我建议完全单向行驶
完全继承会将所有条件逻辑移动到派生的clases中,并且返回的任何“类型”都是无状态的单例(枚举对此有利)。理想情况下,通过稍微进一步的重构,您可以将任何类型的依赖代码移动到派生类中。
select UID,USERNAME,concat('JSON OBJECT OF PID (',group_concat(PID),')') PORTFOLIO
from User u join Portfolio p
on u.UID=p.UID group by UID
或者完全构成,其中“到期”是最终的,并将其决定推迟到包含的策略类型。同样,任何打开类型的逻辑通常都可以移入策略类中。
SELECT u.UID,NAME,concat('JSON OBJECT OF PID (',group_concat(pid),')')
FROM `User` u LEFT join Portfolio p
on u.UID=p.UID group by u.UID
组合优于继承的优势在于它更清晰,无法实现与不相关的DueType和Customer类型的其他变体,即具有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;
}
}
和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 {
...
}
的{{1}}对象,而无需创建一个Due
类。 (但如果在你的情况下这是不可能的,这种分歧的可能性是坏事。)
另一个优点是您可以在运行时更改策略,而无需创建全新的CustomerTypeA
对象。但同样可能不是需要/期望的东西。
答案 1 :(得分:0)
是的,你走在正确的轨道上。这是模板模式之王。 有一件事你可以使用泛型,因为你有相同类型的到期和客户:
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.
}