库存设计方法(继承与泛型)

发布于 2024-11-13 12:14:00 字数 1563 浏览 4 评论 0原文

问候! 我正在尝试确定哪种方法是实现以下场景的最佳方法:

车辆和零件都是“实体”,可以是库存中的项目。 车辆具有通常的 VIN、年份、制造商、型号、类型等...而零件具有 PartNumber、QuantityOnHand、IsPartOfSet、Vendor... 当作为商品“库存”在库存中时,两者都具有 RetailPrice、PurchasePrice、PurchaseDate,但同时它们还具有许多不共同的其他属性 (例如,车辆具有 CurrentMileage、NewOrUsed 等......而零件具有 TreshholdCount、LastCountDate 等......) 因此,正如您所看到的,零件和车辆都可以在库存中,但它们几乎没有共享的属性(更多的是它们不共享的属性)...

对于上面的场景,我试图在几种方法之间做出决定:

选项 1 - 为所有内容提供单独的类(无继承)

  • 车辆 - 常见车辆属性(VIN、年份、品牌、型号等)
  • VehicleInventoryItem - 引用车辆并包含其他库存特定属性(定价、保修、状态)
  • VehicleInventoryManager - 单例业务逻辑添加、删除、通知等
  • Part
  • PartInventoryItem
  • PartInventoryManager

我认为这种方法最灵活,但会遇到一些属性重复的问题。管理器也可以有非常不同的方法...

选项 2 - 基类简单继承

  • Vehicle - 与选项 1 相同
  • Part - 与选项 1 相同
  • InventoryItem - 基类
  • VehicleInventoryItem - 扩展 InventoryItem,引用 Vehicle
  • PartInventoryItem - 扩展 InventoryItem,引用 Part
  • InventoryManager - 全部方法接受 InventoryItem 作为参数

使用这种方法,我担心 InventoryManager 会受到零件与车辆所需的不同操作的污染

选项 3 - 泛型

  • 项目 - T 将是零件或车辆(我什至可以更具体,例如 - VehicleItem : Item)
  • Inventory - 保存对 Item
  • InventoryManager 的引用 - 在 T 上操作的单例

在这种方法中,类较少,但我再次担心 InventoryManager

Recap

  1. Vehicle 和当“库存”在库存中时,部分共享很少的属性。
  2. 车辆和零件的库存管理也将大不相同(当现有数量较低时,零件会“重新订购”,当车辆出售时,可能会购买类似的零件,但它是唯一的)
  3. 在我的场景中,不会有其他对象/模型将是“可库存的”(存在于任何类型的库存中)

问题

社区有何想法?还有另一种方法(也许是接口?) 如果 2 个域对象共享至少 1 个属性(例如,PurchasePrice),是否应该保证具有某种继承(例如,选项 2 或 3)

Greetings!
I am trying to decide on which is the best approach to implement a following scenario:

Vehicle and Part are both "entites" which can be an Item in an Inventory.
Vehicle has the usual VIN, Year, Make, Model, Type, etc, etc... while Part has PartNumber, QuantityOnHand, IsPartOfSet, Vendor...
When "stocked" in an Inventory as an Item, both have RetailPrice, PurchasePrice, PurchaseDate but at the same time they have a lot of other properties that are not in common
(e.g Vehicle has CurrentMileage, NewOrUsed, etc... etc.. while Part has TreshholdCount, LastCountDate, etc, etc..)
So as you can see both Part and Vehicle can be in Inventory, but they have very few properties that are share (more that they don't)...

With scenario above, I am trying to decide between several approaches:

Option 1 - Separate classes for everything (no inheritance)

  • Vehicle - common vehicle properties (VIN, year, make, model, etc, etc)
  • VehicleInventoryItem - has a reference to Vehicle and contains other inventory specific properties (pricing, warranties, status)
  • VehicleInventoryManager - singleton with business logic add, remove, notify, etc, etc
  • Part
  • PartInventoryItem
  • PartInventoryManager

I think this approach is most flexible while it suffers for some property repetition. Managers also can have very different methods...

Option 2 - Base class simple inheritance

  • Vehicle - same as option 1
  • Part - same as option 1
  • InventoryItem - base class
  • VehicleInventoryItem - extends InventoryItem, references Vehicle
  • PartInventoryItem - extends InventoryItem, references Part
  • InventoryManager - all methods accept InventoryItem as parameters

With this approach, I am worried about InventoryManager being polluted with different operations needed for parts vs vehicles

Option 3 - Generics

  • Item - where T will be part or vehicle (I can even go more specific then, e.g. - VehicleItem : Item)
  • Inventory - holds reference to Item
  • InventoryManager - singleton that operates on T

In this approach, there is less classes but again I am worried about InventoryManager

Recap

  1. Vehicle and Part share very few properties when "stocked" in Inventory.
  2. Inventory management for Vehicle and Part will also be mostly different (parts are "reordered" when qty on hand is low, when vehicle is sold similar one may be purchased but it is unique)
  3. In my scenario there will be no other objects/models that will be "stockable" (being in Inventory of any kind)

Questions

What does community think? Is there another approach (perhaps interfaces?)
If 2 domain objects share at least 1 property (e.g. PurchasePrice), should that warrant having some sort of inheritance (e.g. option 2 or 3)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浪荡不羁 2024-11-20 12:14:00

我将创建一个抽象基类,表示库存中可能存在的任何项目。类似于 InventoryItem。它将具有您提到的所有事物共有的基本属性:RetailPrice、PurchasePrice、PurchaseDate 等。并且它将为某些属性和方法提供默认实现(在适当的情况下)。

然后,我将从此类继承并将其专门用于您计划库存的每个项目:VehiclePart。重写您需要的方法,实现标记为抽象的所有方法,并添加特定子类所需的任何附加功能和/或业务逻辑。

绝对没有理由在这里使用接口。正如您提到的,您销售的所有商品都有许多共同的属性。它们有一些额外的功能,并且某些功能的工作方式可能不同,但有很多功能基本上是相同的。没有理由在多个地方重复该功能。使用抽象基类使您有机会提供默认实现。

您根本不需要 InventoryManager 类:您有理由怀疑它必须了解不同类型的子类。只需让派生类完成所有工作即可。这就是他们的目的。

有关为什么抽象基类通常优于接口的更多信息,请参阅以下答案:

我无法想象为什么泛型在这里相关。它们是用于解决特定问题的特定工具,而不是通用设计模式。如果您需要泛型,请使用它们。但是,利用继承和多态性的精心设计也使得您一开始就不需要它们的可能性大大降低。

I'd create an abstract base class representing any item that is potentially held in inventory. Something like InventoryItem. It would have the basic properties you mention that everything has in common: RetailPrice, PurchasePrice, PurchaseDate, etc. And it would provide a default implementation (where appropriate) for certain properties and methods.

Then, I would inherit from this class and specialize it for each of the items you plan on stocking: Vehicle and Part. Override the methods that you need to, implement all of the methods marked as abstract, and add any additional functionality and/or business logic that is required by the specific subclasses.

There's absolutely no reason to use an interface here. As you mention, all of the things you sell share many common attributes. They have some extra ones and some of the functions might work differently, but there's a lot that is fundamentally the same. There's no reason to duplicate that functionality across multiple places. Using an abstract base class gives you the chance to provide a default implementation.

You don't need an InventoryManager class at all: you're right to be suspect of it having to be aware of the different types of subclasses. Just let the derived classes do all the work. That's what they're for.

For more on why abstract base classes are generally superior to interfaces, see the following answers:

And I can't imagine why generics are relevant here. They're a specific tool used to solve a specific problem, not a general design pattern. If you need generics, use them. But a well-conceived design that takes advantage of inheritance and polymorphism also makes it a lot less unlikely that you'll need them in the first place.

ま昔日黯然 2024-11-20 12:14:00

我将创建一个基类:我们将其称为 InventoryItem,其中包含所有共享属性(RetailPricePurchasePricePurchaseDate 等)

Part然后,Vehicle 将从 InventoryItem 继承,并使用它们需要的任何属性对其进行扩展。

然后,我将创建一个名为 InventoryManager 的基类,VehicleManagerPartManager 继承自该基类。 InventoryManager 将包含用于管理库存的所有共享逻辑,子类将使用它们需要的任何功能来扩展它。

我的印象是您在设计过程中处于相当早期的阶段。我不会这么早就尝试为此确定完美的设计。只需构建一些基本的东西,然后在进行过程中对其进行更改和扩展,因为当您开始构建和使用 API 时,您会更好地理解问题。

“如有疑问,请忽略它。”

I would create a base class: Let's call it InventoryItem containing all the shared properties (RetailPrice, PurchasePrice, PurchaseDate etc.)

Part and Vehicle would then inherit from InventoryItem and extend it with whatever properties they need.

I would then create a base class called InventoryManager which VehicleManager and PartManager inherits from. InventoryManager would contain all the shared logic for managing the inventory and the sub classes would extend it with whatever functionality they need.

I get the impression that you are pretty early in the design process. I wouldn't bother trying to nail the perfect design for this, this early. Just build something basic and change and extend it as you go along, because when you start to build and use the API you will understand the problem better.

"When in doubt, leave it out."

记忆で 2024-11-20 12:14:00

简要查看您的描述后,我建议将与库存相关的方法放在接口中的项目上。如果您需要车辆和零件之间的关系,那么您始终可以在零件上拥有一个属性来引用它们来自的车辆,或者反之亦然(或者可能两者都有,如果您需要进行双向查找)。这似乎将处理库存相关任务的关注点分成了一个特定的类别。
希望有帮助。

From a brief look at your description I would like to suggest putting the Inventory related methods on the items in an Interface. If you need a relationship between vehicles and parts, you can always have a property on your parts to reference the vehicle they come from, or the other way around (or possibly both, if you need to do lookups both ways). This seems to separate the concern of dealing with inventory related tasks into a specific class.
Hope that helps.

诗化ㄋ丶相逢 2024-11-20 12:14:00

也许我遗漏了一些东西,但我不明白您对 InventoryManager 中“污染”的担忧。如果这是一个问题,那就需要一个单独的课程。您所描述的每个其他类都共享通用功能(至少是它们的标识符),因此继承似乎是当今的惯例。

然而,我认为您会想要使用多种技术的组合。您将使用继承、接口(例如,用于比较)和泛型(用于列表)。一个并不一定排斥另一个。

Maybe I'm missing something, but I don't understand your concern about "pollution" in the InventoryManager. If that's a concern, it would call for a separate class. Every other class you've described shares common functionality (at the very least, their identifiers), so inheritance would seem to be the order of the day.

I think, however, that you're going to want to use a mix of technologies. You'll use inheritance, with interfaces (for comparison, for example), and generics (for lists). One does not necessarily exclude the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文