在面向对象设计中改变对象类型

时间:2014-01-02 18:49:03

标签: class design-patterns polymorphism uml

我有两种会员和两种付款方式。在第一个设计中,我使用了一个类用于两种成员类型和两种计算方法。我知道,这个设计并不好。

然后我尝试了另一种具有多态性的设计。在这个设计中,我有两个成员类型的类。看起来好一点,但这个设计存在问题。我必须在创建成员后更改成员的状态(特殊到常规或常规到特殊)。我怎么能在第二张图中做到这一点,或者有更好的方法吗?

enter image description here

2 个答案:

答案 0 :(得分:0)

听起来像你理想的是:

  • 两种子类型,MemberSpecialMember,每种都有自己的calculatePayment()实现,
  • 在这些子类型之间迁移对象的能力。

您的第二个解决方案涵盖了第一点。不幸的是,主流OO语言通常不支持类型迁移。有几个选项需要考虑:

  1. Strategy Pattern。将每个calculatePayment方法封装在策略子类型中;创建成员时,根据成员类型绑定适当的策略子类型。如果您需要迁移成员实例,只需重新绑定到另一个策略的实例。

  2. 使用您的第二个设计并在每个子类型中实施migrate()作为操作。实现将实际删除当前实例并创建另一个子类型的等效项。

  3. 使用哪种方法取决于许多因素。 (1)每次调用calculatePayment()时,运行时开销略高。但是成员对象的身份是不可变的。 (2)calculatePayment()中的运行时开销较少,但对象ID不是不可变的,因为您实际上是在删除实例并创建一个新实例。

    第h

答案 1 :(得分:0)

如果您将它们视为成员和特殊成员,那么创建成员作为基类,使用自己的calculatePayment和特殊成员作为派生类,并使用重写的calculatePayment更自然,更容易。

因此,您可以根据状态来处理与父项或子项相同的对象,从而切换函数。

如果您喜欢您的构造(我也喜欢它),请为这些类提供其他名称(MemberCommon和MemberSpecial),并将它们都基于同一个类“member”。这个类将计算为:

if (state.isEqualTo("special")) 
    return(((SpecialMember)this).calculate())
else
    return(((CommonMember)this).calculate())

但我认为,最诚实的方式就是根据状态进行计算 - 制作一个类,两个函数并在它们之间切换。