簡體   English   中英

是否可以使用擴展抽象類的空子類?

[英]Is it ok to have an empty subclass that extends an abstract class?

考慮以下:

  public abstract class Item {
     String name;
     String description;
     //concrete getters and setters follow
  }

   public class InventoryItem extends Item {
     //empty subclass of Item 
   }

  public class CartItem extends Item {
     int quantity;
     int tax;
     //getters and setters for quantity and tax follow
  }

InventoryItem表示可供銷售的項目,而CartItem表示添加到購物車的項目,因此它具有其他屬性,如數量和稅金。 在這種情況下,是否可以使用抽象類Item的空子類?

選項2:我們可以有一個空的Item接口。 InventoryItem將實現Item並定義名稱和描述屬性,並具有getter和setter。 CartItem將從InventoryItem擴展,並將數量和稅收定義為屬性,並具有getter和setter。

選項3:擁有Item接口會更好嗎? InventoryItem將實現Item。 然后我們可以有一個CartItem類,它有'一個'項和兩個屬性,即稅和數量

我認為這個設計沒有任何問題:它明確地將Item指定為基礎,而InventoryItem / CartItem為可實例化的類。 我將Item重命名為AbstractItem (Java類庫執行此操作)以強調該類的預期用途將用作其他類的基礎。

存在C ++特定的問題,例如通過基指針的賦值 ,這使得非常希望使所有“非葉子”類抽象化。 雖然規則並沒有按字面意思轉換為Java,但我認為將非葉類抽象化仍然是一個好主意,即使該類是自給自足的。 這有助於您在用於直接實例化的類和用於擴展的類之間進行明確分離,這有助於不熟悉您的代碼庫的人員進行維護。

進一步采用該規則,Java中的常見做法是使所有葉類final 這是一個很好的防御規則,特別是當你的類是不可變的時候。

編輯:對於購物車中的建模項目,繼承不是最好的選擇。 事實上,我認為做錯了。 我會讓我的CartItem擁有一個Item ,而不是擴展它,因為該項目不會通過放置在購物車中而成為另一種實體。 以下是我認為它應該如何建模:

public class Item {
    String name;
    String description;
    ...
}

public class CartItem {
   Item item;
   int quantity;
   int tax;
   ...
}

讓我提供一個稍長的建議或意見,這可能會提供一些指導。

當設計是一個層次結構時,我傾向於僅通過多態來區分行為。 一般來說,我傾向於避免僅通過數據區分對象。 多年來,我甚至根據它們所擁有的變量來停止為類似結構的“數據對象”創建的繼承層次結構。

我花費大部分時間的地方在於定義抽象類的公共接口表示方法,然后具有所有適用於相同接口但具有不同行為的子類。 (利斯科夫替代原則)

在這種情況下,我會考慮一個公共接口/抽象Item類,其中Item實現的層次結構在庫存方式,計算稅收等方面有所不同。我可以使用方法.isInCatalog()來告訴我項目在哪里或者什么如果我必須以不同的方式處理它是它的本質,但我仍然會嘗試將大多數項類型特定邏輯封裝到其多態方法的實現中。

雖然這些類型的計算通常在數據庫的批處理/聚合操作中實現,而不是在單個對象中完成,但我會在抽象級別.getTax(),. getQuantity()上進行,然后具有不同行為的子類。 (考慮NullObject重構,以避免處理空值)

這篇堅實的博客文章中概述了很少有助於這種設計的原則:

http://codebork.com/2009/02/18/solid-principles-ood.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM