2016-03-31 9 views
0

Ich muss Gebühren für Kunden verwalten. Ich habe eine Klasse namens Due gemacht. Es speichert Gebühren für zwei Arten von Kunden X, Y. Es geht so.Sollte ich Klassenvererbung verwenden oder nicht?

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. 
} 

Auch DueType sind für X und Y. So habe ich eine Schnittstelle namens DueType und Aufzählungen XDueType, YDueType implementiert es geschafft.

public interface DueType { 
} 

public enum XDueType implements DueType { 
    A, B; 
} 

public enum YDueType implements DueType { 
    C, D; 
} 

Und ich habe zwei verschiedene Klassen, jeweils speziell für X und Y fällig. Gefällt Ihnen dieses

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; 
    } 
} 

habe ich auf Due unabhängig von ihrer Art, die eine Vielzahl von Operationen zu tun (Diese Operationen werden für gleich sein XDue oder YDue).

Meine Frage ist, sollte ich Vererbung hier oben verwenden oder nicht. Ich hätte nur eine Klasse machen können Due nur. Das hätte einfach den Job für mich erledigen können. Aber die frühere Methode erscheint mir semantisch korrekter. Auch vorwärts gehen XDue, YDue kann weniger ähnlich werden. Daher denke ich, dass es besser ist, sie von jetzt getrennt zu halten. Hab ich recht?

+0

Mögliche Duplikat (http: // Stackoverflow.com/questions/49002/prefer-composition-over-vererbung) – MaxG

+1

Warum haben Sie eine leere Schnittstelle ohne abstrakte Methoden erstellt? – Logan

+0

Dies kann nicht ohne die semantische Information beantwortet werden, wie XDue und YDue unterscheiden, wie sie? – IceFire

Antwort

0

Es klingt, als ob die Klasse ein bisschen Refactoring benötigt - es ist eine Mischung aus Vererbung und Komposition im Moment. Ich schlage vor, vollständig in die eine oder andere Richtung zu gehen

Vollständige Vererbung würde die gesamte bedingte Logik in die abgeleiteten Klassen verschieben, und alle "Typen" zurückgegeben werden Stateless Singletons (Enums sind gut dafür). Idealerweise können Sie mit ein wenig weiterem Refactoring jeden Typ dependedant Code, der diese Typen einschaltet, auch in die abgeleiteten Klassen verschieben.

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; 
    } 
} 

Oder gehen Sie vollständige Zusammensetzung, wo die fällige ist endgültig und verschiebt seine Entscheidungen zu enthaltenen Strategie-Typen. Wiederum kann jede Logik, die den Typ einschaltet, normalerweise in die Strategy-Klassen verschoben werden.

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 { 
... 
} 

Der Vorteil der Komposition der Vererbung ist, dass seine Reiniger zusätzliche Variationen auf DueType und Kundentyp, der in keinem Zusammenhang zu implementieren sind, dh ein Due Objekt mit CustomerTypeA und DueTypeB, ohne eine DueAB Klasse erstellen zu müssen. (Aber wenn das in Ihrer Situation nicht möglich ist, ist dieses Potenzial für Unterschiede eine schlechte Sache).

Ein weiterer Vorteil ist, dass Sie die Strategien zur Laufzeit ändern können, ohne ein komplett neues Due Objekt zu erstellen. Aber auch das ist vielleicht nicht etwas, das benötigt/gewünscht wird.

0

Ja, Sie sind auf dem richtigen Weg. Dies ist ein König von Template-Muster. Eine Sache, können Sie Gebrauch von Generika machen, da Sie durch und Kunden gleichen Typs haben: [? Komposition der Vererbung Bevorzugen]

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. 
} 
Verwandte Themen