我应该使用类继承吗?

时间:2016-03-31 22:11:23

标签: java oop inheritance composition

我必须为客户管理会费。我做了一个名为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 可能会变得不那么相似。因此,我认为最好将它们与现在分开。我对么?

2 个答案:

答案 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.
}
相关问题